luo-image-annotator 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,33 +1 @@
|
|
|
1
|
-
(function(B,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],t):(B=typeof globalThis<"u"?globalThis:B||self,t(B.VueImageAnnotator={},B.Vue))})(this,(function(B,t){"use strict";var Qe=Object.defineProperty;var tn=(B,t,z)=>t in B?Qe(B,t,{enumerable:!0,configurable:!0,writable:!0,value:z}):B[t]=z;var A=(B,t,z)=>tn(B,typeof t!="symbol"?t+"":t,z);const z=(y,e)=>Math.sqrt(Math.pow(y.x-e.x,2)+Math.pow(y.y-e.y,2)),it=(y,e)=>{let i=!1;for(let n=0,a=e.length-1;n<e.length;a=n++){const h=e[n].x,c=e[n].y,l=e[a].x,g=e[a].y;c>y.y!=g>y.y&&y.x<(l-h)*(y.y-c)/(g-c)+h&&(i=!i)}return i},q=(y,e,i)=>{const n=i*(Math.PI/180),a=Math.cos(n),h=Math.sin(n),c=y.x-e.x,l=y.y-e.y;return{x:e.x+(c*a-l*h),y:e.y+(c*h+l*a)}};class at{constructor(e){A(this,"canvas");A(this,"ctx");A(this,"img");A(this,"annotations",[]);A(this,"currentTool",null);A(this,"interactionMode","none");A(this,"activeAnnotation",null);A(this,"hoverAnnotation",null);A(this,"isDrawing",!1);A(this,"isDragging",!1);A(this,"isPanning",!1);A(this,"panStartPoint",null);A(this,"dragStartPoint",null);A(this,"dragStartAnnotation",null);A(this,"lastMouseMovePoint",null);A(this,"isHoveringStartPoint",!1);A(this,"currentLabelColor","#FF4081");A(this,"visibleLabels",new Set);A(this,"selectedHandleIndex",-1);A(this,"hoverHandleIndex",-1);A(this,"scale",1);A(this,"offset",{x:0,y:0});A(this,"listeners",{});A(this,"imageUrl","");this.canvas=e;const i=e.getContext("2d");if(!i)throw new Error("Could not get 2d context");this.ctx=i,this.img=new Image,this.img.crossOrigin="Anonymous",this.img.onload=()=>{this.fitImageToCanvas(),this.render()},this.bindEvents()}on(e,i){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(i)}emit(e,i){this.listeners[e]&&this.listeners[e].forEach(n=>n(i))}loadImage(e){this.imageUrl=e,this.img.src=e,this.activeAnnotation=null,this.isDrawing=!1}setAnnotations(e){this.annotations=JSON.parse(JSON.stringify(e)),this.render()}getAnnotations(){return this.annotations}setTool(e){e==="pan"?(this.interactionMode="pan",this.currentTool=null,this.isPanning=!1,this.canvas.style.cursor="grab"):e==="select"?(this.interactionMode="select",this.currentTool=null,this.canvas.style.cursor="default"):e?(this.interactionMode="draw",this.currentTool=e,this.canvas.style.cursor="crosshair"):(this.interactionMode="none",this.currentTool=null,this.canvas.style.cursor="default"),this.activeAnnotation=null,this.isDrawing=!1,this.render()}setLabelStyle(e){this.currentLabelColor=e}setVisibleLabels(e){this.visibleLabels=new Set(e),this.render()}zoom(e){const n=e>0?this.scale*1.1:this.scale/1.1;if(n<.1||n>10)return;const a=this.canvas.width/2,h=this.canvas.height/2,c=this.toImageCoords(a,h);this.scale=n,this.offset.x=a-c.x*this.scale,this.offset.y=h-c.y*this.scale,this.clampViewportOffset(),this.render()}resize(){this.fitImageToCanvas(),this.render()}toImageCoords(e,i){return{x:(e-this.offset.x)/this.scale,y:(i-this.offset.y)/this.scale}}toScreenCoords(e,i){return{x:e*this.scale+this.offset.x,y:i*this.scale+this.offset.y}}fitImageToCanvas(){const e=this.canvas.parentElement;if(e){if(this.canvas.width=e.clientWidth,this.canvas.height=e.clientHeight,this.img.width===0)return;const i=this.canvas.width/this.img.width,n=this.canvas.height/this.img.height;this.scale=Math.min(i,n),this.offset.x=(this.canvas.width-this.img.width*this.scale)/2,this.offset.y=(this.canvas.height-this.img.height*this.scale)/2,this.clampViewportOffset()}}clampViewportOffset(){if(this.img.width===0||this.img.height===0)return;const e=this.img.width*this.scale,i=this.img.height*this.scale;if(e<=this.canvas.width)this.offset.x=(this.canvas.width-e)/2;else{const n=this.canvas.width-e,a=0;this.offset.x=Math.min(a,Math.max(n,this.offset.x))}if(i<=this.canvas.height)this.offset.y=(this.canvas.height-i)/2;else{const n=this.canvas.height-i,a=0;this.offset.y=Math.min(a,Math.max(n,this.offset.y))}}bindEvents(){this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("mouseleave",this.handleMouseUp.bind(this)),window.addEventListener("keydown",this.handleKeyDown.bind(this))}handleKeyDown(e){this.interactionMode==="select"&&(e.key==="Delete"||e.key==="Backspace")&&this.activeAnnotation&&this.deleteAnnotation(this.activeAnnotation.id)}deleteAnnotation(e){const i=this.annotations.findIndex(n=>n.id===e);if(i>-1){const n=this.annotations[i];this.annotations.splice(i,1),this.activeAnnotation=null,this.emit("annotationChange",{action:"delete",changedItem:n,imageUrl:this.imageUrl}),this.render()}}handleMouseDown(e){const i=this.canvas.getBoundingClientRect(),n=e.clientX-i.left,a=e.clientY-i.top,h=this.toImageCoords(n,a);if(this.canvas.style.cursor==="grab"||this.canvas.style.cursor==="grabbing"){this.isPanning=!0,this.panStartPoint={x:n,y:a},this.canvas.style.cursor="grabbing";return}if(this.interactionMode==="select"&&this.activeAnnotation){const g=this.getHitHandle(n,a,this.activeAnnotation);if(g!==-100){this.isDragging=!0,this.dragStartPoint=h,this.selectedHandleIndex=g,this.dragStartAnnotation=JSON.parse(JSON.stringify(this.activeAnnotation));return}}const c=this.interactionMode==="select"?this.getHitCategory(n,a):null;if(c){this.activeAnnotation=c,this.isDragging=!1,this.selectedHandleIndex=-1,this.emit("annotationChange",{action:"select",changedItem:c,imageUrl:this.imageUrl}),this.render();return}const l=this.getHitAnnotation(h);if(this.interactionMode==="select"){if(l){if(!(this.visibleLabels.size>0&&!this.visibleLabels.has(l.label))){this.activeAnnotation=l,this.isDragging=!0,this.dragStartPoint=h,this.selectedHandleIndex=-1,this.dragStartAnnotation=JSON.parse(JSON.stringify(l)),this.emit("annotationChange",{action:"select",changedItem:l,imageUrl:this.imageUrl}),this.render();return}}else this.activeAnnotation=null,this.emit("annotationChange",{action:"select",changedItem:void 0,imageUrl:this.imageUrl}),this.render();return}if(this.interactionMode==="draw"){if(this.isDrawing&&this.currentTool==="polygon"&&this.activeAnnotation){const g=this.activeAnnotation.coordinates;if(g.points.length>2&&z(h,g.points[0])<20/this.scale){this.finishDrawing();return}this.startDrawing(h);return}if(this.currentTool){if(this.currentTool==="polygon"&&!this.isDrawing){this.startDrawing(h);return}this.startDrawing(h)}return}this.activeAnnotation=null,this.render()}handleMouseMove(e){const i=this.canvas.getBoundingClientRect(),n=e.clientX-i.left,a=e.clientY-i.top,h=this.toImageCoords(n,a);if(this.isPanning&&this.panStartPoint){const c=n-this.panStartPoint.x,l=a-this.panStartPoint.y;this.offset.x+=c,this.offset.y+=l,this.clampViewportOffset(),this.panStartPoint={x:n,y:a},this.render();return}if(this.lastMouseMovePoint=h,this.isDrawing){if(this.currentTool==="polygon"&&this.activeAnnotation){const c=this.activeAnnotation.coordinates;if(c.points.length>2){const l=c.points[0],g=z(h,l);this.isHoveringStartPoint=g<20/this.scale}else this.isHoveringStartPoint=!1}this.updateDrawing(h)}else this.isDragging&&this.activeAnnotation&&this.dragStartPoint?this.updateDragging(h):this.checkHover(n,a,h);this.render()}handleMouseUp(e){if(this.isPanning){this.isPanning=!1,this.panStartPoint=null,this.canvas.style.cursor="grab";return}if(this.isDrawing){if(this.currentTool==="polygon"){this.render();return}this.finishDrawing()}else this.isDragging&&this.activeAnnotation&&this.emit("annotationChange",{action:"update",changedItem:this.activeAnnotation,imageUrl:this.imageUrl});this.currentTool!=="polygon"&&(this.isDrawing=!1),this.isDragging=!1,this.dragStartPoint=null,this.selectedHandleIndex=-1,this.render()}hexToRgba(e,i){if(!e.startsWith("#"))return e;const n=parseInt(e.slice(1,3),16),a=parseInt(e.slice(3,5),16),h=parseInt(e.slice(5,7),16);return`rgba(${n}, ${a}, ${h}, ${i})`}startDrawing(e){if(!this.currentTool)return;const i=Date.now().toString();if(this.hexToRgba(this.currentLabelColor,.2),this.currentLabelColor,this.currentTool==="rectangle")this.isDrawing=!0,this.dragStartPoint=e,this.activeAnnotation={id:i,type:"rectangle",label:"",coordinates:{x1:e.x,y1:e.y,x2:e.x,y2:e.y},style:{strokeColor:this.currentLabelColor}};else if(this.currentTool==="point"){const n={id:i,type:"point",label:"",coordinates:{points:[e]},style:{strokeColor:this.currentLabelColor}};this.annotations.push(n),this.emit("annotationChange",{action:"add",changedItem:n,imageUrl:this.imageUrl}),this.activeAnnotation=n}else if(this.currentTool==="polygon")this.activeAnnotation&&this.activeAnnotation.type==="polygon"&&this.isDrawing?this.activeAnnotation.coordinates.points.push(e):(this.isDrawing=!0,this.activeAnnotation={id:i,type:"polygon",label:"",coordinates:{points:[e]},style:{strokeColor:this.currentLabelColor}});else if(this.currentTool==="category"){const n={id:i,type:"category",label:"",coordinates:null,style:{strokeColor:this.currentLabelColor}};this.annotations.push(n),this.emit("annotationChange",{action:"add",changedItem:n,imageUrl:this.imageUrl}),this.activeAnnotation=n}else this.currentTool==="rotatedRect"&&(this.isDrawing=!0,this.dragStartPoint=e,this.activeAnnotation={id:i,type:"rotatedRect",label:"",coordinates:{x:e.x,y:e.y,width:0,height:0,angle:0},style:{strokeColor:this.currentLabelColor}})}updateDrawing(e){if(this.activeAnnotation)if(this.activeAnnotation.type==="rectangle"&&this.dragStartPoint){const i=this.activeAnnotation.coordinates;i.x2=e.x,i.y2=e.y}else if(this.activeAnnotation.type==="rotatedRect"&&this.dragStartPoint){const i=this.activeAnnotation.coordinates,n=Math.abs(e.x-this.dragStartPoint.x),a=Math.abs(e.y-this.dragStartPoint.y);i.width=n*2,i.height=a*2}else this.activeAnnotation.type}finishDrawing(){if(this.activeAnnotation){if(this.activeAnnotation.type==="rectangle"){const e=this.activeAnnotation.coordinates;if(Math.abs(e.x1-e.x2)<2||Math.abs(e.y1-e.y2)<2){this.activeAnnotation=null,this.isDrawing=!1;return}const i=Math.min(e.x1,e.x2),n=Math.max(e.x1,e.x2),a=Math.min(e.y1,e.y2),h=Math.max(e.y1,e.y2);e.x1=i,e.x2=n,e.y1=a,e.y2=h,this.annotations.push(this.activeAnnotation),this.emit("annotationChange",{action:"add",changedItem:this.activeAnnotation,imageUrl:this.imageUrl})}else if(this.activeAnnotation.type==="polygon"){if(this.activeAnnotation.coordinates.points.length<3){this.activeAnnotation=null,this.isDrawing=!1;return}this.annotations.push(this.activeAnnotation),this.emit("annotationChange",{action:"add",changedItem:this.activeAnnotation,imageUrl:this.imageUrl})}else if(this.activeAnnotation.type==="rotatedRect"){const e=this.activeAnnotation.coordinates;if(e.width<2||e.height<2){this.activeAnnotation=null,this.isDrawing=!1;return}this.annotations.push(this.activeAnnotation),this.emit("annotationChange",{action:"add",changedItem:this.activeAnnotation,imageUrl:this.imageUrl})}this.activeAnnotation.type}this.isDrawing=!1}updateDragging(e){if(!this.activeAnnotation||!this.dragStartPoint||!this.dragStartAnnotation)return;const i=e.x-this.dragStartPoint.x,n=e.y-this.dragStartPoint.y;this.selectedHandleIndex===-1?this.moveAnnotation(this.activeAnnotation,this.dragStartAnnotation,i,n):this.resizeAnnotation(this.activeAnnotation,this.dragStartAnnotation,this.selectedHandleIndex,e)}moveAnnotation(e,i,n,a){if(e.type==="rectangle"){const h=i.coordinates,c=e.coordinates;c.x1=h.x1+n,c.x2=h.x2+n,c.y1=h.y1+a,c.y2=h.y2+a}else if(e.type==="point"){const h=i.coordinates,c=e.coordinates;c.points=h.points.map(l=>({x:l.x+n,y:l.y+a}))}else if(e.type==="rotatedRect"){const h=i.coordinates,c=e.coordinates;c.x=h.x+n,c.y=h.y+a}else if(e.type==="polygon"){const h=i.coordinates,c=e.coordinates;c.points=h.points.map(l=>({x:l.x+n,y:l.y+a}))}}resizeAnnotation(e,i,n,a){if(e.type==="rectangle"){const h=e.coordinates;n===0&&(h.x1=a.x,h.y1=a.y),n===1&&(h.x2=a.x,h.y1=a.y),n===2&&(h.x2=a.x,h.y2=a.y),n===3&&(h.x1=a.x,h.y2=a.y)}else if(e.type==="polygon"){const h=e.coordinates;n>=0&&n<h.points.length&&(h.points[n]=a)}else if(e.type==="point"){const h=e.coordinates;n>=0&&n<h.points.length&&(h.points[n]=a)}else if(e.type==="rotatedRect"){const h=e.coordinates;if(n===-2){const c=h.x,l=h.y,g=a.x-c,m=a.y-l;let x=Math.atan2(m,g)*180/Math.PI;x+=90,h.angle=x}else{const c=h.angle*Math.PI/180,l=Math.cos(-c),g=Math.sin(-c),m=a.x-h.x,x=a.y-h.y,u=m*l-x*g,k=m*g+x*l;(n===0||n===3)&&(h.width/2,h.width=Math.abs(u)*2),(n===1||n===2)&&(h.width=Math.abs(u)*2),(n===0||n===1)&&(h.height=Math.abs(k)*2),(n===2||n===3)&&(h.height=Math.abs(k)*2)}}}getHitAnnotation(e){for(let i=this.annotations.length-1;i>=0;i--){const n=this.annotations[i];if(this.isPointInAnnotation(e,n))return n}return null}isPointInAnnotation(e,i){if(i.type==="rectangle"){const n=i.coordinates;return e.x>=n.x1&&e.x<=n.x2&&e.y>=n.y1&&e.y<=n.y2}else if(i.type==="polygon"){const n=i.coordinates;return it(e,n.points)}else if(i.type==="rotatedRect"){const n=i.coordinates,a=q(e,{x:n.x,y:n.y},-n.angle),h=n.width/2,c=n.height/2;return a.x>=n.x-h&&a.x<=n.x+h&&a.y>=n.y-c&&a.y<=n.y+c}else if(i.type==="point")return i.coordinates.points.some(a=>z(e,a)<10/this.scale);return!1}getHitHandle(e,i,n){const a=this.getAnnotationHandles(n),h=6;for(let c=0;c<a.length;c++){const l=a[c],g=this.toScreenCoords(l.x,l.y);if(Math.abs(e-g.x)<h&&Math.abs(i-g.y)<h)return n.type==="rotatedRect"&&c===4?-2:c}return-100}getAnnotationHandles(e){if(e.type==="rectangle"){const i=e.coordinates;return[{x:i.x1,y:i.y1},{x:i.x2,y:i.y1},{x:i.x2,y:i.y2},{x:i.x1,y:i.y2}]}else{if(e.type==="polygon")return e.coordinates.points;if(e.type==="point")return e.coordinates.points;if(e.type==="rotatedRect"){const i=e.coordinates,n={x:i.x,y:i.y},a=i.width/2,h=i.height/2,c={x:i.x-a,y:i.y-h},l={x:i.x+a,y:i.y-h},g={x:i.x+a,y:i.y+h},m={x:i.x-a,y:i.y+h},x={x:i.x,y:i.y-h-20/this.scale};return[c,l,g,m,x].map(u=>q(u,n,i.angle))}}return[]}checkHover(e,i,n){const a=this.getHitCategory(e,i);if(a){this.canvas.style.cursor="pointer",this.hoverAnnotation=a;return}if(this.activeAnnotation&&this.getHitHandle(e,i,this.activeAnnotation)!==-100){this.canvas.style.cursor="pointer";return}const h=this.getHitAnnotation(n);h?(this.canvas.style.cursor="move",this.hoverAnnotation=h):(this.canvas.style.cursor="default",this.hoverAnnotation=null)}render(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.img.complete&&this.img.width>0&&this.ctx.drawImage(this.img,this.offset.x,this.offset.y,this.img.width*this.scale,this.img.height*this.scale),this.annotations.forEach(e=>{e!==this.activeAnnotation&&this.drawItem(e,!1)}),this.activeAnnotation&&this.drawItem(this.activeAnnotation,!0),this.renderCategories()}renderCategories(){const e=this.annotations.filter(g=>g.type==="category");if(e.length===0)return;this.ctx.save(),this.ctx.font="14px sans-serif",this.ctx.textBaseline="top";let i=10;const n=10,a=8,h=4,c=24,l=8;e.forEach(g=>{const m=g.label||"Unlabeled",x=this.ctx.measureText(m).width+a*2,u=this.activeAnnotation===g,k=this.hoverAnnotation===g;this.ctx.fillStyle=u?"#E3F2FD":k?"#F5F5F5":"rgba(255, 255, 255, 0.9)",this.ctx.strokeStyle=u?"#2196F3":"#666",this.ctx.lineWidth=u?2:1,this.ctx.beginPath(),this.ctx.rect(i,n,x,c),this.ctx.fill(),this.ctx.stroke(),this.ctx.fillStyle=u?"#1976D2":"#333",this.ctx.fillText(m,i+a,n+h),i+=x+l}),this.ctx.restore()}getHitCategory(e,i){const n=this.annotations.filter(x=>x.type==="category");if(n.length===0)return null;this.ctx.save(),this.ctx.font="14px sans-serif";let a=10;const h=10,c=8,l=24,g=8;let m=null;for(const x of n){const u=x.label||"Unlabeled",k=this.ctx.measureText(u).width+c*2;if(e>=a&&e<=a+k&&i>=h&&i<=h+l){m=x;break}a+=k+g}return this.ctx.restore(),m}drawItem(e,i){var h;if(this.visibleLabels.size>0&&!this.visibleLabels.has(e.label)&&!i)return;this.ctx.save();const n=((h=e.style)==null?void 0:h.strokeColor)||"#FF4081",a=i?"#00E5FF":n;if(this.ctx.strokeStyle=a,this.ctx.lineWidth=2,i?this.ctx.fillStyle="rgba(0, 229, 255, 0.2)":this.ctx.fillStyle=this.hexToRgba(n,.2),e.type==="rectangle"){const c=e.coordinates,l=this.toScreenCoords(c.x1,c.y1),g=this.toScreenCoords(c.x2,c.y2),m=Math.min(l.x,g.x),x=Math.min(l.y,g.y),u=Math.abs(l.x-g.x),k=Math.abs(l.y-g.y);this.ctx.strokeRect(m,x,u,k),this.ctx.fillStyle=i?"rgba(0, 229, 255, 0.2)":"rgba(255, 64, 129, 0.2)",this.ctx.fillRect(m,x,u,k),i&&this.drawHandles(this.getAnnotationHandles(e))}else if(e.type==="polygon"){const c=e.coordinates;if(c.points.length===0){this.ctx.restore();return}this.ctx.beginPath();const l=this.toScreenCoords(c.points[0].x,c.points[0].y);this.ctx.moveTo(l.x,l.y);for(let g=1;g<c.points.length;g++){const m=this.toScreenCoords(c.points[g].x,c.points[g].y);this.ctx.lineTo(m.x,m.y)}if(!this.isDrawing||e!==this.activeAnnotation)this.ctx.closePath();else if(this.lastMouseMovePoint){let g=this.lastMouseMovePoint;if(this.isHoveringStartPoint&&c.points.length>0){g=c.points[0];const x=this.toScreenCoords(c.points[0].x,c.points[0].y);this.ctx.save(),this.ctx.beginPath(),this.ctx.arc(x.x,x.y,10,0,Math.PI*2),this.ctx.fillStyle="rgba(255, 215, 0, 0.6)",this.ctx.strokeStyle="#FFFFFF",this.ctx.lineWidth=2,this.ctx.fill(),this.ctx.stroke(),this.ctx.restore()}const m=this.toScreenCoords(g.x,g.y);this.ctx.lineTo(m.x,m.y)}this.ctx.stroke(),this.ctx.fillStyle=i?"rgba(0, 229, 255, 0.2)":"rgba(255, 64, 129, 0.2)",this.ctx.fill(),i&&this.drawHandles(this.getAnnotationHandles(e))}else if(e.type==="rotatedRect"){const c=e.coordinates;this.ctx.translate(this.toScreenCoords(c.x,c.y).x,this.toScreenCoords(c.x,c.y).y),this.ctx.rotate(c.angle*Math.PI/180);const l=c.width*this.scale,g=c.height*this.scale;this.ctx.strokeRect(-l/2,-g/2,l,g),this.ctx.fillStyle=i?"rgba(0, 229, 255, 0.2)":"rgba(255, 64, 129, 0.2)",this.ctx.fillRect(-l/2,-g/2,l,g),this.ctx.rotate(-c.angle*Math.PI/180),this.ctx.translate(-this.toScreenCoords(c.x,c.y).x,-this.toScreenCoords(c.x,c.y).y),i&&this.drawHandles(this.getAnnotationHandles(e))}else e.type==="point"&&e.coordinates.points.forEach(l=>{const g=this.toScreenCoords(l.x,l.y);this.ctx.beginPath(),this.ctx.arc(g.x,g.y,5,0,Math.PI*2),this.ctx.fillStyle=i?"#00E5FF":n,this.ctx.fill(),this.ctx.stroke()});this.ctx.restore()}drawHandles(e){this.ctx.fillStyle="#FFFFFF",this.ctx.strokeStyle="#000000",this.ctx.lineWidth=1,e.forEach(i=>{const n=this.toScreenCoords(i.x,i.y);this.ctx.fillRect(n.x-4,n.y-4,8,8),this.ctx.strokeRect(n.x-4,n.y-4,8,8)})}}const lt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
2
|
-
<path d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z m0-320a64 64 0 1 0 0-128 64 64 0 0 0 0 128z m0 64a128 128 0 1 1 0-256 128 128 0 0 1 0 256z" fill="currentColor"/>\r
|
|
3
|
-
</svg>`,rt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
4
|
-
<path d="M609.408 149.376l-277.76 277.76a96 96 0 0 0 0 135.68l277.76 277.76a32 32 0 1 0 45.248-45.248L376.96 512l277.76-277.76a32 32 0 0 0-45.248-45.248z" fill="currentColor"/>\r
|
|
5
|
-
</svg>`,ct=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
6
|
-
<path d="M704 192h160v160h-160z m-64-64v288h288V128H640zM160 672h160v160H160z m-64-64v288h288V608H96z m256-320h320v64H352z" fill="currentColor"/>\r
|
|
7
|
-
</svg>`,ht=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
8
|
-
<path d="M256 256h512v512H256z m-64-64v640h640V192H192z" fill="currentColor"/>\r
|
|
9
|
-
</svg>`,dt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
10
|
-
<path d="M160 256h704a32 32 0 1 1 0 64h-64v608a32 32 0 0 1-32 32H256a32 32 0 0 1-32-32V320h-64a32 32 0 1 1 0-64zm128 64v576h448V320H288z m128 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zm256 0v512a32 32 0 1 1-64 0V320a32 32 0 1 1 64 0zM352 128h320a32 32 0 0 1 32 32v64H320v-64a32 32 0 0 1 32-32z" fill="currentColor"/>\r
|
|
11
|
-
</svg>`,gt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
12
|
-
<path d="M512 666.56l-186.88-186.88a32 32 0 0 0-45.248 45.248l209.536 209.536a96 96 0 0 0 135.68 0l209.536-209.536a32 32 0 1 0-45.248-45.248L544 666.56V128a32 32 0 0 0-64 0v538.56zM192 832h640a32 32 0 1 1 0 64H192a32 32 0 1 1 0-64z" fill="currentColor"/>\r
|
|
13
|
-
</svg>`,mt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
14
|
-
<path d="M832 512a32 32 0 1 1 64 0v352a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h352a32 32 0 0 1 0 64H192v640h640V512z m-144-320l-480 480v160h160l480-480-160-160z m-114.56 480H256v-117.76L653.44 236.8l117.76 117.76L573.44 672z m208-208l-117.76-117.76 66.56-66.56a32 32 0 0 1 45.248 0l72.512 72.512a32 32 0 0 1 0 45.248l-66.56 66.56z" fill="currentColor"/>\r
|
|
15
|
-
</svg>`,ft=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
16
|
-
<path d="M940.48 876.16L148.16 83.84a32 32 0 1 0-45.12 45.12L236.8 262.4C163.52 337.28 107.52 429.12 82.56 528.96a32 32 0 0 0 0 20.48C144.384 727.68 314.88 840.96 512 840.96c103.04 0 199.36-30.72 283.52-83.84l99.84 99.84a32 32 0 1 0 45.12-45.12zM512 776.96c-176.64 0-333.44-98.56-402.56-248.96 25.6-56.32 63.36-107.52 110.08-151.04L364.8 522.24a128 128 0 0 0 147.2 147.2l123.52 123.52A445.44 445.44 0 0 1 512 776.96z m373.12-32.64l-64-64C857.6 627.84 879.616 572.16 879.616 512c0-176.64-156.8-328.96-367.616-328.96-58.24 0-113.6 11.52-164.48 32.64l-55.68-55.68C346.88 136.96 427.52 119.04 512 119.04c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48 450.56 450.56 0 0 1-120.32 258.56z m-309.12-309.12l-128-128A128 128 0 0 1 576 435.2z" fill="currentColor"/>\r
|
|
17
|
-
</svg>`,ut=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
18
|
-
<path d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 832a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm-48-384H320a32 32 0 0 1 0-64h144V304a32 32 0 1 1 64 0v144h144a32 32 0 1 1 0 64H528v144a32 32 0 1 1-64 0V512z" fill="currentColor"/>\r
|
|
19
|
-
</svg>`,pt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
20
|
-
<path d="M224 448a32 32 0 0 0 9.536 22.592l416 416a32 32 0 0 0 45.248 0l226.24-226.24a32 32 0 0 0 0-45.248l-416-416A32 32 0 0 0 482.432 192H256a64 64 0 0 0-64 64v192z m64-192h160l384 384-160 160-384-384V256z m64 128a64 64 0 1 0 0-128 64 64 0 0 0 0 128z" fill="currentColor"/>\r
|
|
21
|
-
</svg>`,yt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
22
|
-
<path d="M160 832h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0-704h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64zm0 352h704a32 32 0 1 1 0 64H160a32 32 0 1 1 0-64z" fill="currentColor"/>\r
|
|
23
|
-
</svg>`,vt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
24
|
-
<path d="M784.512 230.272v-50.56a32 32 0 1 1 64 0v149.056a32 32 0 0 1-32 32H667.52a32 32 0 1 1 0-64h92.992A320 320 0 1 0 524.8 833.152a320 320 0 0 0 320-320h64a384 384 0 0 1-384 384 384 384 0 0 1-384-384 384 384 0 0 1 643.712-282.88z" fill="currentColor"/>\r
|
|
25
|
-
</svg>`,xt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
26
|
-
<path d="M340.864 149.376a32 32 0 0 0-45.248 45.248L573.44 512l-277.76 317.376a32 32 0 0 0 45.248 45.248l277.76-277.76a96 96 0 0 0 0-135.68L340.864 149.376z" fill="currentColor"/>\r
|
|
27
|
-
</svg>`,bt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
28
|
-
<path d="M512 192c229.76 0 425.216 142.08 493.44 346.24a32 32 0 0 1 0 20.48C937.216 762.88 741.76 904.96 512 904.96S86.784 762.88 18.56 558.72a32 32 0 0 1 0-20.48C86.784 334.08 282.24 192 512 192zm0 64c-197.12 0-367.616 120.32-428.16 296.32C144.384 727.68 314.88 840.96 512 840.96s367.616-113.28 428.16-288.64C879.616 376.32 709.12 256 512 256zm0 160a128 128 0 1 1 0 256 128 128 0 0 1 0-256zm0 64a64 64 0 1 0 0 128 64 64 0 0 0 0-128z" fill="currentColor"/>\r
|
|
29
|
-
</svg>`,wt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
30
|
-
<path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM416 448h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64h96v-96a32 32 0 0 1 64 0v96z" fill="currentColor"/>\r
|
|
31
|
-
</svg>`,kt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
|
|
32
|
-
<path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM256 448h320a32 32 0 1 1 0 64H256a32 32 0 1 1 0-64z" fill="currentColor"/>\r
|
|
33
|
-
</svg>`,Ct=["innerHTML"],_t=t.defineComponent({__name:"SvgIcon",props:{name:{},size:{}},setup(y){const e=y,i=t.ref(""),n=Object.assign({"../assets/svg/aim.svg":lt,"../assets/svg/back.svg":rt,"../assets/svg/connection.svg":ct,"../assets/svg/crop.svg":ht,"../assets/svg/delete.svg":dt,"../assets/svg/download.svg":gt,"../assets/svg/edit.svg":mt,"../assets/svg/hide.svg":ft,"../assets/svg/pointer.svg":ut,"../assets/svg/price-tag.svg":pt,"../assets/svg/rank.svg":yt,"../assets/svg/refresh-right.svg":vt,"../assets/svg/right.svg":xt,"../assets/svg/view.svg":bt,"../assets/svg/zoom-in.svg":wt,"../assets/svg/zoom-out.svg":kt});return t.watchEffect(()=>{const a=`../assets/svg/${e.name}.svg`,h=n[a];h?i.value=h:(console.warn(`Icon ${e.name} not found at path ${a}`),i.value="")}),(a,h)=>(t.openBlock(),t.createElementBlock("i",{class:t.normalizeClass(["svg-icon",[y.size?`size-${y.size}`:""]]),innerHTML:i.value},null,10,Ct))}}),F=(y,e)=>{const i=y.__vccOpts||y;for(const[n,a]of e)i[n]=a;return i},E=F(_t,[["__scopeId","data-v-3928607b"]]),At={key:0,class:"image-list-sidebar"},It={class:"image-list-title"},St={class:"image-list-scroll"},Bt=["onClick"],Et={class:"image-list-stage"},Vt=["src","alt"],Nt={key:0,class:"thumb-overlay-layer"},zt={key:1,class:"thumb-overlay-svg",viewBox:"0 0 100 100",preserveAspectRatio:"none"},Mt=["points"],Tt={class:"image-list-text"},$t={key:1,class:"left-sidebar"},Dt=["onClick","title"],Pt={class:"center-area"},Lt={key:0,class:"top-bar"},Ht={class:"label-selector"},Rt={class:"tags-row"},Ft=["onClick"],Ut={key:0,class:"no-labels"},Ot={key:1,class:"batch-nav"},Wt=["disabled"],Jt=["disabled"],jt={key:2,class:"right-sidebar"},Yt={class:"label-list"},Xt={class:"label-row"},qt=["onUpdate:modelValue","onChange"],Gt=["title"],Kt=["onClick"],Zt={class:"action-icon more-actions"},Qt=["onClick"],te={key:3,class:"modal-overlay"},ee={class:"modal-content"},ne={class:"form-group"},oe={class:"form-group"},se={class:"color-input-wrapper"},G=F(t.defineComponent({__name:"ImageAnnotator",props:{annotationTypes:{default:()=>["rectangle","polygon","point","rotatedRect"]},batchImages:{default:()=>[]},labels:{default:()=>[]},defaultActiveType:{},theme:{default:"light"},readOnly:{type:Boolean,default:!1},image:{},predictionCandidates:{},session:{},requestId:{},minZoom:{},maxZoom:{}},emits:["annotationChange","batchChange","labelChange","ready","error","tool:change","viewport:change","annotation:add","annotation:update","annotation:delete","annotation:select","prediction:loaded","prediction:apply","prediction:reject"],setup(y,{expose:e,emit:i}){const n=y,a=i,h=t.ref(null),c=t.ref(null),l=t.ref(null),g=t.ref(null),m=t.ref(0),x=t.ref(""),u=t.ref([]),k=t.ref(""),N=t.ref(!1),_=t.ref({name:"",color:"#FF0000"}),C=t.ref("none"),b=t.ref([]),V=t.ref({}),$=t.computed(()=>g.value==="select"&&!!x.value),P=o=>{if(!o||V.value[o])return;const s=new Image;s.onload=()=>{const r=s.naturalWidth||1,d=s.naturalHeight||1;V.value={...V.value,[o]:{width:r,height:d}}},s.src=o},L=()=>{n.batchImages.forEach(o=>{P(o.imageUrl)})},M=()=>{var r,d,f,w;const o=n.batchImages[m.value],s=(o==null?void 0:o.imageUrl)||((r=n.image)==null?void 0:r.url);return{eventId:`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,timestamp:Date.now(),requestId:n.requestId,taskId:(d=n.session)==null?void 0:d.taskId,imageId:((f=n.image)==null?void 0:f.id)||s,operator:(w=n.session)==null?void 0:w.userId}},Z=o=>{var d;const s=o==null?void 0:o.action;if(!s)return;const r={meta:M(),action:s,current:o==null?void 0:o.changedItem,source:(d=o==null?void 0:o.changedItem)!=null&&d.predictionId?"prediction":"manual"};s==="add"&&a("annotation:add",r),s==="update"&&a("annotation:update",r),s==="delete"&&a("annotation:delete",r),s==="select"&&a("annotation:select",r)},W=t.computed(()=>n.annotationTypes.filter(o=>o!=="category")),J=o=>({rectangle:"crop",polygon:"connection",point:"aim",rotatedRect:"refresh-right",category:"price-tag"})[o]||o,j=o=>({rectangle:"矩形框",polygon:"多边形",point:"关键点",rotatedRect:"旋转矩形",category:"分类标签"})[o]||o;t.onMounted(()=>{if(L(),h.value){l.value=new at(h.value),l.value.on("annotationChange",s=>{var r,d;if(s.action==="add"&&s.changedItem){const f=u.value.find(w=>w.id===k.value);f&&(s.changedItem.label=f.name,s.changedItem.labelId=f.id)}s.action==="select"?x.value=((r=s.changedItem)==null?void 0:r.id)||"":s.action==="delete"&&((d=s.changedItem)==null?void 0:d.id)===x.value&&(x.value=""),a("annotationChange",s),Z(s)}),D(),T();const o=new ResizeObserver(()=>{var s;(s=l.value)==null||s.resize()});c.value&&o.observe(c.value),n.defaultActiveType&&p(n.defaultActiveType),a("ready",{meta:M()})}});const T=()=>{if(!l.value)return;const o=u.value.find(r=>r.id===k.value);o&&l.value.setLabelStyle(o.color);const s=u.value.filter(r=>r.visible).map(r=>r.name);l.value.setVisibleLabels(s)},D=()=>{var o;if(l.value)if(x.value="",requestAnimationFrame(()=>{var s;(s=l.value)==null||s.resize()}),n.batchImages.length>0){const s=n.batchImages[m.value];l.value.loadImage(s.imageUrl),s.annotations?l.value.setAnnotations(s.annotations):l.value.setAnnotations([])}else(o=n.image)!=null&&o.url&&l.value.loadImage(n.image.url)},p=o=>{var s,r;if(g.value=o,x.value="",o!=="pan"&&o!=="select"&&u.value.length===0){alert("请先创建标签!");return}o==="pan"||o==="select"?(s=l.value)==null||s.setTool(o):(r=l.value)==null||r.setTool(o),a("tool:change",{meta:M(),tool:o})},v=()=>{var o;(o=l.value)!=null&&o.activeAnnotation&&l.value.deleteAnnotation(l.value.activeAnnotation.id)},I=()=>{l.value&&a("viewport:change",{meta:M(),scale:l.value.scale,offset:{...l.value.offset}})},H=()=>{var o;(o=l.value)==null||o.zoom(1),I()},Q=()=>{var o;(o=l.value)==null||o.zoom(-1),I()},Se=()=>{_.value={name:"",color:"#2196F3"},N.value=!0},tt=()=>{N.value=!1},Be=()=>{if(!_.value.name.trim()){alert("请输入标签名称");return}const s={id:Date.now().toString(),name:_.value.name,color:_.value.color,visible:!0};u.value.push(s),a("labelChange",u.value),T(),u.value.length===1&&R(s),tt()},R=o=>{var s;k.value=o.id,(s=l.value)==null||s.setLabelStyle(o.color)},Ee=(o,s)=>{if(!o.startsWith("#"))return o;let r=0,d=0,f=0;return o.length===4?(r=parseInt(o[1]+o[1],16),d=parseInt(o[2]+o[2],16),f=parseInt(o[3]+o[3],16)):o.length===7&&(r=parseInt(o.slice(1,3),16),d=parseInt(o.slice(3,5),16),f=parseInt(o.slice(5,7),16)),`rgba(${r}, ${d}, ${f}, ${s})`},Ve=o=>{var s;if(o.id===k.value&&((s=l.value)==null||s.setLabelStyle(o.color)),l.value){const r=l.value.getAnnotations();let d=!1;r.forEach(f=>{f.label===o.name&&(f.style||(f.style={}),f.style.strokeColor=o.color,f.style.fillColor=Ee(o.color,.2),d=!0)}),d&&l.value.render()}a("labelChange",u.value),T()},Ne=o=>{o.visible=!o.visible,T()},ze=o=>{const s=u.value.findIndex(r=>r.id===o);s>-1&&(u.value.splice(s,1),a("labelChange",u.value),k.value===o&&(k.value=u.value.length>0?u.value[0].id:"",k.value&&R(u.value[0])),T())};t.watch(()=>n.labels,o=>{const s=JSON.parse(JSON.stringify(o||[]));if(u.value=s,u.value.length>0)if(!k.value||!u.value.find(r=>r.id===k.value))R(u.value[0]);else{const r=u.value.find(d=>d.id===k.value);r&&R(r)}else k.value="";T()},{immediate:!0,deep:!0});const Me=()=>{m.value>0&&(Y(),m.value--,D(),X())},Te=()=>{m.value<n.batchImages.length-1&&(Y(),m.value++,D(),X())},Y=()=>{if(l.value){const o=l.value.getAnnotations();n.batchImages[m.value].annotations=o}},X=()=>{const o=n.batchImages[m.value];a("batchChange",{currentIndex:m.value,total:n.batchImages.length,currentImageUrl:o.imageUrl,currentAnnotations:o.annotations||[]})},et=(o=[])=>{var f;if(!l.value)return;if(b.value=JSON.parse(JSON.stringify(o)),b.value.length===0){C.value="none";return}C.value="loaded";const r=(l.value.getAnnotations()||[]).filter(w=>!w.predictionId),d=b.value.map(w=>{const S=JSON.parse(JSON.stringify(w.annotation));return S.id=S.id||`pred-${w.id}`,S.predictionId=w.id,S.modelRunId=w.modelRunId||S.modelRunId,S.confidence=w.confidence??S.confidence,S.reviewStatus=S.reviewStatus||"draft",S});l.value.setAnnotations([...r,...d]),a("prediction:loaded",{meta:M(),modelRunId:(f=b.value[0])==null?void 0:f.modelRunId,candidates:b.value})},$e=(o,s)=>{var f;if(!l.value)return[];C.value="applying";const d=(l.value.getAnnotations()||[]).filter(w=>w.predictionId&&o.includes(w.predictionId));return d.forEach(w=>{w.reviewStatus="accepted"}),C.value="applied",a("prediction:apply",{meta:M(),modelRunId:(f=d[0])==null?void 0:f.modelRunId,candidateIds:o,threshold:s,acceptedAnnotations:d}),l.value.render(),d},De=(o,s)=>{var f;if(!l.value)return;const r=l.value.getAnnotations()||[],d=r.filter(w=>!(w.predictionId&&o.includes(w.predictionId)));l.value.setAnnotations(d),a("prediction:reject",{meta:M(),modelRunId:(f=r.find(w=>w.predictionId&&o.includes(w.predictionId)))==null?void 0:f.modelRunId,candidateIds:o,reason:s})},Pe=(o,s=[])=>{l.value&&(l.value.loadImage(o.url),l.value.setAnnotations(s))},Le=o=>{var s;(s=l.value)==null||s.setAnnotations(o)},nt=()=>{var o;return((o=l.value)==null?void 0:o.getAnnotations())||[]},He=(o="json")=>{var r,d;const s=nt();return{format:o,image:((r=n.batchImages[m.value])==null?void 0:r.imageUrl)||((d=n.image)==null?void 0:d.url)||"",annotations:s}},ot=o=>{o>=0&&o<n.batchImages.length&&(Y(),m.value=o,D(),X())},Re=o=>{var s;return o===m.value&&l.value?l.value.getAnnotations()||[]:((s=n.batchImages[o])==null?void 0:s.annotations)||[]},Fe=o=>o.type==="rectangle",Ue=o=>o.type==="polygon",Oe=o=>o.type==="point",We=o=>o.type==="rotatedRect",U=o=>{var r,d;const s=(r=u.value.find(f=>f.name===o.label))==null?void 0:r.color;return((d=o.style)==null?void 0:d.strokeColor)||s||"#409eff"},st=o=>{const s=o.coordinates;return(s==null?void 0:s.points)||[]},O=o=>{const s=n.batchImages[o];if(s!=null&&s.width&&(s!=null&&s.height))return{width:s.width,height:s.height};const r=s!=null&&s.imageUrl?V.value[s.imageUrl]:void 0;return r||(s!=null&&s.imageUrl&&P(s.imageUrl),{width:1,height:1})},Je=o=>{const s=n.batchImages[o];return s!=null&&s.width&&(s!=null&&s.height)?!0:s!=null&&s.imageUrl?!!V.value[s.imageUrl]:!1},je=(o,s)=>{const r=s.coordinates,d=O(o),f=U(s),w=Math.min(r.x1,r.x2),S=Math.min(r.y1,r.y2),Ke=Math.max(r.x1,r.x2),Ze=Math.max(r.y1,r.y2);return{left:`${w/d.width*100}%`,top:`${S/d.height*100}%`,width:`${(Ke-w)/d.width*100}%`,height:`${(Ze-S)/d.height*100}%`,borderColor:f,backgroundColor:`${f}22`}},Ye=(o,s)=>{const r=O(o);return st(s).map(d=>`${d.x/r.width*100},${d.y/r.height*100}`).join(" ")},Xe=o=>{const s=U(o);return{fill:`${s}33`,stroke:s,strokeWidth:"1.4"}},qe=(o,s,r)=>{const d=O(o),f=U(r);return{left:`${s.x/d.width*100}%`,top:`${s.y/d.height*100}%`,backgroundColor:f}},Ge=(o,s)=>{const r=s.coordinates,d=O(o),f=U(s),w=Math.abs(r.width),S=Math.abs(r.height);return{left:`${(r.x-w/2)/d.width*100}%`,top:`${(r.y-S/2)/d.height*100}%`,width:`${w/d.width*100}%`,height:`${S/d.height*100}%`,transform:`rotate(${r.angle||0}deg)`,borderColor:f,backgroundColor:`${f}22`}};return e({jumpTo:ot,setImage:Pe,setAnnotations:Le,getAnnotations:nt,selectTool:p,loadPredictionCandidates:et,applyPredictions:$e,rejectPredictions:De,exportAnnotations:He,getAllAnnotations:()=>{var o,s;return n.batchImages.length>0?n.batchImages:[{imageUrl:((o=n.image)==null?void 0:o.url)||"",annotations:((s=l.value)==null?void 0:s.getAnnotations())||[]}]},getCurrentAnnotation:()=>{var o,s,r;return{imageUrl:((o=n.batchImages[m.value])==null?void 0:o.imageUrl)||((s=n.image)==null?void 0:s.url)||"",annotations:((r=l.value)==null?void 0:r.getAnnotations())||[]}}}),t.watch(()=>{var o;return(o=n.image)==null?void 0:o.url},()=>{var o;n.batchImages.length===0&&((o=n.image)!=null&&o.url)&&D()}),t.watch(()=>n.predictionCandidates,o=>{o&&et(o)},{immediate:!0,deep:!0}),t.watch(()=>n.batchImages.map(o=>`${o.imageUrl}:${o.width||""}x${o.height||""}`),()=>{L()},{immediate:!0}),(o,s)=>(t.openBlock(),t.createElementBlock("div",{class:t.normalizeClass(["annotation-container",y.theme])},[y.batchImages&&y.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",At,[t.createElementVNode("div",It,"批量图片("+t.toDisplayString(y.batchImages.length)+")",1),t.createElementVNode("div",St,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.batchImages,(r,d)=>(t.openBlock(),t.createElementBlock("button",{key:`${r.imageUrl}-${d}`,class:t.normalizeClass(["image-list-item",{active:d===m.value}]),onClick:f=>ot(d)},[t.createElementVNode("div",Et,[t.createElementVNode("img",{src:r.imageUrl,alt:`第${d+1}张`,class:"image-list-thumb"},null,8,Vt),Je(d)?(t.openBlock(),t.createElementBlock("div",Nt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(Re(d),f=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:f.id},[Fe(f)?(t.openBlock(),t.createElementBlock("div",{key:0,class:"thumb-overlay-rect",style:t.normalizeStyle(je(d,f))},null,4)):Ue(f)?(t.openBlock(),t.createElementBlock("svg",zt,[t.createElementVNode("polygon",{points:Ye(d,f),style:t.normalizeStyle(Xe(f))},null,12,Mt)])):Oe(f)?(t.openBlock(!0),t.createElementBlock(t.Fragment,{key:2},t.renderList(st(f),(w,S)=>(t.openBlock(),t.createElementBlock("div",{key:`${f.id}-${S}`,class:"thumb-overlay-point",style:t.normalizeStyle(qe(d,w,f))},null,4))),128)):We(f)?(t.openBlock(),t.createElementBlock("div",{key:3,class:"thumb-overlay-rotated",style:t.normalizeStyle(Ge(d,f))},null,4)):t.createCommentVNode("",!0)],64))),128))])):t.createCommentVNode("",!0)]),t.createElementVNode("span",Tt,"第 "+t.toDisplayString(d+1)+" 张",1)],10,Bt))),128))])])):t.createCommentVNode("",!0),y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",$t,[t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:g.value==="pan"}]),onClick:s[0]||(s[0]=r=>p("pan")),title:"拖动"},[t.createVNode(E,{name:"rank"})],2),t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:g.value==="select"}]),onClick:s[1]||(s[1]=r=>p("select")),title:"选择"},[t.createVNode(E,{name:"pointer"})],2),s[5]||(s[5]=t.createElementVNode("div",{class:"divider"},null,-1)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(W.value,r=>(t.openBlock(),t.createElementBlock("div",{key:r,class:t.normalizeClass(["tool-btn",{active:g.value===r}]),onClick:d=>p(r),title:j(r)},[t.createVNode(E,{name:J(r)},null,8,["name"])],10,Dt))),128)),s[6]||(s[6]=t.createElementVNode("div",{class:"divider"},null,-1)),t.createElementVNode("div",{class:"tool-btn",onClick:H,title:"放大"},[t.createVNode(E,{name:"zoom-in"})]),t.createElementVNode("div",{class:"tool-btn",onClick:Q,title:"缩小"},[t.createVNode(E,{name:"zoom-out"})]),s[7]||(s[7]=t.createElementVNode("div",{class:"divider"},null,-1)),$.value?(t.openBlock(),t.createElementBlock("div",{key:0,class:"tool-btn",onClick:v,title:"删除选中"},[t.createVNode(E,{name:"delete"})])):t.createCommentVNode("",!0)])),t.createElementVNode("div",Pt,[y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Lt,[t.createElementVNode("div",Ht,[s[8]||(s[8]=t.createElementVNode("span",{class:"label-text"},"当前标签:",-1)),t.createElementVNode("div",Rt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(u.value,r=>(t.openBlock(),t.createElementBlock("div",{key:r.id,class:t.normalizeClass(["tag-chip",{active:k.value===r.id}]),style:t.normalizeStyle({backgroundColor:r.color,borderColor:r.color}),onClick:d=>R(r)},t.toDisplayString(r.name),15,Ft))),128)),u.value.length===0?(t.openBlock(),t.createElementBlock("div",Ut,"请在右侧创建标签")):t.createCommentVNode("",!0)])])])),t.createElementVNode("div",{class:"canvas-wrapper",ref_key:"canvasWrapper",ref:c,onWheel:s[2]||(s[2]=t.withModifiers(()=>{},["prevent"]))},[t.createElementVNode("canvas",{ref_key:"canvasRef",ref:h},null,512)],544),y.batchImages&&y.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",Ot,[t.createElementVNode("button",{onClick:Me,disabled:m.value<=0},[t.createVNode(E,{name:"back"}),s[9]||(s[9]=t.createTextVNode(" 上一张 ",-1))],8,Wt),t.createElementVNode("span",null,t.toDisplayString(m.value+1)+" / "+t.toDisplayString(y.batchImages.length),1),t.createElementVNode("button",{onClick:Te,disabled:m.value>=y.batchImages.length-1},[s[10]||(s[10]=t.createTextVNode(" 下一张 ",-1)),t.createVNode(E,{name:"right"})],8,Jt)])):t.createCommentVNode("",!0)]),y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",jt,[t.createElementVNode("div",{class:"sidebar-header"},[s[11]||(s[11]=t.createElementVNode("h3",null,"标签管理",-1)),t.createElementVNode("button",{class:"add-btn",onClick:Se},"添加标签")]),t.createElementVNode("div",Yt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(u.value,r=>(t.openBlock(),t.createElementBlock("div",{key:r.id,class:"label-item"},[t.createElementVNode("div",Xt,[t.createElementVNode("label",{class:"color-wrapper",style:t.normalizeStyle({backgroundColor:r.color})},[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":d=>r.color=d,onChange:d=>Ve(r),style:{visibility:"hidden",width:"0",height:"0"}},null,40,qt),[[t.vModelText,r.color]])],4),t.createElementVNode("span",{class:"label-name",title:r.name},t.toDisplayString(r.name),9,Gt),t.createElementVNode("span",{class:"action-icon eye",onClick:d=>Ne(r)},[r.visible?(t.openBlock(),t.createBlock(E,{key:0,name:"view"})):(t.openBlock(),t.createBlock(E,{key:1,name:"hide"}))],8,Kt),t.createElementVNode("div",Zt,[s[12]||(s[12]=t.createElementVNode("span",{class:"dots"},"•••",-1)),t.createElementVNode("span",{class:"delete-btn",onClick:d=>ze(r.id),title:"删除"},[t.createVNode(E,{name:"delete"})],8,Qt)])])]))),128))])])),N.value?(t.openBlock(),t.createElementBlock("div",te,[t.createElementVNode("div",ee,[s[15]||(s[15]=t.createElementVNode("h3",null,"新增标签",-1)),t.createElementVNode("div",ne,[s[13]||(s[13]=t.createElementVNode("label",null,"名称",-1)),t.withDirectives(t.createElementVNode("input",{"onUpdate:modelValue":s[3]||(s[3]=r=>_.value.name=r),placeholder:"请输入标签名称",class:"modal-input"},null,512),[[t.vModelText,_.value.name]])]),t.createElementVNode("div",oe,[s[14]||(s[14]=t.createElementVNode("label",null,"颜色",-1)),t.createElementVNode("div",se,[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":s[4]||(s[4]=r=>_.value.color=r),class:"modal-color-picker"},null,512),[[t.vModelText,_.value.color]]),t.createElementVNode("span",null,t.toDisplayString(_.value.color),1)])]),t.createElementVNode("div",{class:"modal-actions"},[t.createElementVNode("button",{onClick:tt,class:"cancel-btn"},"取消"),t.createElementVNode("button",{onClick:Be,class:"confirm-btn"},"确认")])])])):t.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-ccc538f3"]]),ie={class:"thumbnail-wrapper",ref:"wrapper"},ae=["src","alt"],le=["viewBox","preserveAspectRatio"],re=["x","y","width","height","stroke","stroke-width"],ce=["points","stroke","stroke-width"],he=["x","y","fill","font-size"],de={key:1,class:"loading-placeholder"},ge=F(t.defineComponent({__name:"AnnotationThumbnail",props:{src:{},annotations:{},alt:{},labels:{},fit:{},strokeWidth:{},fontSize:{}},setup(y){const e=y,i=t.ref(null),n=t.ref(!1),a=t.ref(0),h=t.ref(0),c=()=>{i.value&&(a.value=i.value.naturalWidth,h.value=i.value.naturalHeight,n.value=!0)},l=t.computed(()=>e.fit==="contain"?"xMidYMid meet":"xMidYMid slice"),g=t.computed(()=>e.strokeWidth??10),m=t.computed(()=>e.fontSize??30),x=_=>{var C;if((C=_.style)!=null&&C.strokeColor)return _.style.strokeColor;if(e.labels){const b=e.labels.find(V=>V.name===_.label);if(b)return b.color}return"#FF0000"},u=_=>{const C=_.coordinates,b=Math.min(C.x1,C.x2),V=Math.min(C.y1,C.y2),$=Math.abs(C.x1-C.x2),P=Math.abs(C.y1-C.y2);return{x:b,y:V,width:$,height:P}},k=_=>_.coordinates.points.map(b=>`${b.x},${b.y}`).join(" "),N=_=>{if(_.type==="rectangle"){const C=u(_);return{x:C.x,y:C.y-5}}else if(_.type==="polygon"){const C=_.coordinates.points;if(C.length>0)return{x:C[0].x,y:C[0].y-5}}return{x:0,y:0}};return(_,C)=>(t.openBlock(),t.createElementBlock("div",ie,[t.createElementVNode("img",{ref_key:"img",ref:i,src:y.src,class:"thumbnail-image",style:t.normalizeStyle({objectFit:y.fit}),onLoad:c,alt:y.alt},null,44,ae),n.value?(t.openBlock(),t.createElementBlock("svg",{key:0,class:"annotation-overlay",viewBox:`0 0 ${a.value} ${h.value}`,preserveAspectRatio:l.value},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.annotations,b=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:b.id},[b.type==="rectangle"?(t.openBlock(),t.createElementBlock("rect",{key:0,x:u(b).x,y:u(b).y,width:u(b).width,height:u(b).height,stroke:x(b),"stroke-width":g.value,fill:"transparent"},null,8,re)):t.createCommentVNode("",!0),b.type==="polygon"?(t.openBlock(),t.createElementBlock("polygon",{key:1,points:k(b),stroke:x(b),"stroke-width":g.value,fill:"transparent"},null,8,ce)):t.createCommentVNode("",!0),b.label?(t.openBlock(),t.createElementBlock("text",{key:2,x:N(b).x,y:N(b).y,fill:x(b),"font-size":m.value,"font-weight":"bold",class:"anno-label"},t.toDisplayString(b.label),9,he)):t.createCommentVNode("",!0)],64))),128))],8,le)):(t.openBlock(),t.createElementBlock("div",de,"Loading..."))],512))}}),[["__scopeId","data-v-d2fd08ec"]]),me={key:0,class:"gallery-view"},fe={class:"gallery-header"},ue={class:"label-summary"},pe=["onClick"],ye={class:"thumbnail-wrapper"},ve={class:"img-meta"},xe={class:"img-index"},be={class:"anno-count"},we={key:0,class:"bottom-bar"},ke={key:1,class:"editor-view"},Ce={class:"editor-header"},_e={class:"header-left"},Ae={class:"editor-title"},Ie={class:"editor-content"},K=F(t.defineComponent({__name:"BatchAnnotator",props:{images:{},labels:{},actionBar:{},clickToEnterEditor:{type:Boolean},thumbStrokeWidth:{},thumbFontSize:{}},emits:["export","update:images","imageClick","update:labels"],setup(y,{expose:e,emit:i}){const n=y,a=i,h=t.ref("gallery"),c=t.ref([]),l=t.ref([]),g=t.ref(0),m=t.ref(null),x=t.ref(null),u=t.ref(null),k=t.computed(()=>{var p,v;return((v=(p=n.actionBar)==null?void 0:p.annotateButton)==null?void 0:v.show)===!0}),N=t.computed(()=>{var p,v;return((v=(p=n.actionBar)==null?void 0:p.exportButton)==null?void 0:v.show)===!0}),_=t.computed(()=>k.value||N.value),C=t.computed(()=>{var p,v;return((v=(p=n.actionBar)==null?void 0:p.annotateButton)==null?void 0:v.text)||"手动标注"}),b=t.computed(()=>{var p,v;return((v=(p=n.actionBar)==null?void 0:p.exportButton)==null?void 0:v.text)||"导出"}),V=t.computed(()=>n.clickToEnterEditor!==!1);t.watch(()=>n.images,p=>{c.value=JSON.parse(JSON.stringify(p))},{immediate:!0,deep:!0}),t.watch(()=>n.labels,p=>{l.value=JSON.parse(JSON.stringify(p||[]))},{immediate:!0,deep:!0});const $=p=>{g.value=p,h.value="editor",u.value&&(u.value.scrollTop=0),t.nextTick(()=>{x.value&&(x.value.scrollTop=0),window.scrollTo(0,0),requestAnimationFrame(()=>{var v,I;(I=(v=m.value)==null?void 0:v.jumpTo)==null||I.call(v,p)})})},P=(p,v)=>{if(V.value){$(p);return}a("imageClick",{index:p,imageId:v.id,image:v})},L=p=>c.value.findIndex(v=>v.id===p);e({openImageById:p=>{const v=L(p);return v<0?!1:($(v),!0)},triggerImageClickById:p=>{const v=L(p);if(v<0)return!1;const I=c.value[v];return I?(a("imageClick",{index:v,imageId:I.id,image:I}),!0):!1},getFinalData:()=>({images:JSON.parse(JSON.stringify(c.value)),labels:JSON.parse(JSON.stringify(l.value))})});const W=()=>{if(m.value&&m.value.getCurrentAnnotation){const p=m.value.getCurrentAnnotation();c.value[g.value]&&(c.value[g.value].annotations=p.annotations)}h.value="gallery"},J=()=>{a("export",c.value)},j=p=>{g.value=p.currentIndex,c.value[p.currentIndex]&&(c.value[p.currentIndex].annotations=p.currentAnnotations)},T=p=>{if(m.value&&m.value.getCurrentAnnotation){const v=m.value.getCurrentAnnotation();c.value[g.value]&&(c.value[g.value].annotations=v.annotations,a("update:images",c.value))}},D=p=>{l.value=JSON.parse(JSON.stringify(p||[])),a("update:labels",l.value)};return(p,v)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"batchRootRef",ref:x,class:"batch-annotator"},[h.value==="gallery"?(t.openBlock(),t.createElementBlock("div",me,[t.createElementVNode("div",fe,[t.createElementVNode("h3",null,"批量查看与标注 ("+t.toDisplayString(c.value.length)+" 张)",1),t.createElementVNode("div",ue,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(l.value,I=>(t.openBlock(),t.createElementBlock("span",{key:I.id,class:"label-badge",style:t.normalizeStyle({backgroundColor:I.color})},t.toDisplayString(I.name),5))),128))])]),t.createElementVNode("div",{ref_key:"galleryGridRef",ref:u,class:"gallery-grid"},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(c.value,(I,H)=>(t.openBlock(),t.createElementBlock("div",{key:H,class:"gallery-item",onClick:Q=>P(H,I)},[t.createElementVNode("div",ye,[t.createVNode(ge,{src:I.imageUrl,annotations:I.annotations||[],labels:l.value,fit:"cover",strokeWidth:n.thumbStrokeWidth,fontSize:n.thumbFontSize},null,8,["src","annotations","labels","strokeWidth","fontSize"])]),t.createElementVNode("div",ve,[t.createElementVNode("span",xe,"#"+t.toDisplayString(H+1),1),t.createElementVNode("span",be,t.toDisplayString((I.annotations||[]).length)+" 标注",1)])],8,pe))),128))],512),_.value?(t.openBlock(),t.createElementBlock("div",we,[k.value?(t.openBlock(),t.createElementBlock("button",{key:0,class:"action-btn primary",onClick:v[0]||(v[0]=I=>$(0))},[t.createVNode(E,{name:"edit"}),t.createTextVNode(" "+t.toDisplayString(C.value),1)])):t.createCommentVNode("",!0),N.value?(t.openBlock(),t.createElementBlock("button",{key:1,class:"action-btn success",onClick:J},[t.createVNode(E,{name:"download"}),t.createTextVNode(" "+t.toDisplayString(b.value),1)])):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0)])):(t.openBlock(),t.createElementBlock("div",ke,[t.createElementVNode("div",Ce,[t.createElementVNode("div",_e,[t.createElementVNode("button",{class:"back-btn",onClick:W},[t.createVNode(E,{name:"back"}),v[1]||(v[1]=t.createTextVNode(" 返回列表 ",-1))]),t.createElementVNode("span",Ae,"正在标注: "+t.toDisplayString(g.value+1)+" / "+t.toDisplayString(c.value.length),1)])]),t.createElementVNode("div",Ie,[t.createVNode(G,{ref_key:"annotatorRef",ref:m,batchImages:c.value,labels:l.value,annotationTypes:["rectangle","polygon","point","rotatedRect"],onBatchChange:j,onAnnotationChange:T,onLabelChange:D},null,8,["batchImages","labels"])])]))],512))}}),[["__scopeId","data-v-0ae1040a"]]);B.BatchAnnotator=K,B.ImageAnnotator=G,B.default=K,Object.defineProperties(B,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
1
|
+
(function(T,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],t):(T=typeof globalThis<"u"?globalThis:T||self,t(T.VueImageAnnotator={},T.Vue))})(this,(function(T,t){"use strict";var Tn=Object.defineProperty;var Dn=(T,t,H)=>t in T?Tn(T,t,{enumerable:!0,configurable:!0,writable:!0,value:H}):T[t]=H;var B=(T,t,H)=>Dn(T,typeof t!="symbol"?t+"":t,H);const H=(w,e)=>Math.sqrt(Math.pow(w.x-e.x,2)+Math.pow(w.y-e.y,2)),ht=(w,e)=>{let i=!1;for(let n=0,r=e.length-1;n<e.length;r=n++){const c=e[n].x,l=e[n].y,g=e[r].x,m=e[r].y;l>w.y!=m>w.y&&w.x<(g-c)*(w.y-l)/(m-l)+c&&(i=!i)}return i},et=(w,e,i)=>{const n=i*(Math.PI/180),r=Math.cos(n),c=Math.sin(n),l=w.x-e.x,g=w.y-e.y;return{x:e.x+(l*r-g*c),y:e.y+(l*c+g*r)}};class dt{constructor(e){B(this,"canvas");B(this,"ctx");B(this,"img");B(this,"annotations",[]);B(this,"currentTool",null);B(this,"interactionMode","none");B(this,"activeAnnotation",null);B(this,"hoverAnnotation",null);B(this,"isDrawing",!1);B(this,"isDragging",!1);B(this,"isPanning",!1);B(this,"panStartPoint",null);B(this,"dragStartPoint",null);B(this,"dragStartAnnotation",null);B(this,"lastMouseMovePoint",null);B(this,"isHoveringStartPoint",!1);B(this,"currentLabelColor","#FF4081");B(this,"visibleLabels",new Set);B(this,"selectedHandleIndex",-1);B(this,"hoverHandleIndex",-1);B(this,"scale",1);B(this,"offset",{x:0,y:0});B(this,"listeners",{});B(this,"imageUrl","");this.canvas=e;const i=e.getContext("2d");if(!i)throw new Error("Could not get 2d context");this.ctx=i,this.img=new Image,this.img.crossOrigin="Anonymous",this.img.onload=()=>{this.fitImageToCanvas(),this.render()},this.bindEvents()}on(e,i){this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(i)}emit(e,i){this.listeners[e]&&this.listeners[e].forEach(n=>n(i))}loadImage(e){this.imageUrl=e,this.img.src=e,this.activeAnnotation=null,this.isDrawing=!1}setAnnotations(e){this.annotations=JSON.parse(JSON.stringify(e)),this.render()}getAnnotations(){return this.annotations}setTool(e){e==="pan"?(this.interactionMode="pan",this.currentTool=null,this.isPanning=!1,this.canvas.style.cursor="grab"):e==="select"?(this.interactionMode="select",this.currentTool=null,this.canvas.style.cursor="default"):e?(this.interactionMode="draw",this.currentTool=e,this.canvas.style.cursor="crosshair"):(this.interactionMode="none",this.currentTool=null,this.canvas.style.cursor="default"),this.activeAnnotation=null,this.isDrawing=!1,this.render()}setLabelStyle(e){this.currentLabelColor=e}setVisibleLabels(e){this.visibleLabels=new Set(e),this.render()}zoom(e){const n=e>0?this.scale*1.1:this.scale/1.1;if(n<.1||n>10)return;const r=this.canvas.width/2,c=this.canvas.height/2,l=this.toImageCoords(r,c);this.scale=n,this.offset.x=r-l.x*this.scale,this.offset.y=c-l.y*this.scale,this.clampViewportOffset(),this.render()}resize(){this.fitImageToCanvas(),this.render()}toImageCoords(e,i){return{x:(e-this.offset.x)/this.scale,y:(i-this.offset.y)/this.scale}}toScreenCoords(e,i){return{x:e*this.scale+this.offset.x,y:i*this.scale+this.offset.y}}fitImageToCanvas(){const e=this.canvas.parentElement;if(e){if(this.canvas.width=e.clientWidth,this.canvas.height=e.clientHeight,this.img.width===0)return;const i=this.canvas.width/this.img.width,n=this.canvas.height/this.img.height;this.scale=Math.min(i,n),this.offset.x=(this.canvas.width-this.img.width*this.scale)/2,this.offset.y=(this.canvas.height-this.img.height*this.scale)/2,this.clampViewportOffset()}}clampViewportOffset(){if(this.img.width===0||this.img.height===0)return;const e=this.img.width*this.scale,i=this.img.height*this.scale;if(e<=this.canvas.width)this.offset.x=(this.canvas.width-e)/2;else{const n=this.canvas.width-e,r=0;this.offset.x=Math.min(r,Math.max(n,this.offset.x))}if(i<=this.canvas.height)this.offset.y=(this.canvas.height-i)/2;else{const n=this.canvas.height-i,r=0;this.offset.y=Math.min(r,Math.max(n,this.offset.y))}}bindEvents(){this.canvas.addEventListener("mousedown",this.handleMouseDown.bind(this)),this.canvas.addEventListener("mousemove",this.handleMouseMove.bind(this)),this.canvas.addEventListener("mouseup",this.handleMouseUp.bind(this)),this.canvas.addEventListener("mouseleave",this.handleMouseUp.bind(this)),window.addEventListener("keydown",this.handleKeyDown.bind(this))}handleKeyDown(e){this.interactionMode==="select"&&(e.key==="Delete"||e.key==="Backspace")&&this.activeAnnotation&&this.deleteAnnotation(this.activeAnnotation.id)}deleteAnnotation(e){const i=this.annotations.findIndex(n=>n.id===e);if(i>-1){const n=this.annotations[i];this.annotations.splice(i,1),this.activeAnnotation=null,this.emit("annotationChange",{action:"delete",changedItem:n,imageUrl:this.imageUrl}),this.render()}}handleMouseDown(e){const i=this.canvas.getBoundingClientRect(),n=e.clientX-i.left,r=e.clientY-i.top,c=this.toImageCoords(n,r);if(this.canvas.style.cursor==="grab"||this.canvas.style.cursor==="grabbing"){this.isPanning=!0,this.panStartPoint={x:n,y:r},this.canvas.style.cursor="grabbing";return}if(this.interactionMode==="select"&&this.activeAnnotation){const m=this.getHitHandle(n,r,this.activeAnnotation);if(m!==-100){this.isDragging=!0,this.dragStartPoint=c,this.selectedHandleIndex=m,this.dragStartAnnotation=JSON.parse(JSON.stringify(this.activeAnnotation));return}}const l=this.interactionMode==="select"?this.getHitCategory(n,r):null;if(l){this.activeAnnotation=l,this.isDragging=!1,this.selectedHandleIndex=-1,this.emit("annotationChange",{action:"select",changedItem:l,imageUrl:this.imageUrl}),this.render();return}const g=this.getHitAnnotation(c);if(this.interactionMode==="select"){if(g){if(!(this.visibleLabels.size>0&&!this.visibleLabels.has(g.label))){this.activeAnnotation=g,this.isDragging=!0,this.dragStartPoint=c,this.selectedHandleIndex=-1,this.dragStartAnnotation=JSON.parse(JSON.stringify(g)),this.emit("annotationChange",{action:"select",changedItem:g,imageUrl:this.imageUrl}),this.render();return}}else this.activeAnnotation=null,this.emit("annotationChange",{action:"select",changedItem:void 0,imageUrl:this.imageUrl}),this.render();return}if(this.interactionMode==="draw"){if(this.isDrawing&&this.currentTool==="polygon"&&this.activeAnnotation){const m=this.activeAnnotation.coordinates;if(m.points.length>2&&H(c,m.points[0])<20/this.scale){this.finishDrawing();return}this.startDrawing(c);return}if(this.currentTool){if(this.currentTool==="polygon"&&!this.isDrawing){this.startDrawing(c);return}this.startDrawing(c)}return}this.activeAnnotation=null,this.render()}handleMouseMove(e){const i=this.canvas.getBoundingClientRect(),n=e.clientX-i.left,r=e.clientY-i.top,c=this.toImageCoords(n,r);if(this.isPanning&&this.panStartPoint){const l=n-this.panStartPoint.x,g=r-this.panStartPoint.y;this.offset.x+=l,this.offset.y+=g,this.clampViewportOffset(),this.panStartPoint={x:n,y:r},this.render();return}if(this.lastMouseMovePoint=c,this.isDrawing){if(this.currentTool==="polygon"&&this.activeAnnotation){const l=this.activeAnnotation.coordinates;if(l.points.length>2){const g=l.points[0],m=H(c,g);this.isHoveringStartPoint=m<20/this.scale}else this.isHoveringStartPoint=!1}this.updateDrawing(c)}else this.isDragging&&this.activeAnnotation&&this.dragStartPoint?this.updateDragging(c):this.checkHover(n,r,c);this.render()}handleMouseUp(e){if(this.isPanning){this.isPanning=!1,this.panStartPoint=null,this.canvas.style.cursor="grab";return}if(this.isDrawing){if(this.currentTool==="polygon"){this.render();return}this.finishDrawing()}else this.isDragging&&this.activeAnnotation&&this.emit("annotationChange",{action:"update",changedItem:this.activeAnnotation,imageUrl:this.imageUrl});this.currentTool!=="polygon"&&(this.isDrawing=!1),this.isDragging=!1,this.dragStartPoint=null,this.selectedHandleIndex=-1,this.render()}hexToRgba(e,i){if(!e.startsWith("#"))return e;const n=parseInt(e.slice(1,3),16),r=parseInt(e.slice(3,5),16),c=parseInt(e.slice(5,7),16);return`rgba(${n}, ${r}, ${c}, ${i})`}startDrawing(e){if(!this.currentTool)return;const i=Date.now().toString();if(this.hexToRgba(this.currentLabelColor,.2),this.currentLabelColor,this.currentTool==="rectangle")this.isDrawing=!0,this.dragStartPoint=e,this.activeAnnotation={id:i,type:"rectangle",label:"",coordinates:{x1:e.x,y1:e.y,x2:e.x,y2:e.y},style:{strokeColor:this.currentLabelColor}};else if(this.currentTool==="point"){const n={id:i,type:"point",label:"",coordinates:{points:[e]},style:{strokeColor:this.currentLabelColor}};this.annotations.push(n),this.emit("annotationChange",{action:"add",changedItem:n,imageUrl:this.imageUrl}),this.activeAnnotation=n}else if(this.currentTool==="polygon")this.activeAnnotation&&this.activeAnnotation.type==="polygon"&&this.isDrawing?this.activeAnnotation.coordinates.points.push(e):(this.isDrawing=!0,this.activeAnnotation={id:i,type:"polygon",label:"",coordinates:{points:[e]},style:{strokeColor:this.currentLabelColor}});else if(this.currentTool==="category"){const n={id:i,type:"category",label:"",coordinates:{x:e.x,y:e.y},style:{strokeColor:this.currentLabelColor}};this.annotations.push(n),this.emit("annotationChange",{action:"add",changedItem:n,imageUrl:this.imageUrl}),this.activeAnnotation=n}else this.currentTool==="rotatedRect"&&(this.isDrawing=!0,this.dragStartPoint=e,this.activeAnnotation={id:i,type:"rotatedRect",label:"",coordinates:{x:e.x,y:e.y,width:0,height:0,angle:0},style:{strokeColor:this.currentLabelColor}})}updateDrawing(e){if(this.activeAnnotation)if(this.activeAnnotation.type==="rectangle"&&this.dragStartPoint){const i=this.activeAnnotation.coordinates;i.x2=e.x,i.y2=e.y}else if(this.activeAnnotation.type==="rotatedRect"&&this.dragStartPoint){const i=this.activeAnnotation.coordinates,n=Math.abs(e.x-this.dragStartPoint.x),r=Math.abs(e.y-this.dragStartPoint.y);i.width=n*2,i.height=r*2}else this.activeAnnotation.type}finishDrawing(){if(this.activeAnnotation){if(this.activeAnnotation.type==="rectangle"){const e=this.activeAnnotation.coordinates;if(Math.abs(e.x1-e.x2)<2||Math.abs(e.y1-e.y2)<2){this.activeAnnotation=null,this.isDrawing=!1;return}const i=Math.min(e.x1,e.x2),n=Math.max(e.x1,e.x2),r=Math.min(e.y1,e.y2),c=Math.max(e.y1,e.y2);e.x1=i,e.x2=n,e.y1=r,e.y2=c,this.annotations.push(this.activeAnnotation),this.emit("annotationChange",{action:"add",changedItem:this.activeAnnotation,imageUrl:this.imageUrl})}else if(this.activeAnnotation.type==="polygon"){if(this.activeAnnotation.coordinates.points.length<3){this.activeAnnotation=null,this.isDrawing=!1;return}this.annotations.push(this.activeAnnotation),this.emit("annotationChange",{action:"add",changedItem:this.activeAnnotation,imageUrl:this.imageUrl})}else if(this.activeAnnotation.type==="rotatedRect"){const e=this.activeAnnotation.coordinates;if(e.width<2||e.height<2){this.activeAnnotation=null,this.isDrawing=!1;return}this.annotations.push(this.activeAnnotation),this.emit("annotationChange",{action:"add",changedItem:this.activeAnnotation,imageUrl:this.imageUrl})}this.activeAnnotation.type}this.isDrawing=!1}updateDragging(e){if(!this.activeAnnotation||!this.dragStartPoint||!this.dragStartAnnotation)return;const i=e.x-this.dragStartPoint.x,n=e.y-this.dragStartPoint.y;this.selectedHandleIndex===-1?this.moveAnnotation(this.activeAnnotation,this.dragStartAnnotation,i,n):this.resizeAnnotation(this.activeAnnotation,this.dragStartAnnotation,this.selectedHandleIndex,e)}moveAnnotation(e,i,n,r){if(e.type==="rectangle"){const c=i.coordinates,l=e.coordinates;l.x1=c.x1+n,l.x2=c.x2+n,l.y1=c.y1+r,l.y2=c.y2+r}else if(e.type==="point"){const c=i.coordinates,l=e.coordinates;l.points=c.points.map(g=>({x:g.x+n,y:g.y+r}))}else if(e.type==="rotatedRect"){const c=i.coordinates,l=e.coordinates;l.x=c.x+n,l.y=c.y+r}else if(e.type==="polygon"){const c=i.coordinates,l=e.coordinates;l.points=c.points.map(g=>({x:g.x+n,y:g.y+r}))}else if(e.type==="category"){const c=i.coordinates,l=e.coordinates;c&&l&&(l.x=c.x+n,l.y=c.y+r)}}resizeAnnotation(e,i,n,r){if(e.type==="rectangle"){const c=e.coordinates;n===0&&(c.x1=r.x,c.y1=r.y),n===1&&(c.x2=r.x,c.y1=r.y),n===2&&(c.x2=r.x,c.y2=r.y),n===3&&(c.x1=r.x,c.y2=r.y)}else if(e.type==="polygon"){const c=e.coordinates;n>=0&&n<c.points.length&&(c.points[n]=r)}else if(e.type==="point"){const c=e.coordinates;n>=0&&n<c.points.length&&(c.points[n]=r)}else if(e.type==="rotatedRect"){const c=e.coordinates;if(n===-2){const l=c.x,g=c.y,m=r.x-l,h=r.y-g;let _=Math.atan2(h,m)*180/Math.PI;_+=90,c.angle=_}else{const l=c.angle*Math.PI/180,g=Math.cos(-l),m=Math.sin(-l),h=r.x-c.x,_=r.y-c.y,u=h*g-_*m,S=h*m+_*g;(n===0||n===3)&&(c.width/2,c.width=Math.abs(u)*2),(n===1||n===2)&&(c.width=Math.abs(u)*2),(n===0||n===1)&&(c.height=Math.abs(S)*2),(n===2||n===3)&&(c.height=Math.abs(S)*2)}}}getHitAnnotation(e){for(let i=this.annotations.length-1;i>=0;i--){const n=this.annotations[i];if(this.isPointInAnnotation(e,n))return n}return null}isPointInAnnotation(e,i){if(i.type==="rectangle"){const n=i.coordinates;return e.x>=n.x1&&e.x<=n.x2&&e.y>=n.y1&&e.y<=n.y2}else if(i.type==="polygon"){const n=i.coordinates;return ht(e,n.points)}else if(i.type==="rotatedRect"){const n=i.coordinates,r=et(e,{x:n.x,y:n.y},-n.angle),c=n.width/2,l=n.height/2;return r.x>=n.x-c&&r.x<=n.x+c&&r.y>=n.y-l&&r.y<=n.y+l}else if(i.type==="point")return i.coordinates.points.some(r=>H(e,r)<10/this.scale);return!1}getHitHandle(e,i,n){const r=this.getAnnotationHandles(n),c=6;for(let l=0;l<r.length;l++){const g=r[l],m=this.toScreenCoords(g.x,g.y);if(Math.abs(e-m.x)<c&&Math.abs(i-m.y)<c)return n.type==="rotatedRect"&&l===4?-2:l}return-100}getAnnotationHandles(e){if(e.type==="rectangle"){const i=e.coordinates;return[{x:i.x1,y:i.y1},{x:i.x2,y:i.y1},{x:i.x2,y:i.y2},{x:i.x1,y:i.y2}]}else{if(e.type==="polygon")return e.coordinates.points;if(e.type==="point")return e.coordinates.points;if(e.type==="rotatedRect"){const i=e.coordinates,n={x:i.x,y:i.y},r=i.width/2,c=i.height/2,l={x:i.x-r,y:i.y-c},g={x:i.x+r,y:i.y-c},m={x:i.x+r,y:i.y+c},h={x:i.x-r,y:i.y+c},_={x:i.x,y:i.y-c-20/this.scale};return[l,g,m,h,_].map(u=>et(u,n,i.angle))}}return[]}checkHover(e,i,n){const r=this.getHitCategory(e,i);if(r){this.canvas.style.cursor="pointer",this.hoverAnnotation=r;return}if(this.activeAnnotation&&this.getHitHandle(e,i,this.activeAnnotation)!==-100){this.canvas.style.cursor="pointer";return}const c=this.getHitAnnotation(n);c?(this.canvas.style.cursor="move",this.hoverAnnotation=c):(this.canvas.style.cursor="default",this.hoverAnnotation=null)}render(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.img.complete&&this.img.width>0&&this.ctx.drawImage(this.img,this.offset.x,this.offset.y,this.img.width*this.scale,this.img.height*this.scale),this.annotations.forEach(e=>{e!==this.activeAnnotation&&this.drawItem(e,!1)}),this.activeAnnotation&&this.drawItem(this.activeAnnotation,!0),this.renderCategories()}renderCategories(){const e=this.annotations.filter(n=>n.type==="category");if(e.length===0)return;this.ctx.save(),this.ctx.font="14px sans-serif",this.ctx.textBaseline="middle",this.ctx.textAlign="center";const i=12;e.forEach(n=>{var b;const r=n.label||"未命名分类",c=this.ctx.measureText(r).width+i*2,l=28,g=this.activeAnnotation===n,m=this.hoverAnnotation===n;let h={x:20,y:20};n.coordinates&&typeof n.coordinates.x=="number"&&typeof n.coordinates.y=="number"&&(h=this.toScreenCoords(n.coordinates.x,n.coordinates.y));const _=h.x-c/2,u=h.y-l/2,S=((b=n.style)==null?void 0:b.strokeColor)||"#2196F3";this.ctx.fillStyle=g?S:this.hexToRgba(S,.85),m&&!g&&(this.ctx.fillStyle=S),g?(this.ctx.strokeStyle="#ffffff",this.ctx.lineWidth=2):(this.ctx.strokeStyle="transparent",this.ctx.lineWidth=0),this.ctx.beginPath(),this.ctx.roundRect(_,u,c,l,6),this.ctx.fill(),g&&(this.ctx.stroke(),this.ctx.save(),this.ctx.strokeStyle=S,this.ctx.lineWidth=2,this.ctx.strokeRect(_-3,u-3,c+6,l+6),this.ctx.restore()),this.ctx.fillStyle="#ffffff",this.ctx.fillText(r,h.x,h.y)}),this.ctx.restore()}getHitCategory(e,i){const n=this.annotations.filter(g=>g.type==="category");if(n.length===0)return null;this.ctx.save(),this.ctx.font="14px sans-serif";const r=12,c=28;let l=null;for(let g=n.length-1;g>=0;g--){const m=n[g],h=m.label||"未命名分类",_=this.ctx.measureText(h).width+r*2;let u={x:20,y:20};m.coordinates&&typeof m.coordinates.x=="number"&&typeof m.coordinates.y=="number"&&(u=this.toScreenCoords(m.coordinates.x,m.coordinates.y));const S=u.x-_/2,b=u.y-c/2;if(e>=S&&e<=S+_&&i>=b&&i<=b+c){l=m;break}}return this.ctx.restore(),l}drawItem(e,i){var c;if(this.visibleLabels.size>0&&!this.visibleLabels.has(e.label)&&!i)return;this.ctx.save();const n=((c=e.style)==null?void 0:c.strokeColor)||"#FF4081",r=i?"#00E5FF":n;if(this.ctx.strokeStyle=r,this.ctx.lineWidth=2,e.type==="rectangle"){const l=e.coordinates,g=this.toScreenCoords(l.x1,l.y1),m=this.toScreenCoords(l.x2,l.y2),h=Math.min(g.x,m.x),_=Math.min(g.y,m.y),u=Math.abs(g.x-m.x),S=Math.abs(g.y-m.y);this.ctx.strokeRect(h,_,u,S),i&&this.drawHandles(this.getAnnotationHandles(e))}else if(e.type==="polygon"){const l=e.coordinates;if(l.points.length===0){this.ctx.restore();return}this.ctx.beginPath();const g=this.toScreenCoords(l.points[0].x,l.points[0].y);this.ctx.moveTo(g.x,g.y);for(let m=1;m<l.points.length;m++){const h=this.toScreenCoords(l.points[m].x,l.points[m].y);this.ctx.lineTo(h.x,h.y)}if(!this.isDrawing||e!==this.activeAnnotation)this.ctx.closePath();else if(this.lastMouseMovePoint){let m=this.lastMouseMovePoint;if(this.isHoveringStartPoint&&l.points.length>0){m=l.points[0];const _=this.toScreenCoords(l.points[0].x,l.points[0].y);this.ctx.save(),this.ctx.beginPath(),this.ctx.arc(_.x,_.y,10,0,Math.PI*2),this.ctx.fillStyle="rgba(255, 215, 0, 0.6)",this.ctx.strokeStyle="#FFFFFF",this.ctx.lineWidth=2,this.ctx.fill(),this.ctx.stroke(),this.ctx.restore()}const h=this.toScreenCoords(m.x,m.y);this.ctx.lineTo(h.x,h.y)}this.ctx.stroke(),i&&this.drawHandles(this.getAnnotationHandles(e))}else if(e.type==="rotatedRect"){const l=e.coordinates;this.ctx.translate(this.toScreenCoords(l.x,l.y).x,this.toScreenCoords(l.x,l.y).y),this.ctx.rotate(l.angle*Math.PI/180);const g=l.width*this.scale,m=l.height*this.scale;this.ctx.strokeRect(-g/2,-m/2,g,m),this.ctx.rotate(-l.angle*Math.PI/180),this.ctx.translate(-this.toScreenCoords(l.x,l.y).x,-this.toScreenCoords(l.x,l.y).y),i&&this.drawHandles(this.getAnnotationHandles(e))}else e.type==="point"&&e.coordinates.points.forEach(g=>{const m=this.toScreenCoords(g.x,g.y);this.ctx.beginPath(),this.ctx.arc(m.x,m.y,5,0,Math.PI*2),this.ctx.fillStyle=i?"#00E5FF":n,this.ctx.fill(),this.ctx.stroke()});this.ctx.restore()}drawHandles(e){this.ctx.fillStyle="#FFFFFF",this.ctx.strokeStyle="#000000",this.ctx.lineWidth=1,e.forEach(i=>{const n=this.toScreenCoords(i.x,i.y);this.ctx.fillRect(n.x-4,n.y-4,8,8),this.ctx.strokeRect(n.x-4,n.y-4,8,8)})}}const gt='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032114659" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21132" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 391.68c-66.56 0-120.32 54.187-120.32 120.32 0 66.56 53.76 120.32 120.32 120.32 66.133 0 120.32-53.76 120.32-120.32A120.747 120.747 0 0 0 512 391.68z" p-id="21133" fill="#515151"></path><path d="M512 113.493c-219.733 0-398.507 178.774-398.507 398.507S292.267 910.507 512 910.507 910.507 731.733 910.507 512 731.733 113.493 512 113.493z m0 720.214c-177.493 0-321.707-144.214-321.707-321.707S334.507 190.293 512 190.293 833.707 334.507 833.707 512 689.493 833.707 512 833.707z" p-id="21134" fill="#515151"></path></svg>',mt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M15.7 4.3c.4.4.4 1 0 1.4L9.4 12l6.3 6.3c.4.4.4 1 0 1.4-.4.4-1 .4-1.4 0l-7-7c-.4-.4-.4-1 0-1.4l7-7c.4-.4 1-.4 1.4 0z"/></svg>',ft='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032015085" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16560" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M911.872 972.629333l-2.645333-1.621333-209.92-208.554667-91.306667 193.194667-147.029333-494.933333 486.4 179.968-177.834667 68.266666 201.472 200.362667a9.898667 9.898667 0 0 1 2.133333 4.608 10.069333 10.069333 0 0 1-1.024 4.778667l-2.389333 3.157333-47.786667 47.530667a9.813333 9.813333 0 0 1-4.522666 2.901333 12.544 12.544 0 0 1-2.56 0z m-657.066667-12.970666L0.256 501.248l97.109333-175.445333 64.256-115.456L254.805333 42.581333h510.208l259.328 466.858667h-100.608L714.325333 132.778667H305.322667l-204.8 368.384 204.8 368.725333H418.133333v90.026667z" fill="#515151" p-id="16561"></path></svg>',pt='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032973956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6763" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M613.6 960H97.2c-17.7 0-32-14.3-32-32V98.5c0-17.7 14.3-32 32-32h829.5c17.7 0 32 14.3 32 32v518.2c0 17.7-14.3 32-32 32s-32-14.3-32-32V130.5H129.2V896h484.4c17.7 0 32 14.3 32 32s-14.3 32-32 32z" fill="#515151" p-id="6764"></path><path d="M711.3 694.9l120.3 46.9-100.7 80.7z" fill="#515151" p-id="6765"></path><path d="M707.6 882.1L671.3 645l223.6 87.1-187.3 150z m43.7-137.3l2.8 18 14.2-11.4-17-6.6z" fill="#515151" p-id="6766"></path><path d="M927 957.9c-8.2 0-16.4-3.1-22.6-9.4L723.2 767.2c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l181.2 181.2c12.5 12.5 12.5 32.8 0 45.3-6.3 6.3-14.5 9.5-22.7 9.5z" fill="#515151" p-id="6767"></path></svg>',yt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M19 6h-4V5c0-1.1-.9-2-2-2h-2c-1.1 0-2 .9-2 2v1H5c-.6 0-1 .4-1 1s.4 1 1 1h14c.6 0 1-.4 1-1s-.4-1-1-1zM10 5h4v1h-4V5z"/><path fill="currentColor" d="M6 9v10c0 1.7 1.3 3 3 3h6c1.7 0 3-1.3 3-3V9H6zm4 9c0 .6-.4 1-1 1s-1-.4-1-1v-5c0-.6.4-1 1-1s1 .4 1 1v5zm4 0c0 .6-.4 1-1 1s-1-.4-1-1v-5c0-.6.4-1 1-1s1 .4 1 1v5z"/></svg>',ut='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M19 15v4c0 1.1-.9 2-2 2H7c-1.1 0-2-.9-2-2v-4c0-.6.4-1 1-1s1 .4 1 1v4h10v-4c0-.6.4-1 1-1s1 .4 1 1zm-7.7 1.3c.2.2.4.3.7.3s.5-.1.7-.3l4.6-4.6c.4-.4.4-1 0-1.4-.4-.4-1-.4-1.4 0l-2.9 2.9V3c0-.6-.4-1-1-1s-1 .4-1 1v8.3l-2.9-2.9c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4l4.6 4.6z"/></svg>',vt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M3 17.2v4.3c0 .3.2.5.5.5h4.3c.1 0 .3-.1.4-.2l11.1-11.1-5.1-5.1L3.1 16.8c-.1.1-.1.3-.1.4zm18.8-10.9c.4-.4.4-1 0-1.4l-3.7-3.7c-.4-.4-1-.4-1.4 0l-2.3 2.3 5.1 5.1 2.3-2.3z"/></svg>',wt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M18.7 4.3c.4.4.4 1 0 1.4L12.4 12l6.3 6.3c.4.4.4 1 0 1.4-.4.4-1 .4-1.4 0l-7-7c-.4-.4-.4-1 0-1.4l7-7c.4-.4 1-.4 1.4 0z"/><path fill="currentColor" d="M10.7 4.3c.4.4.4 1 0 1.4L4.4 12l6.3 6.3c.4.4.4 1 0 1.4-.4.4-1 .4-1.4 0l-7-7c-.4-.4-.4-1 0-1.4l7-7c.4-.4 1-.4 1.4 0z"/></svg>',xt='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032412624" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3527" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M870.2976 144.0256l51.2 51.2-122.88 122.88a514.304 514.304 0 0 1 170.7264 193.8688C885.0432 679.04 711.8848 793.6 512 793.6c-56.832 0-111.488-9.2672-162.56-26.3424L197.4016 919.296l-51.2-51.2L870.2976 144.0256z m-127.1552 229.5296l-76.6208 76.6208a166.4 166.4 0 0 1-216.32 216.3712l-38.6048 38.5792c29.5168 6.9632 60.032 10.9312 91.1872 11.5712L512 716.8c150.6816 0 287.488-77.2096 366.464-200.3456l2.816-4.48-2.816-4.48a435.8144 435.8144 0 0 0-135.3216-133.9392zM512 230.4c49.664 0 97.664 7.0656 143.0528 20.2496l-63.8208 63.7696a436.4032 436.4032 0 0 0-70.016-7.1168L512 307.2a434.8928 434.8928 0 0 0-366.464 200.3456l-2.816 4.48 2.816 4.48a435.84 435.84 0 0 0 119.8848 123.776l-55.0912 55.04a514.2528 514.2528 0 0 1-155.648-183.296C138.9312 344.96 312.0896 230.4 512 230.4z m89.5488 284.8l-86.3744 86.2976 1.7408-0.0256a89.6 89.6 0 0 0 84.6336-86.272zM512 345.6a166.656 166.656 0 0 1 42.5728 5.504l-79.0272 79.0272a89.9328 89.9328 0 0 0-45.4144 45.4144l-79.0272 79.0272A166.4 166.4 0 0 1 512 345.6z" p-id="3528" fill="#515151"></path></svg>',bt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M5.3 19.7c-.4-.4-.4-1 0-1.4l6.3-6.3-6.3-6.3c-.4-.4-.4-1 0-1.4.4-.4 1-.4 1.4 0l7 7c.4.4.4 1 0 1.4l-7 7c-.4.4-1 .4-1.4 0z"/><path fill="currentColor" d="M13.3 19.7c-.4-.4-.4-1 0-1.4l6.3-6.3-6.3-6.3c-.4-.4-.4-1 0-1.4.4-.4 1-.4 1.4 0l7 7c.4.4.4 1 0 1.4l-7 7c-.4.4-1 .4-1.4 0z"/></svg>',kt='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775031871732" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12257" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M174.63 78.98c0.03-12.61 16.41-19.91 25.81-11.5l328.72 293.98 318.27 284.63c10.51 9.4 0.4 26.75-14.25 24.46L435.7 608.43c-6.23-0.97-12.72 1.92-16.16 7.2L199.96 952.72c-8.09 12.42-27.76 8.34-27.72-5.76l1.17-426.97 1.22-441.01z" fill="#515151" p-id="12258"></path></svg>',Ct='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032210611" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23146" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M543.487882 0.00128a161.919393 161.919393 0 0 0-114.55957 47.359822L47.553742 428.991671a162.111392 162.111392 0 0 0 0 229.119141l318.270806 318.398806a161.983393 161.983393 0 0 0 229.119141 0l381.630569-381.694569A162.111392 162.111392 0 0 0 1023.99808 480.255479V161.920673A161.919393 161.919393 0 0 0 861.886688 0.00128H543.487882z m0 90.55966l318.462806 0.064a71.295733 71.295733 0 0 1 71.487732 71.295733v318.270806c0 18.943929-7.615971 37.119861-21.055921 50.559811l-381.56657 381.758568a71.423732 71.423732 0 0 1-101.055621 0L111.489502 594.111052a71.487732 71.487732 0 0 1 0-101.119621l381.566569-381.566569c13.37595-13.37595 31.551882-20.863922 50.431811-20.863922z m112.447578 124.159535a153.023426 153.023426 0 1 0 0 306.046852 153.023426 153.023426 0 0 0 0-306.046852z m57.727784 129.151515a62.463766 62.463766 0 1 1-115.455567 47.807821 62.463766 62.463766 0 0 1 115.455567-47.807821z" p-id="23147" fill="#515151"></path></svg>',_t='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M20.5 10.5V11c0 4.7-3.8 8.5-8.5 8.5S3.5 15.7 3.5 11v-4c0-1.4 1.1-2.5 2.5-2.5s2.5 1.1 2.5 2.5v1.5c0 .3.2.5.5.5s.5-.2.5-.5v-4c0-1.4 1.1-2.5 2.5-2.5s2.5 1.1 2.5 2.5v1.5c0 .3.2.5.5.5s.5-.2.5-.5v-1c0-1.4 1.1-2.5 2.5-2.5s2.5 1.1 2.5 2.5v2.5c0 .3.2.5.5.5s.5-.2.5-.5v-1.5c0-1.4 1.1-2.5 2.5-2.5s2.5 1.1 2.5 2.5z"/></svg>',Et='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775033156525" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3463" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M694.4 960H195.2C131.7 960 80 908.4 80 845.1V462c0-63.4 51.7-114.9 115.2-114.9h499.2c63.5 0 115.2 51.6 115.2 114.9v383.1c0 63.3-51.7 114.9-115.2 114.9zM195.2 423.7c-21.2 0-38.4 17.2-38.4 38.3v383.1c0 21.1 17.2 38.3 38.4 38.3h499.2c21.2 0 38.4-17.2 38.4-38.3V462c0-21.1-17.2-38.3-38.4-38.3H195.2z" fill="#515151" p-id="3464"></path><path d="M905.6 450.3c-14.8 0-28.9-8.6-35.2-23C788.6 240.8 592.7 213 483.2 213c-21.2 0-38.4-17.2-38.4-38.3s17.2-38.3 38.4-38.3c218.2 0 385 94.9 457.6 260.3 8.5 19.4-0.4 42-19.8 50.5-5 2.1-10.3 3.1-15.4 3.1z" fill="#515151" p-id="3465"></path><path d="M473.6 285.4c-9.8 0-19.7-3.7-27.2-11.2l-72.5-72.4c-15-15-15-39.2 0-54.2l72.5-72.4c15-15 39.3-15 54.3 0s15 39.2 0 54.2l-45.4 45.3 45.4 45.3c15 15 15 39.2 0 54.2-7.4 7.4-17.3 11.2-27.1 11.2z" fill="#515151" p-id="3466"></path></svg>',Bt='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M8.3 19.7c-.4-.4-.4-1 0-1.4l6.3-6.3-6.3-6.3c-.4-.4-.4-1 0-1.4.4-.4 1-.4 1.4 0l7 7c.4.4.4 1 0 1.4l-7 7c-.4.4-1 .4-1.4 0z"/></svg>',St='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032400373" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 230.4c199.8848 0 373.0176 114.5344 457.344 281.5744C885.0432 679.04 711.8848 793.6 512 793.6c-199.8848 0-373.0176-114.5344-457.344-281.5744C138.9568 344.96 312.1152 230.4 512 230.4z m0 76.8a434.8928 434.8928 0 0 0-366.464 200.3456l-2.816 4.48 2.816 4.48a434.944 434.944 0 0 0 357.248 200.192L512 716.8c150.6816 0 287.488-77.2096 366.464-200.3456l2.816-4.48-2.816-4.48a434.944 434.944 0 0 0-357.248-200.192L512 307.2z m0 38.4a166.4 166.4 0 1 1 0 332.8 166.4 166.4 0 0 1 0-332.8z m0 76.8a89.6 89.6 0 1 0 0 179.2 89.6 89.6 0 0 0 0-179.2z" p-id="3315" fill="#515151"></path></svg>',It='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032548251" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4695" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M849.7664 778.1376c1.9968 1.4848 3.84 3.072 5.632 4.864l72.3968 72.3968a51.2 51.2 0 1 1-72.3968 72.3968l-72.3968-72.3968a51.6096 51.6096 0 0 1-4.864-5.632 448 448 0 1 1 71.68-71.68zM460.8 460.8V358.4a51.2 51.2 0 1 1 102.4 0v102.4h102.4a51.2 51.2 0 0 1 0 102.4h-102.4v102.4a51.2 51.2 0 0 1-102.4 0v-102.4H358.4a51.2 51.2 0 0 1 0-102.4h102.4z m38.4 384a345.6 345.6 0 1 0 0-691.2 345.6 345.6 0 0 0 0 691.2z" fill="#515151" p-id="4696"></path></svg>',At='<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1775032629657" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1933" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M849.7664 778.1376c1.9968 1.4848 3.84 3.072 5.632 4.864l72.3968 72.3968a51.2 51.2 0 1 1-72.3968 72.3968l-72.3968-72.3968a51.6096 51.6096 0 0 1-4.864-5.632 448 448 0 1 1 71.68-71.68zM499.2 844.8a345.6 345.6 0 1 0 0-691.2 345.6 345.6 0 0 0 0 691.2zM358.4 563.2a51.2 51.2 0 0 1 0-102.4h307.2a51.2 51.2 0 0 1 0 102.4H358.4z" fill="#666666" p-id="1934"></path></svg>',Vt=["innerHTML"],Nt=t.defineComponent({__name:"SvgIcon",props:{name:{},size:{}},setup(w){const e=w,i=t.ref(""),n=Object.assign({"../assets/svg/aim.svg":gt,"../assets/svg/back.svg":mt,"../assets/svg/connection.svg":ft,"../assets/svg/crop.svg":pt,"../assets/svg/delete.svg":yt,"../assets/svg/download.svg":ut,"../assets/svg/edit.svg":vt,"../assets/svg/first.svg":wt,"../assets/svg/hide.svg":xt,"../assets/svg/last.svg":bt,"../assets/svg/pointer.svg":kt,"../assets/svg/price-tag.svg":Ct,"../assets/svg/rank.svg":_t,"../assets/svg/refresh-right.svg":Et,"../assets/svg/right.svg":Bt,"../assets/svg/view.svg":St,"../assets/svg/zoom-in.svg":It,"../assets/svg/zoom-out.svg":At});return t.watchEffect(()=>{const r=`../assets/svg/${e.name}.svg`,c=n[r];c?i.value=c:(console.warn(`Icon ${e.name} not found at path ${r}`),i.value="")}),(r,c)=>(t.openBlock(),t.createElementBlock("i",{class:t.normalizeClass(["svg-icon",[w.size?`size-${w.size}`:""]]),innerHTML:i.value},null,10,Vt))}}),Y=(w,e)=>{const i=w.__vccOpts||w;for(const[n,r]of e)i[n]=r;return i},V=Y(Nt,[["__scopeId","data-v-3928607b"]]),Tt={key:0,class:"image-list-sidebar"},Dt={class:"image-list-header"},Mt=["onClick"],zt={class:"image-list-stage"},Lt=["src","alt"],Pt={key:0,class:"thumb-overlay-layer"},$t={key:1,class:"thumb-overlay-svg",viewBox:"0 0 100 100",preserveAspectRatio:"none"},Rt=["points"],Ht={class:"image-list-text"},Ut={class:"center-sidebar"},Ft={key:0,class:"left-sidebar"},Ot=["onClick","title"],Wt={key:0,class:"divider"},Gt={class:"center-area"},Jt={key:0,class:"floating-label-selector"},Yt={key:0,class:"current-label"},jt={class:"label-name"},Xt={key:1,class:"current-label empty"},qt={key:0,class:"selector-dropdown"},Kt={key:0,class:"dropdown-empty"},Zt=["onClick"],Qt={class:"label-name"},te={key:0,class:"batch-nav"},ee=["disabled"],ne=["disabled"],oe=["disabled"],se=["disabled"],ie={key:1,class:"right-sidebar"},ae={class:"label-list"},le={class:"label-row"},ce=["onUpdate:modelValue","onChange"],re=["title"],he=["onClick"],de={class:"action-icon more-actions"},ge=["onClick"],me={class:"modal-content"},fe={class:"modal-body"},pe={class:"form-group"},ye={class:"form-group"},ue={class:"color-input-wrapper"},ve={class:"color-value"},we={class:"modal-actions"},xe=["disabled"],nt=Y(t.defineComponent({__name:"ImageAnnotator",props:{annotationTypes:{default:()=>["rectangle","polygon","point","rotatedRect","category"]},batchImages:{default:()=>[]},labels:{default:()=>[]},defaultActiveType:{},theme:{default:"light"},readOnly:{type:Boolean,default:!1},image:{},predictionCandidates:{},session:{},requestId:{},minZoom:{},maxZoom:{}},emits:["annotationChange","batchChange","labelChange","ready","error","tool:change","viewport:change","annotation:add","annotation:update","annotation:delete","annotation:select","prediction:loaded","prediction:apply","prediction:reject"],setup(w,{expose:e,emit:i}){const n=w,r=i,c=t.ref(null),l=t.ref(null),g=t.ref(null),m=t.ref([]),h=t.ref(null),_=t.ref(null),u=t.ref(0),S=t.ref(""),b=t.ref([]),A=t.ref(""),U=t.ref(!1),x=t.ref({name:"",color:"#FF0000"}),E=t.ref("none"),p=t.ref([]),N=t.ref({}),M=t.computed(()=>_.value==="select"&&!!S.value),P=t.ref(!1),F=t.computed(()=>b.value.find(o=>o.id===A.value)),st=o=>{o.stopPropagation(),P.value=!P.value},it=o=>{W(o),P.value=!1};t.onMounted(()=>{document.addEventListener("click",o=>{o.target.closest(".floating-label-selector")||(P.value=!1)})});const j=o=>{if(!o||N.value[o])return;const s=new Image;s.onload=()=>{const a=s.naturalWidth||1,d=s.naturalHeight||1;N.value={...N.value,[o]:{width:a,height:d}}},s.src=o},X=()=>{n.batchImages.forEach(o=>{j(o.imageUrl)})},K=(o,s)=>{m.value[s]=o},O=(o=u.value)=>{const s=g.value,a=m.value[o];if(!s||!a)return;const d=s.scrollTop,f=d+s.clientHeight,C=a.offsetTop,I=C+a.offsetHeight;if(C<d){s.scrollTo({top:Math.max(C-8,0),behavior:"smooth"});return}I>f&&s.scrollTo({top:I-s.clientHeight+8,behavior:"smooth"})},$=()=>{var a,d,f,C;const o=n.batchImages[u.value],s=(o==null?void 0:o.imageUrl)||((a=n.image)==null?void 0:a.url);return{eventId:`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,timestamp:Date.now(),requestId:n.requestId,taskId:(d=n.session)==null?void 0:d.taskId,imageId:((f=n.image)==null?void 0:f.id)||s,operator:(C=n.session)==null?void 0:C.userId}},y=o=>{var d;const s=o==null?void 0:o.action;if(!s)return;const a={meta:$(),action:s,current:o==null?void 0:o.changedItem,source:(d=o==null?void 0:o.changedItem)!=null&&d.predictionId?"prediction":"manual"};s==="add"&&r("annotation:add",a),s==="update"&&r("annotation:update",a),s==="delete"&&r("annotation:delete",a),s==="select"&&r("annotation:select",a)},v=t.computed(()=>n.annotationTypes),k=o=>({rectangle:"crop",polygon:"connection",point:"aim",rotatedRect:"refresh-right",category:"price-tag"})[o]||o,z=o=>({rectangle:"矩形框",polygon:"多边形",point:"关键点",rotatedRect:"旋转矩形",category:"分类标签"})[o]||o;t.onMounted(()=>{if(X(),c.value){h.value=new dt(c.value),h.value.on("annotationChange",s=>{var a,d;if(s.action==="add"&&s.changedItem){const f=b.value.find(C=>C.id===A.value);f&&(s.changedItem.label=f.name,s.changedItem.labelId=f.id)}s.action==="select"?S.value=((a=s.changedItem)==null?void 0:a.id)||"":s.action==="delete"&&((d=s.changedItem)==null?void 0:d.id)===S.value&&(S.value=""),r("annotationChange",s),y(s)}),L(),D();const o=new ResizeObserver(()=>{var s;(s=h.value)==null||s.resize()});l.value&&o.observe(l.value),n.defaultActiveType&&R(n.defaultActiveType),t.nextTick(()=>O()),r("ready",{meta:$()})}});const D=()=>{if(!h.value)return;const o=b.value.find(a=>a.id===A.value);o&&h.value.setLabelStyle(o.color);const s=b.value.filter(a=>a.visible).map(a=>a.name);h.value.setVisibleLabels(s)},L=()=>{var o;if(h.value)if(S.value="",requestAnimationFrame(()=>{var s;(s=h.value)==null||s.resize()}),n.batchImages.length>0){const s=n.batchImages[u.value];h.value.loadImage(s.imageUrl),s.annotations?h.value.setAnnotations(s.annotations):h.value.setAnnotations([])}else(o=n.image)!=null&&o.url&&h.value.loadImage(n.image.url)},R=o=>{var s,a;if(_.value=o,S.value="",o!=="pan"&&o!=="select"&&b.value.length===0){alert("请先创建标签!");return}o==="pan"||o==="select"?(s=h.value)==null||s.setTool(o):(a=h.value)==null||a.setTool(o),r("tool:change",{meta:$(),tool:o})},Ze=()=>{var o;(o=h.value)!=null&&o.activeAnnotation&&h.value.deleteAnnotation(h.value.activeAnnotation.id)},at=()=>{h.value&&r("viewport:change",{meta:$(),scale:h.value.scale,offset:{...h.value.offset}})},Qe=()=>{var o;(o=h.value)==null||o.zoom(1),at()},tn=()=>{var o;(o=h.value)==null||o.zoom(-1),at()},en=()=>{x.value={name:"",color:"#2196F3"},U.value=!0},Z=()=>{U.value=!1},nn=()=>{if(!x.value.name.trim()){alert("请输入标签名称");return}const s={id:Date.now().toString(),name:x.value.name,color:x.value.color,visible:!0};b.value.push(s),r("labelChange",b.value),D(),b.value.length===1&&W(s),Z()},W=o=>{var s;A.value=o.id,(s=h.value)==null||s.setLabelStyle(o.color)},on=(o,s)=>{if(!o.startsWith("#"))return o;let a=0,d=0,f=0;return o.length===4?(a=parseInt(o[1]+o[1],16),d=parseInt(o[2]+o[2],16),f=parseInt(o[3]+o[3],16)):o.length===7&&(a=parseInt(o.slice(1,3),16),d=parseInt(o.slice(3,5),16),f=parseInt(o.slice(5,7),16)),`rgba(${a}, ${d}, ${f}, ${s})`},sn=o=>{var s;if(o.id===A.value&&((s=h.value)==null||s.setLabelStyle(o.color)),h.value){const a=h.value.getAnnotations();let d=!1;a.forEach(f=>{f.label===o.name&&(f.style||(f.style={}),f.style.strokeColor=o.color,f.style.fillColor=on(o.color,.2),d=!0)}),d&&h.value.render()}r("labelChange",b.value),D()},an=o=>{o.visible=!o.visible,D()},ln=o=>{const s=b.value.findIndex(a=>a.id===o);s>-1&&(b.value.splice(s,1),r("labelChange",b.value),A.value===o&&(A.value=b.value.length>0?b.value[0].id:"",A.value&&W(b.value[0])),D())};t.watch(()=>n.labels,o=>{const s=JSON.parse(JSON.stringify(o||[]));if(b.value=s,b.value.length>0)if(!A.value||!b.value.find(a=>a.id===A.value))W(b.value[0]);else{const a=b.value.find(d=>d.id===A.value);a&&W(a)}else A.value="";D()},{immediate:!0,deep:!0});const cn=()=>{u.value>0&&(Q(),u.value--,L(),tt())},rn=()=>{u.value<n.batchImages.length-1&&(Q(),u.value++,L(),tt())},hn=()=>{u.value>0&&q(0)},dn=()=>{u.value<n.batchImages.length-1&&q(n.batchImages.length-1)},Q=()=>{if(h.value){const o=h.value.getAnnotations();n.batchImages[u.value].annotations=o}},tt=()=>{const o=n.batchImages[u.value];r("batchChange",{currentIndex:u.value,total:n.batchImages.length,currentImageUrl:o.imageUrl,currentAnnotations:o.annotations||[]})},lt=(o=[])=>{var f;if(!h.value)return;if(p.value=JSON.parse(JSON.stringify(o)),p.value.length===0){E.value="none";return}E.value="loaded";const a=(h.value.getAnnotations()||[]).filter(C=>!C.predictionId),d=p.value.map(C=>{const I=JSON.parse(JSON.stringify(C.annotation));return I.id=I.id||`pred-${C.id}`,I.predictionId=C.id,I.modelRunId=C.modelRunId||I.modelRunId,I.confidence=C.confidence??I.confidence,I.reviewStatus=I.reviewStatus||"draft",I});h.value.setAnnotations([...a,...d]),r("prediction:loaded",{meta:$(),modelRunId:(f=p.value[0])==null?void 0:f.modelRunId,candidates:p.value})},gn=(o,s)=>{var f;if(!h.value)return[];E.value="applying";const d=(h.value.getAnnotations()||[]).filter(C=>C.predictionId&&o.includes(C.predictionId));return d.forEach(C=>{C.reviewStatus="accepted"}),E.value="applied",r("prediction:apply",{meta:$(),modelRunId:(f=d[0])==null?void 0:f.modelRunId,candidateIds:o,threshold:s,acceptedAnnotations:d}),h.value.render(),d},mn=(o,s)=>{var f;if(!h.value)return;const a=h.value.getAnnotations()||[],d=a.filter(C=>!(C.predictionId&&o.includes(C.predictionId)));h.value.setAnnotations(d),r("prediction:reject",{meta:$(),modelRunId:(f=a.find(C=>C.predictionId&&o.includes(C.predictionId)))==null?void 0:f.modelRunId,candidateIds:o,reason:s})},fn=(o,s=[])=>{h.value&&(h.value.loadImage(o.url),h.value.setAnnotations(s))},pn=o=>{var s;(s=h.value)==null||s.setAnnotations(o)},ct=()=>{var o;return((o=h.value)==null?void 0:o.getAnnotations())||[]},yn=(o="json")=>{var a,d;const s=ct();return{format:o,image:((a=n.batchImages[u.value])==null?void 0:a.imageUrl)||((d=n.image)==null?void 0:d.url)||"",annotations:s}},q=o=>{o>=0&&o<n.batchImages.length&&(Q(),u.value=o,L(),tt())},un=o=>{var s;return o===u.value&&h.value?h.value.getAnnotations()||[]:((s=n.batchImages[o])==null?void 0:s.annotations)||[]},vn=o=>o.type==="rectangle",wn=o=>o.type==="polygon",xn=o=>o.type==="point",bn=o=>o.type==="rotatedRect",kn=o=>o.type==="category",G=o=>{var a,d;const s=(a=b.value.find(f=>f.name===o.label))==null?void 0:a.color;return((d=o.style)==null?void 0:d.strokeColor)||s||"#409eff"},rt=o=>{const s=o.coordinates;return(s==null?void 0:s.points)||[]},J=o=>{const s=n.batchImages[o];if(s!=null&&s.width&&(s!=null&&s.height))return{width:s.width,height:s.height};const a=s!=null&&s.imageUrl?N.value[s.imageUrl]:void 0;return a||(s!=null&&s.imageUrl&&j(s.imageUrl),{width:1,height:1})},Cn=o=>{const s=n.batchImages[o];return s!=null&&s.width&&(s!=null&&s.height)?!0:s!=null&&s.imageUrl?!!N.value[s.imageUrl]:!1},_n=(o,s)=>{const a=s.coordinates,d=J(o),f=G(s),C=Math.min(a.x1,a.x2),I=Math.min(a.y1,a.y2),Vn=Math.max(a.x1,a.x2),Nn=Math.max(a.y1,a.y2);return{left:`${C/d.width*100}%`,top:`${I/d.height*100}%`,width:`${(Vn-C)/d.width*100}%`,height:`${(Nn-I)/d.height*100}%`,borderColor:f,backgroundColor:`${f}22`}},En=(o,s)=>{const a=J(o);return rt(s).map(d=>`${d.x/a.width*100},${d.y/a.height*100}`).join(" ")},Bn=o=>{const s=G(o);return{fill:`${s}33`,stroke:s,strokeWidth:"1.4"}},Sn=(o,s,a)=>{const d=J(o),f=G(a);return{left:`${s.x/d.width*100}%`,top:`${s.y/d.height*100}%`,backgroundColor:f}},In=(o,s)=>{const a=s.coordinates,d=J(o),f=G(s),C=Math.abs(a.width),I=Math.abs(a.height);return{left:`${(a.x-C/2)/d.width*100}%`,top:`${(a.y-I/2)/d.height*100}%`,width:`${C/d.width*100}%`,height:`${I/d.height*100}%`,transform:`rotate(${a.angle||0}deg)`,borderColor:f,backgroundColor:`${f}22`}},An=(o,s)=>{const a=s.coordinates,d=J(o),f=G(s);return{left:`${a.x/d.width*100}%`,top:`${a.y/d.height*100}%`,backgroundColor:`${f}d9`}};return e({jumpTo:q,setImage:fn,setAnnotations:pn,getAnnotations:ct,selectTool:R,loadPredictionCandidates:lt,applyPredictions:gn,rejectPredictions:mn,exportAnnotations:yn,getAllAnnotations:()=>{var o,s;return n.batchImages.length>0?n.batchImages:[{imageUrl:((o=n.image)==null?void 0:o.url)||"",annotations:((s=h.value)==null?void 0:s.getAnnotations())||[]}]},getCurrentAnnotation:()=>{var o,s,a;return{imageUrl:((o=n.batchImages[u.value])==null?void 0:o.imageUrl)||((s=n.image)==null?void 0:s.url)||"",annotations:((a=h.value)==null?void 0:a.getAnnotations())||[]}}}),t.watch(()=>{var o;return(o=n.image)==null?void 0:o.url},()=>{var o;n.batchImages.length===0&&((o=n.image)!=null&&o.url)&&L()}),t.watch(()=>n.predictionCandidates,o=>{o&<(o)},{immediate:!0,deep:!0}),t.watch(()=>n.batchImages.map(o=>`${o.imageUrl}:${o.width||""}x${o.height||""}`),()=>{X(),m.value=m.value.slice(0,n.batchImages.length),t.nextTick(()=>O())},{immediate:!0}),t.watch(()=>u.value,()=>{t.nextTick(()=>O())}),(o,s)=>(t.openBlock(),t.createElementBlock("div",{class:t.normalizeClass(["annotation-container",w.theme])},[w.batchImages&&w.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",Tt,[t.createElementVNode("div",Dt,"共 "+t.toDisplayString(w.batchImages.length)+" 张",1),t.createElementVNode("div",{ref_key:"imageListScrollRef",ref:g,class:"image-list-scroll"},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(w.batchImages,(a,d)=>(t.openBlock(),t.createElementBlock("button",{key:`${a.imageUrl}-${d}`,ref_for:!0,ref:f=>K(f,d),class:t.normalizeClass(["image-list-item",{active:d===u.value}]),onClick:f=>q(d)},[t.createElementVNode("div",zt,[t.createElementVNode("img",{src:a.imageUrl,alt:`第${d+1}张`,class:"image-list-thumb"},null,8,Lt),Cn(d)?(t.openBlock(),t.createElementBlock("div",Pt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(un(d),f=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:f.id},[vn(f)?(t.openBlock(),t.createElementBlock("div",{key:0,class:"thumb-overlay-rect",style:t.normalizeStyle(_n(d,f))},null,4)):wn(f)?(t.openBlock(),t.createElementBlock("svg",$t,[t.createElementVNode("polygon",{points:En(d,f),style:t.normalizeStyle(Bn(f))},null,12,Rt)])):xn(f)?(t.openBlock(!0),t.createElementBlock(t.Fragment,{key:2},t.renderList(rt(f),(C,I)=>(t.openBlock(),t.createElementBlock("div",{key:`${f.id}-${I}`,class:"thumb-overlay-point",style:t.normalizeStyle(Sn(d,C,f))},null,4))),128)):bn(f)?(t.openBlock(),t.createElementBlock("div",{key:3,class:"thumb-overlay-rotated",style:t.normalizeStyle(In(d,f))},null,4)):kn(f)?(t.openBlock(),t.createElementBlock("div",{key:4,class:"thumb-overlay-category",style:t.normalizeStyle(An(d,f))},t.toDisplayString(f.label),5)):t.createCommentVNode("",!0)],64))),128))])):t.createCommentVNode("",!0)]),t.createElementVNode("span",Ht,"第 "+t.toDisplayString(d+1)+" 张",1)],10,Mt))),128))],512)])):t.createCommentVNode("",!0),t.createElementVNode("div",Ut,[w.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Ft,[t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:_.value==="select"}]),onClick:s[0]||(s[0]=a=>R("select")),title:"选择"},[t.createVNode(V,{name:"pointer"})],2),s[4]||(s[4]=t.createElementVNode("div",{class:"divider"},null,-1)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(v.value,a=>(t.openBlock(),t.createElementBlock("div",{key:a,class:t.normalizeClass(["tool-btn",{active:_.value===a}]),onClick:d=>R(a),title:z(a)},[t.createVNode(V,{name:k(a)},null,8,["name"])],10,Ot))),128)),s[5]||(s[5]=t.createElementVNode("div",{class:"divider"},null,-1)),t.createElementVNode("div",{class:"tool-btn",onClick:Qe,title:"放大"},[t.createVNode(V,{name:"zoom-in"})]),t.createElementVNode("div",{class:"tool-btn",onClick:tn,title:"缩小"},[t.createVNode(V,{name:"zoom-out"})]),M.value?(t.openBlock(),t.createElementBlock("div",Wt)):t.createCommentVNode("",!0),M.value?(t.openBlock(),t.createElementBlock("div",{key:1,class:"tool-btn",onClick:Ze,title:"删除选中"},[t.createVNode(V,{name:"delete"})])):t.createCommentVNode("",!0)]))]),t.createElementVNode("div",Gt,[t.createElementVNode("div",{class:"canvas-wrapper",ref_key:"canvasWrapper",ref:l,onWheel:s[1]||(s[1]=t.withModifiers(()=>{},["prevent"]))},[t.createElementVNode("canvas",{ref_key:"canvasRef",ref:c},null,512),w.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Jt,[t.createElementVNode("div",{class:"selector-trigger",onClick:st},[F.value?(t.openBlock(),t.createElementBlock("div",Yt,[t.createElementVNode("span",{class:"color-dot",style:t.normalizeStyle({backgroundColor:F.value.color})},null,4),t.createElementVNode("span",jt,t.toDisplayString(F.value.name),1)])):(t.openBlock(),t.createElementBlock("div",Xt,[...s[6]||(s[6]=[t.createElementVNode("span",{class:"label-name"},"请选择标签",-1)])])),t.createVNode(V,{name:"right",class:t.normalizeClass(["arrow-icon",{"is-open":P.value}])},null,8,["class"])]),P.value?(t.openBlock(),t.createElementBlock("div",qt,[b.value.length===0?(t.openBlock(),t.createElementBlock("div",Kt,"请在右侧创建标签")):(t.openBlock(!0),t.createElementBlock(t.Fragment,{key:1},t.renderList(b.value,a=>(t.openBlock(),t.createElementBlock("div",{key:a.id,class:t.normalizeClass(["dropdown-item",{active:A.value===a.id}]),onClick:d=>it(a)},[t.createElementVNode("span",{class:"color-dot",style:t.normalizeStyle({backgroundColor:a.color})},null,4),t.createElementVNode("span",Qt,t.toDisplayString(a.name),1),A.value===a.id?(t.openBlock(),t.createBlock(V,{key:0,name:"aim",class:"check-icon"})):t.createCommentVNode("",!0)],10,Zt))),128))])):t.createCommentVNode("",!0)]))],544),w.batchImages&&w.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",te,[t.createElementVNode("button",{class:"icon-btn",onClick:hn,disabled:u.value<=0,title:"第一张"},[t.createVNode(V,{name:"first"})],8,ee),t.createElementVNode("button",{class:"icon-btn",onClick:cn,disabled:u.value<=0,title:"上一张"},[t.createVNode(V,{name:"back"})],8,ne),t.createElementVNode("span",null,t.toDisplayString(u.value+1)+" / "+t.toDisplayString(w.batchImages.length),1),t.createElementVNode("button",{class:"icon-btn",onClick:rn,disabled:u.value>=w.batchImages.length-1,title:"下一张"},[t.createVNode(V,{name:"right"})],8,oe),t.createElementVNode("button",{class:"icon-btn",onClick:dn,disabled:u.value>=w.batchImages.length-1,title:"最后一张"},[t.createVNode(V,{name:"last"})],8,se)])):t.createCommentVNode("",!0)]),w.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",ie,[t.createElementVNode("div",{class:"sidebar-header"},[s[7]||(s[7]=t.createElementVNode("h3",null,"标签",-1)),t.createElementVNode("button",{class:"add-btn",onClick:en},"添加标签")]),t.createElementVNode("div",ae,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(b.value,a=>(t.openBlock(),t.createElementBlock("div",{key:a.id,class:"label-item",style:t.normalizeStyle({backgroundColor:a.color+"1A",color:a.color})},[t.createElementVNode("div",le,[t.createElementVNode("label",{class:"color-wrapper",style:t.normalizeStyle({backgroundColor:a.color})},[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":d=>a.color=d,onChange:d=>sn(a),style:{visibility:"hidden",width:"0",height:"0"}},null,40,ce),[[t.vModelText,a.color]])],4),t.createElementVNode("span",{class:"label-name",title:a.name},t.toDisplayString(a.name),9,re),t.createElementVNode("span",{class:"action-icon eye",onClick:d=>an(a)},[a.visible?(t.openBlock(),t.createBlock(V,{key:0,name:"view"})):(t.openBlock(),t.createBlock(V,{key:1,name:"hide"}))],8,he),t.createElementVNode("div",de,[s[8]||(s[8]=t.createElementVNode("span",{class:"dots"},"•••",-1)),t.createElementVNode("span",{class:"delete-btn",onClick:d=>ln(a.id),title:"删除"},[t.createVNode(V,{name:"delete"})],8,ge)])])],4))),128))])])),U.value?(t.openBlock(),t.createElementBlock("div",{key:2,class:"modal-overlay",onClick:t.withModifiers(Z,["self"])},[t.createElementVNode("div",me,[s[11]||(s[11]=t.createElementVNode("div",{class:"modal-header"},[t.createElementVNode("h3",null,"新增标签")],-1)),t.createElementVNode("div",fe,[t.createElementVNode("div",pe,[s[9]||(s[9]=t.createElementVNode("label",null,[t.createTextVNode("标签名称 "),t.createElementVNode("span",{class:"required"},"*")],-1)),t.withDirectives(t.createElementVNode("input",{"onUpdate:modelValue":s[2]||(s[2]=a=>x.value.name=a),placeholder:"请输入标签名称",class:"modal-input",autofocus:""},null,512),[[t.vModelText,x.value.name]])]),t.createElementVNode("div",ye,[s[10]||(s[10]=t.createElementVNode("label",null,"标签颜色",-1)),t.createElementVNode("div",ue,[t.createElementVNode("label",{class:"color-picker-box",style:t.normalizeStyle({backgroundColor:x.value.color})},[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":s[3]||(s[3]=a=>x.value.color=a),class:"modal-color-picker"},null,512),[[t.vModelText,x.value.color]])],4),t.createElementVNode("span",ve,t.toDisplayString(x.value.color),1)])])]),t.createElementVNode("div",we,[t.createElementVNode("button",{onClick:Z,class:"cancel-btn"},"取消"),t.createElementVNode("button",{onClick:nn,class:"confirm-btn",disabled:!x.value.name.trim()},"确认",8,xe)])])])):t.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-b6482ca8"]]),be={class:"thumbnail-wrapper",ref:"wrapper"},ke=["src","alt"],Ce=["viewBox","preserveAspectRatio"],_e=["x","y","width","height","stroke","stroke-width"],Ee=["points","stroke","stroke-width"],Be=["transform"],Se=["x","y","width","height","stroke","stroke-width"],Ie={key:3},Ae=["cx","cy","r","fill","stroke-width"],Ve=["x","y","width","height","fill"],Ne=["x","y","fill","font-size","font-weight","text-anchor","dominant-baseline"],Te={key:1,class:"loading-placeholder"},De=Y(t.defineComponent({__name:"AnnotationThumbnail",props:{src:{},annotations:{},alt:{},labels:{},fit:{},strokeWidth:{},fontSize:{}},setup(w){const e=w,i=t.ref(null),n=t.ref(!1),r=t.ref(0),c=t.ref(0),l=()=>{i.value&&(r.value=i.value.naturalWidth,c.value=i.value.naturalHeight,n.value=!0)},g=t.computed(()=>e.fit==="contain"?"xMidYMid meet":"xMidYMid slice"),m=t.computed(()=>e.strokeWidth??10),h=t.computed(()=>e.fontSize??30),_=x=>{var E;if((E=x.style)!=null&&E.strokeColor)return x.style.strokeColor;if(e.labels){const p=e.labels.find(N=>N.name===x.label);if(p)return p.color}return"#FF0000"},u=x=>{const E=x.coordinates,p=Math.min(E.x1,E.x2),N=Math.min(E.y1,E.y2),M=Math.abs(E.x1-E.x2),P=Math.abs(E.y1-E.y2);return{x:p,y:N,width:M,height:P}},S=x=>x.coordinates.points.map(p=>`${p.x},${p.y}`).join(" "),b=x=>{if(x.type==="rectangle"){const E=u(x);return{x:E.x,y:E.y-5}}else if(x.type==="polygon"){const E=x.coordinates.points;if(E.length>0)return{x:E[0].x,y:E[0].y-5}}else{if(x.type==="rotatedRect")return{x:x.coordinates.x,y:x.coordinates.y-x.coordinates.height/2-5};if(x.type==="point"){const E=x.coordinates.points;if(E.length>0)return{x:E[0].x,y:E[0].y-15}}else if(x.type==="category")return{x:x.coordinates.x,y:x.coordinates.y}}return{x:0,y:0}},A=x=>{const{x:E,y:p,angle:N}=x.coordinates,M=N*180/Math.PI;return`translate(${E}, ${p}) rotate(${M})`},U=x=>({x:x.coordinates.x,y:x.coordinates.y});return(x,E)=>(t.openBlock(),t.createElementBlock("div",be,[t.createElementVNode("img",{ref_key:"img",ref:i,src:w.src,class:"thumbnail-image",style:t.normalizeStyle({objectFit:w.fit}),onLoad:l,alt:w.alt},null,44,ke),n.value?(t.openBlock(),t.createElementBlock("svg",{key:0,class:"annotation-overlay",viewBox:`0 0 ${r.value} ${c.value}`,preserveAspectRatio:g.value},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(w.annotations,p=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:p.id},[p.type==="rectangle"?(t.openBlock(),t.createElementBlock("rect",{key:0,x:u(p).x,y:u(p).y,width:u(p).width,height:u(p).height,stroke:_(p),"stroke-width":m.value,fill:"transparent"},null,8,_e)):p.type==="polygon"?(t.openBlock(),t.createElementBlock("polygon",{key:1,points:S(p),stroke:_(p),"stroke-width":m.value,fill:"transparent"},null,8,Ee)):p.type==="rotatedRect"?(t.openBlock(),t.createElementBlock("g",{key:2,transform:A(p)},[t.createElementVNode("rect",{x:-p.coordinates.width/2,y:-p.coordinates.height/2,width:p.coordinates.width,height:p.coordinates.height,stroke:_(p),"stroke-width":m.value,fill:"transparent"},null,8,Se)],8,Be)):p.type==="point"?(t.openBlock(),t.createElementBlock("g",Ie,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(p.coordinates.points,(N,M)=>(t.openBlock(),t.createElementBlock("circle",{key:M,cx:N.x,cy:N.y,r:m.value*1.5,fill:_(p),stroke:"white","stroke-width":m.value*.5},null,8,Ae))),128))])):p.type==="category"?(t.openBlock(),t.createElementBlock("rect",{key:4,x:U(p).x-(p.label||"").length*h.value*.6/2-8,y:U(p).y-h.value/2-4,width:(p.label||"").length*h.value*.6+16,height:h.value+8,rx:"6",ry:"6",fill:_(p),"fill-opacity":"0.85"},null,8,Ve)):t.createCommentVNode("",!0),p.label?(t.openBlock(),t.createElementBlock("text",{key:5,x:b(p).x,y:b(p).y,fill:p.type==="category"?"#ffffff":_(p),"font-size":h.value,"font-weight":p.type==="category"?"normal":"bold","text-anchor":p.type==="category"?"middle":"start","dominant-baseline":p.type==="category"?"middle":"auto",class:t.normalizeClass({"anno-label":p.type!=="category"})},t.toDisplayString(p.label),11,Ne)):t.createCommentVNode("",!0)],64))),128))],8,Ce)):(t.openBlock(),t.createElementBlock("div",Te,"Loading..."))],512))}}),[["__scopeId","data-v-159a7956"]]),Me={key:0,class:"gallery-view"},ze={class:"gallery-layout"},Le={class:"gallery-sidebar"},Pe={class:"label-stats-table"},$e={class:"label-cover-wrapper"},Re=["src"],He={class:"gallery-content"},Ue=["onClick"],Fe={class:"thumbnail-wrapper"},Oe={class:"img-meta"},We={class:"img-index"},Ge={class:"anno-count"},Je={key:0,class:"bottom-bar"},Ye={key:1,class:"editor-view"},je={class:"editor-header"},Xe={class:"header-left"},qe={class:"editor-title"},Ke={class:"editor-content"},ot=Y(t.defineComponent({__name:"BatchAnnotator",props:{images:{},labels:{},actionBar:{},clickToEnterEditor:{type:Boolean},thumbStrokeWidth:{},thumbFontSize:{}},emits:["export","update:images","imageClick","update:labels"],setup(w,{expose:e,emit:i}){const n=w,r=i,c=t.ref("gallery"),l=t.ref([]),g=t.ref([]),m=t.ref(0),h=t.ref(null),_=t.ref(null),u=t.ref(null),S=t.computed(()=>{var y,v;return((v=(y=n.actionBar)==null?void 0:y.annotateButton)==null?void 0:v.show)===!0}),b=t.computed(()=>{var y,v;return((v=(y=n.actionBar)==null?void 0:y.exportButton)==null?void 0:v.show)===!0}),A=t.computed(()=>S.value||b.value),U=t.computed(()=>{var y,v;return((v=(y=n.actionBar)==null?void 0:y.annotateButton)==null?void 0:v.text)||"手动标注"}),x=t.computed(()=>{var y,v;return((v=(y=n.actionBar)==null?void 0:y.exportButton)==null?void 0:v.text)||"导出"}),E=t.computed(()=>n.clickToEnterEditor!==!1),p=t.computed(()=>{const y={};g.value.forEach(k=>{y[k.name]={count:0,cover:""}});let v=0;return l.value.forEach(k=>{k.annotations&&k.annotations.forEach(z=>{var L;const D=z.label||(z.labelId?(L=g.value.find(R=>R.id===z.labelId))==null?void 0:L.name:null);D&&y[D]&&(y[D].count++,v++,y[D].cover||(y[D].cover=k.imageUrl))})}),g.value.map(k=>{var L,R;const z=((L=y[k.name])==null?void 0:L.count)||0,D=v===0?"0.00%":(z/v*100).toFixed(2)+"%";return{id:k.id,name:k.name,color:k.color,count:z,percentage:D,cover:((R=y[k.name])==null?void 0:R.cover)||""}})}),N=y=>({color:y.color,backgroundColor:y.color+"1A"});t.watch(()=>n.images,y=>{l.value=JSON.parse(JSON.stringify(y))},{immediate:!0,deep:!0}),t.watch(()=>n.labels,y=>{g.value=JSON.parse(JSON.stringify(y||[]))},{immediate:!0,deep:!0});const M=y=>{m.value=y,c.value="editor",u.value&&(u.value.scrollTop=0),t.nextTick(()=>{_.value&&(_.value.scrollTop=0),window.scrollTo(0,0),requestAnimationFrame(()=>{var v,k;(k=(v=h.value)==null?void 0:v.jumpTo)==null||k.call(v,y)})})},P=(y,v)=>{if(E.value){M(y);return}r("imageClick",{index:y,imageId:v.id,image:v})},F=y=>l.value.findIndex(v=>v.id===y);e({openImageById:y=>{const v=F(y);return v<0?!1:(M(v),!0)},triggerImageClickById:y=>{const v=F(y);if(v<0)return!1;const k=l.value[v];return k?(r("imageClick",{index:v,imageId:k.id,image:k}),!0):!1},getFinalData:()=>({images:JSON.parse(JSON.stringify(l.value)),labels:JSON.parse(JSON.stringify(g.value))})});const j=()=>{if(h.value&&h.value.getCurrentAnnotation){const y=h.value.getCurrentAnnotation();l.value[m.value]&&(l.value[m.value].annotations=y.annotations)}c.value="gallery"},X=()=>{r("export",l.value)},K=y=>{m.value=y.currentIndex,l.value[y.currentIndex]&&(l.value[y.currentIndex].annotations=y.currentAnnotations)},O=y=>{if(h.value&&h.value.getCurrentAnnotation){const v=h.value.getCurrentAnnotation();l.value[m.value]&&(l.value[m.value].annotations=v.annotations,r("update:images",l.value))}},$=y=>{g.value=JSON.parse(JSON.stringify(y||[])),r("update:labels",g.value)};return(y,v)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"batchRootRef",ref:_,class:"batch-annotator"},[c.value==="gallery"?(t.openBlock(),t.createElementBlock("div",Me,[t.createElementVNode("div",ze,[t.createElementVNode("div",Le,[t.createElementVNode("table",Pe,[v[1]||(v[1]=t.createElementVNode("thead",null,[t.createElementVNode("tr",null,[t.createElementVNode("th",null,"标签封面"),t.createElementVNode("th",null,"标签名称"),t.createElementVNode("th",null,"标注数"),t.createElementVNode("th",null,"占比")])],-1)),t.createElementVNode("tbody",null,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(p.value,k=>(t.openBlock(),t.createElementBlock("tr",{key:k.id,style:t.normalizeStyle(N(k))},[t.createElementVNode("td",null,[t.createElementVNode("div",$e,[k.cover?(t.openBlock(),t.createElementBlock("img",{key:0,src:k.cover,class:"label-cover"},null,8,Re)):(t.openBlock(),t.createElementBlock("div",{key:1,class:"label-cover-empty",style:t.normalizeStyle({backgroundColor:k.color})},null,4))])]),t.createElementVNode("td",null,t.toDisplayString(k.name),1),t.createElementVNode("td",null,t.toDisplayString(k.count),1),t.createElementVNode("td",null,t.toDisplayString(k.percentage),1)],4))),128))])])]),t.createElementVNode("div",He,[t.createElementVNode("div",{ref_key:"galleryGridRef",ref:u,class:"gallery-grid"},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(l.value,(k,z)=>(t.openBlock(),t.createElementBlock("div",{key:z,class:"gallery-item",onClick:D=>P(z,k)},[t.createElementVNode("div",Fe,[t.createVNode(De,{src:k.imageUrl,annotations:k.annotations||[],labels:g.value,fit:"cover",strokeWidth:n.thumbStrokeWidth,fontSize:n.thumbFontSize},null,8,["src","annotations","labels","strokeWidth","fontSize"])]),t.createElementVNode("div",Oe,[t.createElementVNode("span",We,"#"+t.toDisplayString(z+1),1),t.createElementVNode("span",Ge,t.toDisplayString((k.annotations||[]).length)+" 标注",1)])],8,Ue))),128))],512)])]),A.value?(t.openBlock(),t.createElementBlock("div",Je,[S.value?(t.openBlock(),t.createElementBlock("button",{key:0,class:"action-btn primary",onClick:v[0]||(v[0]=k=>M(0))},[t.createVNode(V,{name:"edit"}),t.createTextVNode(" "+t.toDisplayString(U.value),1)])):t.createCommentVNode("",!0),b.value?(t.openBlock(),t.createElementBlock("button",{key:1,class:"action-btn success",onClick:X},[t.createVNode(V,{name:"download"}),t.createTextVNode(" "+t.toDisplayString(x.value),1)])):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0)])):(t.openBlock(),t.createElementBlock("div",Ye,[t.createElementVNode("div",je,[t.createElementVNode("div",Xe,[t.createElementVNode("button",{class:"back-btn",onClick:j},[t.createVNode(V,{name:"back",class:"back-icon"}),v[2]||(v[2]=t.createTextVNode()),v[3]||(v[3]=t.createElementVNode("span",{class:"back-text"},"返回",-1))]),t.createElementVNode("span",qe,"正在标注: "+t.toDisplayString(m.value+1)+" / "+t.toDisplayString(l.value.length),1)])]),t.createElementVNode("div",Ke,[t.createVNode(nt,{ref_key:"annotatorRef",ref:h,batchImages:l.value,labels:g.value,annotationTypes:["rectangle","polygon","point","rotatedRect","category"],onBatchChange:K,onAnnotationChange:O,onLabelChange:$},null,8,["batchImages","labels"])])]))],512))}}),[["__scopeId","data-v-369475fa"]]);T.BatchAnnotator=ot,T.ImageAnnotator=nt,T.default=ot,Object.defineProperties(T,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|