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,72 +1,72 @@
1
- var Jt = Object.defineProperty;
2
- var jt = (f, t, i) => t in f ? Jt(f, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : f[t] = i;
3
- var S = (f, t, i) => jt(f, typeof t != "symbol" ? t + "" : t, i);
4
- import { defineComponent as tt, ref as M, watchEffect as Yt, openBlock as y, createElementBlock as x, normalizeClass as J, computed as D, onMounted as Xt, watch as Y, createElementVNode as g, toDisplayString as P, Fragment as B, renderList as F, normalizeStyle as V, createCommentVNode as T, createVNode as L, withModifiers as qt, createTextVNode as K, withDirectives as lt, vModelText as rt, createBlock as yt, nextTick as Gt } from "vue";
5
- const ct = (f, t) => Math.sqrt(Math.pow(f.x - t.x, 2) + Math.pow(f.y - t.y, 2)), Kt = (f, t) => {
6
- let i = !1;
7
- for (let e = 0, o = t.length - 1; e < t.length; o = e++) {
8
- const c = t[e].x, r = t[e].y, a = t[o].x, d = t[o].y;
9
- r > f.y != d > f.y && f.x < (a - c) * (f.y - r) / (d - r) + c && (i = !i);
1
+ var ae = Object.defineProperty;
2
+ var le = (w, t, n) => t in w ? ae(w, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : w[t] = n;
3
+ var T = (w, t, n) => le(w, typeof t != "symbol" ? t + "" : t, n);
4
+ import { defineComponent as ct, ref as M, watchEffect as ce, openBlock as v, createElementBlock as m, normalizeClass as q, computed as V, onMounted as kt, nextTick as at, watch as K, createElementVNode as h, toDisplayString as P, Fragment as N, renderList as J, normalizeStyle as E, createCommentVNode as R, createVNode as H, withModifiers as It, createBlock as vt, withDirectives as ft, vModelText as mt, createTextVNode as lt } from "vue";
5
+ const pt = (w, t) => Math.sqrt(Math.pow(w.x - t.x, 2) + Math.pow(w.y - t.y, 2)), re = (w, t) => {
6
+ let n = !1;
7
+ for (let e = 0, c = t.length - 1; e < t.length; c = e++) {
8
+ const l = t[e].x, a = t[e].y, g = t[c].x, u = t[c].y;
9
+ a > w.y != u > w.y && w.x < (g - l) * (w.y - a) / (u - a) + l && (n = !n);
10
10
  }
11
- return i;
12
- }, pt = (f, t, i) => {
13
- const e = i * (Math.PI / 180), o = Math.cos(e), c = Math.sin(e), r = f.x - t.x, a = f.y - t.y;
11
+ return n;
12
+ }, At = (w, t, n) => {
13
+ const e = n * (Math.PI / 180), c = Math.cos(e), l = Math.sin(e), a = w.x - t.x, g = w.y - t.y;
14
14
  return {
15
- x: t.x + (r * o - a * c),
16
- y: t.y + (r * c + a * o)
15
+ x: t.x + (a * c - g * l),
16
+ y: t.y + (a * l + g * c)
17
17
  };
18
18
  };
19
- class Zt {
19
+ class he {
20
20
  constructor(t) {
21
- S(this, "canvas");
22
- S(this, "ctx");
23
- S(this, "img");
24
- S(this, "annotations", []);
21
+ T(this, "canvas");
22
+ T(this, "ctx");
23
+ T(this, "img");
24
+ T(this, "annotations", []);
25
25
  // 状态
26
- S(this, "currentTool", null);
27
- S(this, "interactionMode", "none");
28
- S(this, "activeAnnotation", null);
29
- S(this, "hoverAnnotation", null);
30
- S(this, "isDrawing", !1);
31
- S(this, "isDragging", !1);
32
- S(this, "isPanning", !1);
26
+ T(this, "currentTool", null);
27
+ T(this, "interactionMode", "none");
28
+ T(this, "activeAnnotation", null);
29
+ T(this, "hoverAnnotation", null);
30
+ T(this, "isDrawing", !1);
31
+ T(this, "isDragging", !1);
32
+ T(this, "isPanning", !1);
33
33
  // 平移模式
34
- S(this, "panStartPoint", null);
34
+ T(this, "panStartPoint", null);
35
35
  // 平移起点
36
- S(this, "dragStartPoint", null);
37
- S(this, "dragStartAnnotation", null);
36
+ T(this, "dragStartPoint", null);
37
+ T(this, "dragStartAnnotation", null);
38
38
  // 快照用于撤销/diff
39
- S(this, "lastMouseMovePoint", null);
39
+ T(this, "lastMouseMovePoint", null);
40
40
  // 用于绘制辅助线
41
- S(this, "isHoveringStartPoint", !1);
41
+ T(this, "isHoveringStartPoint", !1);
42
42
  // 多边形闭合吸附状态
43
43
  // 设置
44
- S(this, "currentLabelColor", "#FF4081");
44
+ T(this, "currentLabelColor", "#FF4081");
45
45
  // 当前选中标签颜色
46
- S(this, "visibleLabels", /* @__PURE__ */ new Set());
46
+ T(this, "visibleLabels", /* @__PURE__ */ new Set());
47
47
  // 可见标签集合 (如果为空则全部可见,或者由外部控制渲染列表)
48
48
  // 交互
49
- S(this, "selectedHandleIndex", -1);
49
+ T(this, "selectedHandleIndex", -1);
50
50
  // -1: 主体, >=0: 顶点索引, -2: 旋转手柄
51
- S(this, "hoverHandleIndex", -1);
51
+ T(this, "hoverHandleIndex", -1);
52
52
  // 视口
53
- S(this, "scale", 1);
54
- S(this, "offset", { x: 0, y: 0 });
55
- S(this, "listeners", {});
56
- S(this, "imageUrl", "");
53
+ T(this, "scale", 1);
54
+ T(this, "offset", { x: 0, y: 0 });
55
+ T(this, "listeners", {});
56
+ T(this, "imageUrl", "");
57
57
  this.canvas = t;
58
- const i = t.getContext("2d");
59
- if (!i) throw new Error("Could not get 2d context");
60
- this.ctx = i, this.img = new Image(), this.img.crossOrigin = "Anonymous", this.img.onload = () => {
58
+ const n = t.getContext("2d");
59
+ if (!n) throw new Error("Could not get 2d context");
60
+ this.ctx = n, this.img = new Image(), this.img.crossOrigin = "Anonymous", this.img.onload = () => {
61
61
  this.fitImageToCanvas(), this.render();
62
62
  }, this.bindEvents();
63
63
  }
64
64
  // --- 公共 API ---
65
- on(t, i) {
66
- this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(i);
65
+ on(t, n) {
66
+ this.listeners[t] || (this.listeners[t] = []), this.listeners[t].push(n);
67
67
  }
68
- emit(t, i) {
69
- this.listeners[t] && this.listeners[t].forEach((e) => e(i));
68
+ emit(t, n) {
69
+ this.listeners[t] && this.listeners[t].forEach((e) => e(n));
70
70
  }
71
71
  loadImage(t) {
72
72
  this.imageUrl = t, this.img.src = t, this.activeAnnotation = null, this.isDrawing = !1;
@@ -89,47 +89,47 @@ class Zt {
89
89
  zoom(t) {
90
90
  const e = t > 0 ? this.scale * 1.1 : this.scale / 1.1;
91
91
  if (e < 0.1 || e > 10) return;
92
- const o = this.canvas.width / 2, c = this.canvas.height / 2, r = this.toImageCoords(o, c);
93
- this.scale = e, this.offset.x = o - r.x * this.scale, this.offset.y = c - r.y * this.scale, this.clampViewportOffset(), this.render();
92
+ const c = this.canvas.width / 2, l = this.canvas.height / 2, a = this.toImageCoords(c, l);
93
+ this.scale = e, this.offset.x = c - a.x * this.scale, this.offset.y = l - a.y * this.scale, this.clampViewportOffset(), this.render();
94
94
  }
95
95
  resize() {
96
96
  this.fitImageToCanvas(), this.render();
97
97
  }
98
98
  // --- 坐标系统 ---
99
- toImageCoords(t, i) {
99
+ toImageCoords(t, n) {
100
100
  return {
101
101
  x: (t - this.offset.x) / this.scale,
102
- y: (i - this.offset.y) / this.scale
102
+ y: (n - this.offset.y) / this.scale
103
103
  };
104
104
  }
105
- toScreenCoords(t, i) {
105
+ toScreenCoords(t, n) {
106
106
  return {
107
107
  x: t * this.scale + this.offset.x,
108
- y: i * this.scale + this.offset.y
108
+ y: n * this.scale + this.offset.y
109
109
  };
110
110
  }
111
111
  fitImageToCanvas() {
112
112
  const t = this.canvas.parentElement;
113
113
  if (t) {
114
114
  if (this.canvas.width = t.clientWidth, this.canvas.height = t.clientHeight, this.img.width === 0) return;
115
- const i = this.canvas.width / this.img.width, e = this.canvas.height / this.img.height;
116
- this.scale = Math.min(i, e), 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();
115
+ const n = this.canvas.width / this.img.width, e = this.canvas.height / this.img.height;
116
+ this.scale = Math.min(n, e), 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();
117
117
  }
118
118
  }
119
119
  clampViewportOffset() {
120
120
  if (this.img.width === 0 || this.img.height === 0) return;
121
- const t = this.img.width * this.scale, i = this.img.height * this.scale;
121
+ const t = this.img.width * this.scale, n = this.img.height * this.scale;
122
122
  if (t <= this.canvas.width)
123
123
  this.offset.x = (this.canvas.width - t) / 2;
124
124
  else {
125
- const e = this.canvas.width - t, o = 0;
126
- this.offset.x = Math.min(o, Math.max(e, this.offset.x));
125
+ const e = this.canvas.width - t, c = 0;
126
+ this.offset.x = Math.min(c, Math.max(e, this.offset.x));
127
127
  }
128
- if (i <= this.canvas.height)
129
- this.offset.y = (this.canvas.height - i) / 2;
128
+ if (n <= this.canvas.height)
129
+ this.offset.y = (this.canvas.height - n) / 2;
130
130
  else {
131
- const e = this.canvas.height - i, o = 0;
132
- this.offset.y = Math.min(o, Math.max(e, this.offset.y));
131
+ const e = this.canvas.height - n, c = 0;
132
+ this.offset.y = Math.min(c, Math.max(e, this.offset.y));
133
133
  }
134
134
  }
135
135
  // --- 事件处理 ---
@@ -140,10 +140,10 @@ class Zt {
140
140
  this.interactionMode === "select" && (t.key === "Delete" || t.key === "Backspace") && this.activeAnnotation && this.deleteAnnotation(this.activeAnnotation.id);
141
141
  }
142
142
  deleteAnnotation(t) {
143
- const i = this.annotations.findIndex((e) => e.id === t);
144
- if (i > -1) {
145
- const e = this.annotations[i];
146
- this.annotations.splice(i, 1), this.activeAnnotation = null, this.emit("annotationChange", {
143
+ const n = this.annotations.findIndex((e) => e.id === t);
144
+ if (n > -1) {
145
+ const e = this.annotations[n];
146
+ this.annotations.splice(n, 1), this.activeAnnotation = null, this.emit("annotationChange", {
147
147
  action: "delete",
148
148
  changedItem: e,
149
149
  imageUrl: this.imageUrl
@@ -151,28 +151,28 @@ class Zt {
151
151
  }
152
152
  }
153
153
  handleMouseDown(t) {
154
- const i = this.canvas.getBoundingClientRect(), e = t.clientX - i.left, o = t.clientY - i.top, c = this.toImageCoords(e, o);
154
+ const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left, c = t.clientY - n.top, l = this.toImageCoords(e, c);
155
155
  if (this.canvas.style.cursor === "grab" || this.canvas.style.cursor === "grabbing") {
156
- this.isPanning = !0, this.panStartPoint = { x: e, y: o }, this.canvas.style.cursor = "grabbing";
156
+ this.isPanning = !0, this.panStartPoint = { x: e, y: c }, this.canvas.style.cursor = "grabbing";
157
157
  return;
158
158
  }
159
159
  if (this.interactionMode === "select" && this.activeAnnotation) {
160
- const d = this.getHitHandle(e, o, this.activeAnnotation);
161
- if (d !== -100) {
162
- this.isDragging = !0, this.dragStartPoint = c, this.selectedHandleIndex = d, this.dragStartAnnotation = JSON.parse(JSON.stringify(this.activeAnnotation));
160
+ const u = this.getHitHandle(e, c, this.activeAnnotation);
161
+ if (u !== -100) {
162
+ this.isDragging = !0, this.dragStartPoint = l, this.selectedHandleIndex = u, this.dragStartAnnotation = JSON.parse(JSON.stringify(this.activeAnnotation));
163
163
  return;
164
164
  }
165
165
  }
166
- const r = this.interactionMode === "select" ? this.getHitCategory(e, o) : null;
167
- if (r) {
168
- this.activeAnnotation = r, this.isDragging = !1, this.selectedHandleIndex = -1, this.emit("annotationChange", { action: "select", changedItem: r, imageUrl: this.imageUrl }), this.render();
166
+ const a = this.interactionMode === "select" ? this.getHitCategory(e, c) : null;
167
+ if (a) {
168
+ this.activeAnnotation = a, this.isDragging = !1, this.selectedHandleIndex = -1, this.emit("annotationChange", { action: "select", changedItem: a, imageUrl: this.imageUrl }), this.render();
169
169
  return;
170
170
  }
171
- const a = this.getHitAnnotation(c);
171
+ const g = this.getHitAnnotation(l);
172
172
  if (this.interactionMode === "select") {
173
- if (a) {
174
- if (!(this.visibleLabels.size > 0 && !this.visibleLabels.has(a.label))) {
175
- this.activeAnnotation = a, this.isDragging = !0, this.dragStartPoint = c, this.selectedHandleIndex = -1, this.dragStartAnnotation = JSON.parse(JSON.stringify(a)), this.emit("annotationChange", { action: "select", changedItem: a, imageUrl: this.imageUrl }), this.render();
173
+ if (g) {
174
+ if (!(this.visibleLabels.size > 0 && !this.visibleLabels.has(g.label))) {
175
+ this.activeAnnotation = g, this.isDragging = !0, this.dragStartPoint = l, this.selectedHandleIndex = -1, this.dragStartAnnotation = JSON.parse(JSON.stringify(g)), this.emit("annotationChange", { action: "select", changedItem: g, imageUrl: this.imageUrl }), this.render();
176
176
  return;
177
177
  }
178
178
  } else
@@ -181,43 +181,43 @@ class Zt {
181
181
  }
182
182
  if (this.interactionMode === "draw") {
183
183
  if (this.isDrawing && this.currentTool === "polygon" && this.activeAnnotation) {
184
- const d = this.activeAnnotation.coordinates;
185
- if (d.points.length > 2 && ct(c, d.points[0]) < 20 / this.scale) {
184
+ const u = this.activeAnnotation.coordinates;
185
+ if (u.points.length > 2 && pt(l, u.points[0]) < 20 / this.scale) {
186
186
  this.finishDrawing();
187
187
  return;
188
188
  }
189
- this.startDrawing(c);
189
+ this.startDrawing(l);
190
190
  return;
191
191
  }
192
192
  if (this.currentTool) {
193
193
  if (this.currentTool === "polygon" && !this.isDrawing) {
194
- this.startDrawing(c);
194
+ this.startDrawing(l);
195
195
  return;
196
196
  }
197
- this.startDrawing(c);
197
+ this.startDrawing(l);
198
198
  }
199
199
  return;
200
200
  }
201
201
  this.activeAnnotation = null, this.render();
202
202
  }
203
203
  handleMouseMove(t) {
204
- const i = this.canvas.getBoundingClientRect(), e = t.clientX - i.left, o = t.clientY - i.top, c = this.toImageCoords(e, o);
204
+ const n = this.canvas.getBoundingClientRect(), e = t.clientX - n.left, c = t.clientY - n.top, l = this.toImageCoords(e, c);
205
205
  if (this.isPanning && this.panStartPoint) {
206
- const r = e - this.panStartPoint.x, a = o - this.panStartPoint.y;
207
- this.offset.x += r, this.offset.y += a, this.clampViewportOffset(), this.panStartPoint = { x: e, y: o }, this.render();
206
+ const a = e - this.panStartPoint.x, g = c - this.panStartPoint.y;
207
+ this.offset.x += a, this.offset.y += g, this.clampViewportOffset(), this.panStartPoint = { x: e, y: c }, this.render();
208
208
  return;
209
209
  }
210
- if (this.lastMouseMovePoint = c, this.isDrawing) {
210
+ if (this.lastMouseMovePoint = l, this.isDrawing) {
211
211
  if (this.currentTool === "polygon" && this.activeAnnotation) {
212
- const r = this.activeAnnotation.coordinates;
213
- if (r.points.length > 2) {
214
- const a = r.points[0], d = ct(c, a);
215
- this.isHoveringStartPoint = d < 20 / this.scale;
212
+ const a = this.activeAnnotation.coordinates;
213
+ if (a.points.length > 2) {
214
+ const g = a.points[0], u = pt(l, g);
215
+ this.isHoveringStartPoint = u < 20 / this.scale;
216
216
  } else
217
217
  this.isHoveringStartPoint = !1;
218
218
  }
219
- this.updateDrawing(c);
220
- } else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(c) : this.checkHover(e, o, c);
219
+ this.updateDrawing(l);
220
+ } else this.isDragging && this.activeAnnotation && this.dragStartPoint ? this.updateDragging(l) : this.checkHover(e, c, l);
221
221
  this.render();
222
222
  }
223
223
  handleMouseUp(t) {
@@ -240,17 +240,17 @@ class Zt {
240
240
  }
241
241
  // --- 绘制逻辑 ---
242
242
  // 辅助函数:将 hex 转换为 rgba
243
- hexToRgba(t, i) {
243
+ hexToRgba(t, n) {
244
244
  if (!t.startsWith("#")) return t;
245
- const e = parseInt(t.slice(1, 3), 16), o = parseInt(t.slice(3, 5), 16), c = parseInt(t.slice(5, 7), 16);
246
- return `rgba(${e}, ${o}, ${c}, ${i})`;
245
+ const e = parseInt(t.slice(1, 3), 16), c = parseInt(t.slice(3, 5), 16), l = parseInt(t.slice(5, 7), 16);
246
+ return `rgba(${e}, ${c}, ${l}, ${n})`;
247
247
  }
248
248
  startDrawing(t) {
249
249
  if (!this.currentTool) return;
250
- const i = Date.now().toString();
250
+ const n = Date.now().toString();
251
251
  if (this.hexToRgba(this.currentLabelColor, 0.2), this.currentLabelColor, this.currentTool === "rectangle")
252
252
  this.isDrawing = !0, this.dragStartPoint = t, this.activeAnnotation = {
253
- id: i,
253
+ id: n,
254
254
  type: "rectangle",
255
255
  label: "",
256
256
  // 组件应填充此项
@@ -259,7 +259,7 @@ class Zt {
259
259
  };
260
260
  else if (this.currentTool === "point") {
261
261
  const e = {
262
- id: i,
262
+ id: n,
263
263
  type: "point",
264
264
  label: "",
265
265
  coordinates: { points: [t] },
@@ -268,7 +268,7 @@ class Zt {
268
268
  this.annotations.push(e), this.emit("annotationChange", { action: "add", changedItem: e, imageUrl: this.imageUrl }), this.activeAnnotation = e;
269
269
  } else if (this.currentTool === "polygon")
270
270
  this.activeAnnotation && this.activeAnnotation.type === "polygon" && this.isDrawing ? this.activeAnnotation.coordinates.points.push(t) : (this.isDrawing = !0, this.activeAnnotation = {
271
- id: i,
271
+ id: n,
272
272
  type: "polygon",
273
273
  label: "",
274
274
  coordinates: { points: [t] },
@@ -276,17 +276,16 @@ class Zt {
276
276
  });
277
277
  else if (this.currentTool === "category") {
278
278
  const e = {
279
- id: i,
279
+ id: n,
280
280
  type: "category",
281
281
  label: "",
282
282
  // 将被填充
283
- coordinates: null,
284
- // 或位置?
283
+ coordinates: { x: t.x, y: t.y },
285
284
  style: { strokeColor: this.currentLabelColor }
286
285
  };
287
286
  this.annotations.push(e), this.emit("annotationChange", { action: "add", changedItem: e, imageUrl: this.imageUrl }), this.activeAnnotation = e;
288
287
  } else this.currentTool === "rotatedRect" && (this.isDrawing = !0, this.dragStartPoint = t, this.activeAnnotation = {
289
- id: i,
288
+ id: n,
290
289
  type: "rotatedRect",
291
290
  label: "",
292
291
  coordinates: { x: t.x, y: t.y, width: 0, height: 0, angle: 0 },
@@ -296,11 +295,11 @@ class Zt {
296
295
  updateDrawing(t) {
297
296
  if (this.activeAnnotation)
298
297
  if (this.activeAnnotation.type === "rectangle" && this.dragStartPoint) {
299
- const i = this.activeAnnotation.coordinates;
300
- i.x2 = t.x, i.y2 = t.y;
298
+ const n = this.activeAnnotation.coordinates;
299
+ n.x2 = t.x, n.y2 = t.y;
301
300
  } else if (this.activeAnnotation.type === "rotatedRect" && this.dragStartPoint) {
302
- const i = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x), o = Math.abs(t.y - this.dragStartPoint.y);
303
- i.width = e * 2, i.height = o * 2;
301
+ const n = this.activeAnnotation.coordinates, e = Math.abs(t.x - this.dragStartPoint.x), c = Math.abs(t.y - this.dragStartPoint.y);
302
+ n.width = e * 2, n.height = c * 2;
304
303
  } else this.activeAnnotation.type;
305
304
  }
306
305
  finishDrawing() {
@@ -311,8 +310,8 @@ class Zt {
311
310
  this.activeAnnotation = null, this.isDrawing = !1;
312
311
  return;
313
312
  }
314
- const i = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2), o = Math.min(t.y1, t.y2), c = Math.max(t.y1, t.y2);
315
- t.x1 = i, t.x2 = e, t.y1 = o, t.y2 = c, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
313
+ const n = Math.min(t.x1, t.x2), e = Math.max(t.x1, t.x2), c = Math.min(t.y1, t.y2), l = Math.max(t.y1, t.y2);
314
+ t.x1 = n, t.x2 = e, t.y1 = c, t.y2 = l, this.annotations.push(this.activeAnnotation), this.emit("annotationChange", { action: "add", changedItem: this.activeAnnotation, imageUrl: this.imageUrl });
316
315
  } else if (this.activeAnnotation.type === "polygon") {
317
316
  if (this.activeAnnotation.coordinates.points.length < 3) {
318
317
  this.activeAnnotation = null, this.isDrawing = !1;
@@ -333,89 +332,92 @@ class Zt {
333
332
  }
334
333
  updateDragging(t) {
335
334
  if (!this.activeAnnotation || !this.dragStartPoint || !this.dragStartAnnotation) return;
336
- const i = t.x - this.dragStartPoint.x, e = t.y - this.dragStartPoint.y;
337
- this.selectedHandleIndex === -1 ? this.moveAnnotation(this.activeAnnotation, this.dragStartAnnotation, i, e) : this.resizeAnnotation(this.activeAnnotation, this.dragStartAnnotation, this.selectedHandleIndex, t);
335
+ const n = t.x - this.dragStartPoint.x, e = t.y - this.dragStartPoint.y;
336
+ this.selectedHandleIndex === -1 ? this.moveAnnotation(this.activeAnnotation, this.dragStartAnnotation, n, e) : this.resizeAnnotation(this.activeAnnotation, this.dragStartAnnotation, this.selectedHandleIndex, t);
338
337
  }
339
- moveAnnotation(t, i, e, o) {
338
+ moveAnnotation(t, n, e, c) {
340
339
  if (t.type === "rectangle") {
341
- const c = i.coordinates, r = t.coordinates;
342
- r.x1 = c.x1 + e, r.x2 = c.x2 + e, r.y1 = c.y1 + o, r.y2 = c.y2 + o;
340
+ const l = n.coordinates, a = t.coordinates;
341
+ a.x1 = l.x1 + e, a.x2 = l.x2 + e, a.y1 = l.y1 + c, a.y2 = l.y2 + c;
343
342
  } else if (t.type === "point") {
344
- const c = i.coordinates, r = t.coordinates;
345
- r.points = c.points.map((a) => ({ x: a.x + e, y: a.y + o }));
343
+ const l = n.coordinates, a = t.coordinates;
344
+ a.points = l.points.map((g) => ({ x: g.x + e, y: g.y + c }));
346
345
  } else if (t.type === "rotatedRect") {
347
- const c = i.coordinates, r = t.coordinates;
348
- r.x = c.x + e, r.y = c.y + o;
346
+ const l = n.coordinates, a = t.coordinates;
347
+ a.x = l.x + e, a.y = l.y + c;
349
348
  } else if (t.type === "polygon") {
350
- const c = i.coordinates, r = t.coordinates;
351
- r.points = c.points.map((a) => ({ x: a.x + e, y: a.y + o }));
349
+ const l = n.coordinates, a = t.coordinates;
350
+ a.points = l.points.map((g) => ({ x: g.x + e, y: g.y + c }));
351
+ } else if (t.type === "category") {
352
+ const l = n.coordinates, a = t.coordinates;
353
+ l && a && (a.x = l.x + e, a.y = l.y + c);
352
354
  }
353
355
  }
354
- resizeAnnotation(t, i, e, o) {
356
+ resizeAnnotation(t, n, e, c) {
355
357
  if (t.type === "rectangle") {
356
- const c = t.coordinates;
357
- e === 0 && (c.x1 = o.x, c.y1 = o.y), e === 1 && (c.x2 = o.x, c.y1 = o.y), e === 2 && (c.x2 = o.x, c.y2 = o.y), e === 3 && (c.x1 = o.x, c.y2 = o.y);
358
+ const l = t.coordinates;
359
+ e === 0 && (l.x1 = c.x, l.y1 = c.y), e === 1 && (l.x2 = c.x, l.y1 = c.y), e === 2 && (l.x2 = c.x, l.y2 = c.y), e === 3 && (l.x1 = c.x, l.y2 = c.y);
358
360
  } else if (t.type === "polygon") {
359
- const c = t.coordinates;
360
- e >= 0 && e < c.points.length && (c.points[e] = o);
361
+ const l = t.coordinates;
362
+ e >= 0 && e < l.points.length && (l.points[e] = c);
361
363
  } else if (t.type === "point") {
362
- const c = t.coordinates;
363
- e >= 0 && e < c.points.length && (c.points[e] = o);
364
+ const l = t.coordinates;
365
+ e >= 0 && e < l.points.length && (l.points[e] = c);
364
366
  } else if (t.type === "rotatedRect") {
365
- const c = t.coordinates;
367
+ const l = t.coordinates;
366
368
  if (e === -2) {
367
- const r = c.x, a = c.y, d = o.x - r, u = o.y - a;
368
- let w = Math.atan2(u, d) * 180 / Math.PI;
369
- w += 90, c.angle = w;
369
+ const a = l.x, g = l.y, u = c.x - a, r = c.y - g;
370
+ let A = Math.atan2(r, u) * 180 / Math.PI;
371
+ A += 90, l.angle = A;
370
372
  } else {
371
- const r = c.angle * Math.PI / 180, a = Math.cos(-r), d = Math.sin(-r), u = o.x - c.x, w = o.y - c.y, m = u * a - w * d, _ = u * d + w * a;
372
- (e === 0 || e === 3) && (c.width / 2, c.width = Math.abs(m) * 2), (e === 1 || e === 2) && (c.width = Math.abs(m) * 2), (e === 0 || e === 1) && (c.height = Math.abs(_) * 2), (e === 2 || e === 3) && (c.height = Math.abs(_) * 2);
373
+ const a = l.angle * Math.PI / 180, g = Math.cos(-a), u = Math.sin(-a), r = c.x - l.x, A = c.y - l.y, x = r * g - A * u, D = r * u + A * g;
374
+ (e === 0 || e === 3) && (l.width / 2, l.width = Math.abs(x) * 2), (e === 1 || e === 2) && (l.width = Math.abs(x) * 2), (e === 0 || e === 1) && (l.height = Math.abs(D) * 2), (e === 2 || e === 3) && (l.height = Math.abs(D) * 2);
373
375
  }
374
376
  }
375
377
  }
376
378
  // --- 命中测试和渲染辅助函数 ---
377
379
  getHitAnnotation(t) {
378
- for (let i = this.annotations.length - 1; i >= 0; i--) {
379
- const e = this.annotations[i];
380
+ for (let n = this.annotations.length - 1; n >= 0; n--) {
381
+ const e = this.annotations[n];
380
382
  if (this.isPointInAnnotation(t, e))
381
383
  return e;
382
384
  }
383
385
  return null;
384
386
  }
385
- isPointInAnnotation(t, i) {
386
- if (i.type === "rectangle") {
387
- const e = i.coordinates;
387
+ isPointInAnnotation(t, n) {
388
+ if (n.type === "rectangle") {
389
+ const e = n.coordinates;
388
390
  return t.x >= e.x1 && t.x <= e.x2 && t.y >= e.y1 && t.y <= e.y2;
389
- } else if (i.type === "polygon") {
390
- const e = i.coordinates;
391
- return Kt(t, e.points);
392
- } else if (i.type === "rotatedRect") {
393
- const e = i.coordinates, o = pt(t, { x: e.x, y: e.y }, -e.angle), c = e.width / 2, r = e.height / 2;
394
- return o.x >= e.x - c && o.x <= e.x + c && o.y >= e.y - r && o.y <= e.y + r;
395
- } else if (i.type === "point")
396
- return i.coordinates.points.some((o) => ct(t, o) < 10 / this.scale);
391
+ } else if (n.type === "polygon") {
392
+ const e = n.coordinates;
393
+ return re(t, e.points);
394
+ } else if (n.type === "rotatedRect") {
395
+ const e = n.coordinates, c = At(t, { x: e.x, y: e.y }, -e.angle), l = e.width / 2, a = e.height / 2;
396
+ return c.x >= e.x - l && c.x <= e.x + l && c.y >= e.y - a && c.y <= e.y + a;
397
+ } else if (n.type === "point")
398
+ return n.coordinates.points.some((c) => pt(t, c) < 10 / this.scale);
397
399
  return !1;
398
400
  }
399
- getHitHandle(t, i, e) {
400
- const o = this.getAnnotationHandles(e), c = 6;
401
- for (let r = 0; r < o.length; r++) {
402
- const a = o[r], d = this.toScreenCoords(a.x, a.y);
403
- if (Math.abs(t - d.x) < c && Math.abs(i - d.y) < c)
404
- return e.type === "rotatedRect" && r === 4 ? -2 : r;
401
+ getHitHandle(t, n, e) {
402
+ const c = this.getAnnotationHandles(e), l = 6;
403
+ for (let a = 0; a < c.length; a++) {
404
+ const g = c[a], u = this.toScreenCoords(g.x, g.y);
405
+ if (Math.abs(t - u.x) < l && Math.abs(n - u.y) < l)
406
+ return e.type === "rotatedRect" && a === 4 ? -2 : a;
405
407
  }
406
408
  return -100;
407
409
  }
408
410
  getAnnotationHandles(t) {
409
411
  if (t.type === "rectangle") {
410
- const i = t.coordinates;
412
+ const n = t.coordinates;
411
413
  return [
412
- { x: i.x1, y: i.y1 },
414
+ { x: n.x1, y: n.y1 },
413
415
  // 左上
414
- { x: i.x2, y: i.y1 },
416
+ { x: n.x2, y: n.y1 },
415
417
  // 右上
416
- { x: i.x2, y: i.y2 },
418
+ { x: n.x2, y: n.y2 },
417
419
  // 右下
418
- { x: i.x1, y: i.y2 }
420
+ { x: n.x1, y: n.y2 }
419
421
  // 左下
420
422
  ];
421
423
  } else {
@@ -424,24 +426,24 @@ class Zt {
424
426
  if (t.type === "point")
425
427
  return t.coordinates.points;
426
428
  if (t.type === "rotatedRect") {
427
- const i = t.coordinates, e = { x: i.x, y: i.y }, o = i.width / 2, c = i.height / 2, r = { x: i.x - o, y: i.y - c }, a = { x: i.x + o, y: i.y - c }, d = { x: i.x + o, y: i.y + c }, u = { x: i.x - o, y: i.y + c }, w = { x: i.x, y: i.y - c - 20 / this.scale };
428
- return [r, a, d, u, w].map((m) => pt(m, e, i.angle));
429
+ const n = t.coordinates, e = { x: n.x, y: n.y }, c = n.width / 2, l = n.height / 2, a = { x: n.x - c, y: n.y - l }, g = { x: n.x + c, y: n.y - l }, u = { x: n.x + c, y: n.y + l }, r = { x: n.x - c, y: n.y + l }, A = { x: n.x, y: n.y - l - 20 / this.scale };
430
+ return [a, g, u, r, A].map((x) => At(x, e, n.angle));
429
431
  }
430
432
  }
431
433
  return [];
432
434
  }
433
- checkHover(t, i, e) {
434
- const o = this.getHitCategory(t, i);
435
- if (o) {
436
- this.canvas.style.cursor = "pointer", this.hoverAnnotation = o;
435
+ checkHover(t, n, e) {
436
+ const c = this.getHitCategory(t, n);
437
+ if (c) {
438
+ this.canvas.style.cursor = "pointer", this.hoverAnnotation = c;
437
439
  return;
438
440
  }
439
- if (this.activeAnnotation && this.getHitHandle(t, i, this.activeAnnotation) !== -100) {
441
+ if (this.activeAnnotation && this.getHitHandle(t, n, this.activeAnnotation) !== -100) {
440
442
  this.canvas.style.cursor = "pointer";
441
443
  return;
442
444
  }
443
- const c = this.getHitAnnotation(e);
444
- c ? (this.canvas.style.cursor = "move", this.hoverAnnotation = c) : (this.canvas.style.cursor = "default", this.hoverAnnotation = null);
445
+ const l = this.getHitAnnotation(e);
446
+ l ? (this.canvas.style.cursor = "move", this.hoverAnnotation = l) : (this.canvas.style.cursor = "default", this.hoverAnnotation = null);
445
447
  }
446
448
  render() {
447
449
  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((t) => {
@@ -449,172 +451,153 @@ class Zt {
449
451
  }), this.activeAnnotation && this.drawItem(this.activeAnnotation, !0), this.renderCategories();
450
452
  }
451
453
  renderCategories() {
452
- const t = this.annotations.filter((d) => d.type === "category");
454
+ const t = this.annotations.filter((e) => e.type === "category");
453
455
  if (t.length === 0) return;
454
- this.ctx.save(), this.ctx.font = "14px sans-serif", this.ctx.textBaseline = "top";
455
- let i = 10;
456
- const e = 10, o = 8, c = 4, r = 24, a = 8;
457
- t.forEach((d) => {
458
- const u = d.label || "Unlabeled", w = this.ctx.measureText(u).width + o * 2, m = this.activeAnnotation === d, _ = this.hoverAnnotation === d;
459
- this.ctx.fillStyle = m ? "#E3F2FD" : _ ? "#F5F5F5" : "rgba(255, 255, 255, 0.9)", this.ctx.strokeStyle = m ? "#2196F3" : "#666", this.ctx.lineWidth = m ? 2 : 1, this.ctx.beginPath(), this.ctx.rect(i, e, w, r), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = m ? "#1976D2" : "#333", this.ctx.fillText(u, i + o, e + c), i += w + a;
456
+ this.ctx.save(), this.ctx.font = "14px sans-serif", this.ctx.textBaseline = "middle", this.ctx.textAlign = "center";
457
+ const n = 12;
458
+ t.forEach((e) => {
459
+ var C;
460
+ const c = e.label || "未命名分类", l = this.ctx.measureText(c).width + n * 2, a = 28, g = this.activeAnnotation === e, u = this.hoverAnnotation === e;
461
+ let r = { x: 20, y: 20 };
462
+ e.coordinates && typeof e.coordinates.x == "number" && typeof e.coordinates.y == "number" && (r = this.toScreenCoords(e.coordinates.x, e.coordinates.y));
463
+ const A = r.x - l / 2, x = r.y - a / 2, D = ((C = e.style) == null ? void 0 : C.strokeColor) || "#2196F3";
464
+ this.ctx.fillStyle = g ? D : this.hexToRgba(D, 0.85), u && !g && (this.ctx.fillStyle = D), g ? (this.ctx.strokeStyle = "#ffffff", this.ctx.lineWidth = 2) : (this.ctx.strokeStyle = "transparent", this.ctx.lineWidth = 0), this.ctx.beginPath(), this.ctx.roundRect(A, x, l, a, 6), this.ctx.fill(), g && (this.ctx.stroke(), this.ctx.save(), this.ctx.strokeStyle = D, this.ctx.lineWidth = 2, this.ctx.strokeRect(A - 3, x - 3, l + 6, a + 6), this.ctx.restore()), this.ctx.fillStyle = "#ffffff", this.ctx.fillText(c, r.x, r.y);
460
465
  }), this.ctx.restore();
461
466
  }
462
- getHitCategory(t, i) {
463
- const e = this.annotations.filter((w) => w.type === "category");
467
+ getHitCategory(t, n) {
468
+ const e = this.annotations.filter((g) => g.type === "category");
464
469
  if (e.length === 0) return null;
465
470
  this.ctx.save(), this.ctx.font = "14px sans-serif";
466
- let o = 10;
467
- const c = 10, r = 8, a = 24, d = 8;
468
- let u = null;
469
- for (const w of e) {
470
- const m = w.label || "Unlabeled", _ = this.ctx.measureText(m).width + r * 2;
471
- if (t >= o && t <= o + _ && i >= c && i <= c + a) {
472
- u = w;
471
+ const c = 12, l = 28;
472
+ let a = null;
473
+ for (let g = e.length - 1; g >= 0; g--) {
474
+ const u = e[g], r = u.label || "未命名分类", A = this.ctx.measureText(r).width + c * 2;
475
+ let x = { x: 20, y: 20 };
476
+ u.coordinates && typeof u.coordinates.x == "number" && typeof u.coordinates.y == "number" && (x = this.toScreenCoords(u.coordinates.x, u.coordinates.y));
477
+ const D = x.x - A / 2, C = x.y - l / 2;
478
+ if (t >= D && t <= D + A && n >= C && n <= C + l) {
479
+ a = u;
473
480
  break;
474
481
  }
475
- o += _ + d;
476
482
  }
477
- return this.ctx.restore(), u;
483
+ return this.ctx.restore(), a;
478
484
  }
479
- drawItem(t, i) {
480
- var c;
481
- if (this.visibleLabels.size > 0 && !this.visibleLabels.has(t.label) && !i)
485
+ drawItem(t, n) {
486
+ var l;
487
+ if (this.visibleLabels.size > 0 && !this.visibleLabels.has(t.label) && !n)
482
488
  return;
483
489
  this.ctx.save();
484
- const e = ((c = t.style) == null ? void 0 : c.strokeColor) || "#FF4081", o = i ? "#00E5FF" : e;
485
- if (this.ctx.strokeStyle = o, this.ctx.lineWidth = 2, i ? this.ctx.fillStyle = "rgba(0, 229, 255, 0.2)" : this.ctx.fillStyle = this.hexToRgba(e, 0.2), t.type === "rectangle") {
486
- const r = t.coordinates, a = this.toScreenCoords(r.x1, r.y1), d = this.toScreenCoords(r.x2, r.y2), u = Math.min(a.x, d.x), w = Math.min(a.y, d.y), m = Math.abs(a.x - d.x), _ = Math.abs(a.y - d.y);
487
- this.ctx.strokeRect(u, w, m, _), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(u, w, m, _), i && this.drawHandles(this.getAnnotationHandles(t));
490
+ const e = ((l = t.style) == null ? void 0 : l.strokeColor) || "#FF4081", c = n ? "#00E5FF" : e;
491
+ if (this.ctx.strokeStyle = c, this.ctx.lineWidth = 2, t.type === "rectangle") {
492
+ const a = t.coordinates, g = this.toScreenCoords(a.x1, a.y1), u = this.toScreenCoords(a.x2, a.y2), r = Math.min(g.x, u.x), A = Math.min(g.y, u.y), x = Math.abs(g.x - u.x), D = Math.abs(g.y - u.y);
493
+ this.ctx.strokeRect(r, A, x, D), n && this.drawHandles(this.getAnnotationHandles(t));
488
494
  } else if (t.type === "polygon") {
489
- const r = t.coordinates;
490
- if (r.points.length === 0) {
495
+ const a = t.coordinates;
496
+ if (a.points.length === 0) {
491
497
  this.ctx.restore();
492
498
  return;
493
499
  }
494
500
  this.ctx.beginPath();
495
- const a = this.toScreenCoords(r.points[0].x, r.points[0].y);
496
- this.ctx.moveTo(a.x, a.y);
497
- for (let d = 1; d < r.points.length; d++) {
498
- const u = this.toScreenCoords(r.points[d].x, r.points[d].y);
499
- this.ctx.lineTo(u.x, u.y);
501
+ const g = this.toScreenCoords(a.points[0].x, a.points[0].y);
502
+ this.ctx.moveTo(g.x, g.y);
503
+ for (let u = 1; u < a.points.length; u++) {
504
+ const r = this.toScreenCoords(a.points[u].x, a.points[u].y);
505
+ this.ctx.lineTo(r.x, r.y);
500
506
  }
501
507
  if (!this.isDrawing || t !== this.activeAnnotation)
502
508
  this.ctx.closePath();
503
509
  else if (this.lastMouseMovePoint) {
504
- let d = this.lastMouseMovePoint;
505
- if (this.isHoveringStartPoint && r.points.length > 0) {
506
- d = r.points[0];
507
- const w = this.toScreenCoords(r.points[0].x, r.points[0].y);
508
- this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(w.x, w.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();
510
+ let u = this.lastMouseMovePoint;
511
+ if (this.isHoveringStartPoint && a.points.length > 0) {
512
+ u = a.points[0];
513
+ const A = this.toScreenCoords(a.points[0].x, a.points[0].y);
514
+ this.ctx.save(), this.ctx.beginPath(), this.ctx.arc(A.x, A.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();
509
515
  }
510
- const u = this.toScreenCoords(d.x, d.y);
511
- this.ctx.lineTo(u.x, u.y);
516
+ const r = this.toScreenCoords(u.x, u.y);
517
+ this.ctx.lineTo(r.x, r.y);
512
518
  }
513
- 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(t));
519
+ this.ctx.stroke(), n && this.drawHandles(this.getAnnotationHandles(t));
514
520
  } else if (t.type === "rotatedRect") {
515
- const r = t.coordinates;
516
- this.ctx.translate(this.toScreenCoords(r.x, r.y).x, this.toScreenCoords(r.x, r.y).y), this.ctx.rotate(r.angle * Math.PI / 180);
517
- const a = r.width * this.scale, d = r.height * this.scale;
518
- this.ctx.strokeRect(-a / 2, -d / 2, a, d), this.ctx.fillStyle = i ? "rgba(0, 229, 255, 0.2)" : "rgba(255, 64, 129, 0.2)", this.ctx.fillRect(-a / 2, -d / 2, a, d), this.ctx.rotate(-r.angle * Math.PI / 180), this.ctx.translate(-this.toScreenCoords(r.x, r.y).x, -this.toScreenCoords(r.x, r.y).y), i && this.drawHandles(this.getAnnotationHandles(t));
519
- } else t.type === "point" && t.coordinates.points.forEach((a) => {
520
- const d = this.toScreenCoords(a.x, a.y);
521
- this.ctx.beginPath(), this.ctx.arc(d.x, d.y, 5, 0, Math.PI * 2), this.ctx.fillStyle = i ? "#00E5FF" : e, this.ctx.fill(), this.ctx.stroke();
521
+ const a = t.coordinates;
522
+ this.ctx.translate(this.toScreenCoords(a.x, a.y).x, this.toScreenCoords(a.x, a.y).y), this.ctx.rotate(a.angle * Math.PI / 180);
523
+ const g = a.width * this.scale, u = a.height * this.scale;
524
+ this.ctx.strokeRect(-g / 2, -u / 2, g, u), this.ctx.rotate(-a.angle * Math.PI / 180), this.ctx.translate(-this.toScreenCoords(a.x, a.y).x, -this.toScreenCoords(a.x, a.y).y), n && this.drawHandles(this.getAnnotationHandles(t));
525
+ } else t.type === "point" && t.coordinates.points.forEach((g) => {
526
+ const u = this.toScreenCoords(g.x, g.y);
527
+ this.ctx.beginPath(), this.ctx.arc(u.x, u.y, 5, 0, Math.PI * 2), this.ctx.fillStyle = n ? "#00E5FF" : e, this.ctx.fill(), this.ctx.stroke();
522
528
  });
523
529
  this.ctx.restore();
524
530
  }
525
531
  drawHandles(t) {
526
- this.ctx.fillStyle = "#FFFFFF", this.ctx.strokeStyle = "#000000", this.ctx.lineWidth = 1, t.forEach((i) => {
527
- const e = this.toScreenCoords(i.x, i.y);
532
+ this.ctx.fillStyle = "#FFFFFF", this.ctx.strokeStyle = "#000000", this.ctx.lineWidth = 1, t.forEach((n) => {
533
+ const e = this.toScreenCoords(n.x, n.y);
528
534
  this.ctx.fillRect(e.x - 4, e.y - 4, 8, 8), this.ctx.strokeRect(e.x - 4, e.y - 4, 8, 8);
529
535
  });
530
536
  }
531
537
  }
532
- const Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
533
- <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
534
- </svg>`, te = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
535
- <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
536
- </svg>`, ee = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
537
- <path d="M704 192h160v160h-160z m-64-64v288h288V128H640zM160 672h160v160H160z m-64-64v288h288V608H96z m256-320h320v64H352z" fill="currentColor"/>\r
538
- </svg>`, ne = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
539
- <path d="M256 256h512v512H256z m-64-64v640h640V192H192z" fill="currentColor"/>\r
540
- </svg>`, se = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
541
- <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
542
- </svg>`, ie = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
543
- <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
544
- </svg>`, oe = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
545
- <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
546
- </svg>`, ae = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
547
- <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
548
- </svg>`, le = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
549
- <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
550
- </svg>`, re = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
551
- <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
552
- </svg>`, ce = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
553
- <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
554
- </svg>`, he = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
555
- <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
556
- </svg>`, de = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
557
- <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
558
- </svg>`, ge = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
559
- <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
560
- </svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
561
- <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
562
- </svg>`, ve = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
563
- <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
564
- </svg>`, me = ["innerHTML"], fe = /* @__PURE__ */ tt({
538
+ const de = '<?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>', ge = '<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>', ue = '<?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>', ve = '<?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>', fe = '<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>', me = '<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>', pe = '<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>', ye = '<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>', we = '<?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>', xe = '<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>', be = '<?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>', _e = '<?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>', Ce = '<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>', ke = '<?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>', Ie = '<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>', Ae = '<?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>', Se = '<?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>', Me = '<?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>', Te = ["innerHTML"], De = /* @__PURE__ */ ct({
565
539
  __name: "SvgIcon",
566
540
  props: {
567
541
  name: {},
568
542
  size: {}
569
543
  },
570
- setup(f) {
571
- const t = f, i = M(""), e = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": Qt, "../assets/svg/back.svg": te, "../assets/svg/connection.svg": ee, "../assets/svg/crop.svg": ne, "../assets/svg/delete.svg": se, "../assets/svg/download.svg": ie, "../assets/svg/edit.svg": oe, "../assets/svg/hide.svg": ae, "../assets/svg/pointer.svg": le, "../assets/svg/price-tag.svg": re, "../assets/svg/rank.svg": ce, "../assets/svg/refresh-right.svg": he, "../assets/svg/right.svg": de, "../assets/svg/view.svg": ge, "../assets/svg/zoom-in.svg": ue, "../assets/svg/zoom-out.svg": ve });
572
- return Yt(() => {
573
- const o = `../assets/svg/${t.name}.svg`, c = e[o];
574
- c ? i.value = c : (console.warn(`Icon ${t.name} not found at path ${o}`), i.value = "");
575
- }), (o, c) => (y(), x("i", {
576
- class: J(["svg-icon", [f.size ? `size-${f.size}` : ""]]),
577
- innerHTML: i.value
578
- }, null, 10, me));
544
+ setup(w) {
545
+ const t = w, n = M(""), e = /* @__PURE__ */ Object.assign({ "../assets/svg/aim.svg": de, "../assets/svg/back.svg": ge, "../assets/svg/connection.svg": ue, "../assets/svg/crop.svg": ve, "../assets/svg/delete.svg": fe, "../assets/svg/download.svg": me, "../assets/svg/edit.svg": pe, "../assets/svg/first.svg": ye, "../assets/svg/hide.svg": we, "../assets/svg/last.svg": xe, "../assets/svg/pointer.svg": be, "../assets/svg/price-tag.svg": _e, "../assets/svg/rank.svg": Ce, "../assets/svg/refresh-right.svg": ke, "../assets/svg/right.svg": Ie, "../assets/svg/view.svg": Ae, "../assets/svg/zoom-in.svg": Se, "../assets/svg/zoom-out.svg": Me });
546
+ return ce(() => {
547
+ const c = `../assets/svg/${t.name}.svg`, l = e[c];
548
+ l ? n.value = l : (console.warn(`Icon ${t.name} not found at path ${c}`), n.value = "");
549
+ }), (c, l) => (v(), m("i", {
550
+ class: q(["svg-icon", [w.size ? `size-${w.size}` : ""]]),
551
+ innerHTML: n.value
552
+ }, null, 10, Te));
579
553
  }
580
- }), et = (f, t) => {
581
- const i = f.__vccOpts || f;
582
- for (const [e, o] of t)
583
- i[e] = o;
584
- return i;
585
- }, H = /* @__PURE__ */ et(fe, [["__scopeId", "data-v-3928607b"]]), ye = {
554
+ }), rt = (w, t) => {
555
+ const n = w.__vccOpts || w;
556
+ for (const [e, c] of t)
557
+ n[e] = c;
558
+ return n;
559
+ }, L = /* @__PURE__ */ rt(De, [["__scopeId", "data-v-3928607b"]]), ze = {
586
560
  key: 0,
587
561
  class: "image-list-sidebar"
588
- }, pe = { class: "image-list-title" }, xe = { class: "image-list-scroll" }, be = ["onClick"], we = { class: "image-list-stage" }, Ce = ["src", "alt"], Ae = {
562
+ }, Pe = { class: "image-list-header" }, $e = ["onClick"], Le = { class: "image-list-stage" }, Re = ["src", "alt"], Be = {
589
563
  key: 0,
590
564
  class: "thumb-overlay-layer"
591
- }, _e = {
565
+ }, He = {
592
566
  key: 1,
593
567
  class: "thumb-overlay-svg",
594
568
  viewBox: "0 0 100 100",
595
569
  preserveAspectRatio: "none"
596
- }, Ie = ["points"], ke = { class: "image-list-text" }, Se = {
597
- key: 1,
570
+ }, Ue = ["points"], Ee = { class: "image-list-text" }, Ve = { class: "center-sidebar" }, Oe = {
571
+ key: 0,
598
572
  class: "left-sidebar"
599
- }, Me = ["onClick", "title"], ze = { class: "center-area" }, $e = {
573
+ }, Fe = ["onClick", "title"], Ne = {
574
+ key: 0,
575
+ class: "divider"
576
+ }, We = { class: "center-area" }, Ge = {
600
577
  key: 0,
601
- class: "top-bar"
602
- }, Te = { class: "label-selector" }, Pe = { class: "tags-row" }, He = ["onClick"], Le = {
578
+ class: "floating-label-selector"
579
+ }, Je = {
603
580
  key: 0,
604
- class: "no-labels"
605
- }, Re = {
581
+ class: "current-label"
582
+ }, Ye = { class: "label-name" }, je = {
606
583
  key: 1,
584
+ class: "current-label empty"
585
+ }, Xe = {
586
+ key: 0,
587
+ class: "selector-dropdown"
588
+ }, qe = {
589
+ key: 0,
590
+ class: "dropdown-empty"
591
+ }, Ke = ["onClick"], Ze = { class: "label-name" }, Qe = {
592
+ key: 0,
607
593
  class: "batch-nav"
608
- }, Be = ["disabled"], De = ["disabled"], Ue = {
609
- key: 2,
594
+ }, ts = ["disabled"], es = ["disabled"], ss = ["disabled"], is = ["disabled"], ns = {
595
+ key: 1,
610
596
  class: "right-sidebar"
611
- }, Fe = { class: "label-list" }, Oe = { class: "label-row" }, Ee = ["onUpdate:modelValue", "onChange"], Ve = ["title"], Ne = ["onClick"], We = { class: "action-icon more-actions" }, Je = ["onClick"], je = {
612
- key: 3,
613
- class: "modal-overlay"
614
- }, Ye = { class: "modal-content" }, Xe = { class: "form-group" }, qe = { class: "form-group" }, Ge = { class: "color-input-wrapper" }, Ke = /* @__PURE__ */ tt({
597
+ }, os = { class: "label-list" }, as = { class: "label-row" }, ls = ["onUpdate:modelValue", "onChange"], cs = ["title"], rs = ["onClick"], hs = { class: "action-icon more-actions" }, ds = ["onClick"], gs = { class: "modal-content" }, us = { class: "modal-body" }, vs = { class: "form-group" }, fs = { class: "form-group" }, ms = { class: "color-input-wrapper" }, ps = { class: "color-value" }, ys = { class: "modal-actions" }, ws = ["disabled"], xs = /* @__PURE__ */ ct({
615
598
  __name: "ImageAnnotator",
616
599
  props: {
617
- annotationTypes: { default: () => ["rectangle", "polygon", "point", "rotatedRect"] },
600
+ annotationTypes: { default: () => ["rectangle", "polygon", "point", "rotatedRect", "category"] },
618
601
  batchImages: { default: () => [] },
619
602
  labels: { default: () => [] },
620
603
  defaultActiveType: {},
@@ -628,581 +611,691 @@ const Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
628
611
  maxZoom: {}
629
612
  },
630
613
  emits: ["annotationChange", "batchChange", "labelChange", "ready", "error", "tool:change", "viewport:change", "annotation:add", "annotation:update", "annotation:delete", "annotation:select", "prediction:loaded", "prediction:apply", "prediction:reject"],
631
- setup(f, { expose: t, emit: i }) {
632
- const e = f, o = i, c = M(null), r = M(null), a = M(null), d = M(null), u = M(0), w = M(""), m = M([]), _ = M(""), U = M(!1), k = M({ name: "", color: "#FF0000" }), I = M("none"), C = M([]), R = M({}), N = D(() => d.value === "select" && !!w.value), j = (n) => {
633
- if (!n || R.value[n]) return;
634
- const s = new Image();
635
- s.onload = () => {
636
- const l = s.naturalWidth || 1, h = s.naturalHeight || 1;
637
- R.value = {
638
- ...R.value,
639
- [n]: { width: l, height: h }
614
+ setup(w, { expose: t, emit: n }) {
615
+ const e = w, c = n, l = M(null), a = M(null), g = M(null), u = M([]), r = M(null), A = M(null), x = M(0), D = M(""), C = M([]), $ = M(""), X = M(!1), _ = M({ name: "", color: "#FF0000" }), S = M("none"), p = M([]), B = M({}), O = V(() => A.value === "select" && !!D.value), G = M(!1), Z = V(() => C.value.find((s) => s.id === $.value)), yt = (s) => {
616
+ s.stopPropagation(), G.value = !G.value;
617
+ }, wt = (s) => {
618
+ tt(s), G.value = !1;
619
+ };
620
+ kt(() => {
621
+ document.addEventListener("click", (s) => {
622
+ s.target.closest(".floating-label-selector") || (G.value = !1);
623
+ });
624
+ });
625
+ const it = (s) => {
626
+ if (!s || B.value[s]) return;
627
+ const i = new Image();
628
+ i.onload = () => {
629
+ const o = i.naturalWidth || 1, d = i.naturalHeight || 1;
630
+ B.value = {
631
+ ...B.value,
632
+ [s]: { width: o, height: d }
640
633
  };
641
- }, s.src = n;
642
- }, X = () => {
643
- e.batchImages.forEach((n) => {
644
- j(n.imageUrl);
634
+ }, i.src = s;
635
+ }, nt = () => {
636
+ e.batchImages.forEach((s) => {
637
+ it(s.imageUrl);
638
+ });
639
+ }, ht = (s, i) => {
640
+ u.value[i] = s;
641
+ }, Q = (s = x.value) => {
642
+ const i = g.value, o = u.value[s];
643
+ if (!i || !o) return;
644
+ const d = i.scrollTop, f = d + i.clientHeight, I = o.offsetTop, z = I + o.offsetHeight;
645
+ if (I < d) {
646
+ i.scrollTo({
647
+ top: Math.max(I - 8, 0),
648
+ behavior: "smooth"
649
+ });
650
+ return;
651
+ }
652
+ z > f && i.scrollTo({
653
+ top: z - i.clientHeight + 8,
654
+ behavior: "smooth"
645
655
  });
646
- }, O = () => {
647
- var l, h, v, A;
648
- const n = e.batchImages[u.value], s = (n == null ? void 0 : n.imageUrl) || ((l = e.image) == null ? void 0 : l.url);
656
+ }, Y = () => {
657
+ var o, d, f, I;
658
+ const s = e.batchImages[x.value], i = (s == null ? void 0 : s.imageUrl) || ((o = e.image) == null ? void 0 : o.url);
649
659
  return {
650
660
  eventId: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
651
661
  timestamp: Date.now(),
652
662
  requestId: e.requestId,
653
- taskId: (h = e.session) == null ? void 0 : h.taskId,
654
- imageId: ((v = e.image) == null ? void 0 : v.id) || s,
655
- operator: (A = e.session) == null ? void 0 : A.userId
663
+ taskId: (d = e.session) == null ? void 0 : d.taskId,
664
+ imageId: ((f = e.image) == null ? void 0 : f.id) || i,
665
+ operator: (I = e.session) == null ? void 0 : I.userId
656
666
  };
657
- }, ht = (n) => {
658
- var h;
659
- const s = n == null ? void 0 : n.action;
660
- if (!s) return;
661
- const l = {
662
- meta: O(),
663
- action: s,
664
- current: n == null ? void 0 : n.changedItem,
665
- source: (h = n == null ? void 0 : n.changedItem) != null && h.predictionId ? "prediction" : "manual"
667
+ }, y = (s) => {
668
+ var d;
669
+ const i = s == null ? void 0 : s.action;
670
+ if (!i) return;
671
+ const o = {
672
+ meta: Y(),
673
+ action: i,
674
+ current: s == null ? void 0 : s.changedItem,
675
+ source: (d = s == null ? void 0 : s.changedItem) != null && d.predictionId ? "prediction" : "manual"
666
676
  };
667
- s === "add" && o("annotation:add", l), s === "update" && o("annotation:update", l), s === "delete" && o("annotation:delete", l), s === "select" && o("annotation:select", l);
668
- }, nt = D(() => e.annotationTypes.filter((n) => n !== "category")), st = (n) => ({
677
+ i === "add" && c("annotation:add", o), i === "update" && c("annotation:update", o), i === "delete" && c("annotation:delete", o), i === "select" && c("annotation:select", o);
678
+ }, b = V(() => e.annotationTypes), k = (s) => ({
669
679
  rectangle: "crop",
670
680
  polygon: "connection",
671
681
  point: "aim",
672
682
  rotatedRect: "refresh-right",
673
683
  category: "price-tag"
674
- })[n] || n, it = (n) => ({
684
+ })[s] || s, F = (s) => ({
675
685
  rectangle: "矩形框",
676
686
  polygon: "多边形",
677
687
  point: "关键点",
678
688
  rotatedRect: "旋转矩形",
679
689
  category: "分类标签"
680
- })[n] || n;
681
- Xt(() => {
682
- if (X(), c.value) {
683
- a.value = new Zt(c.value), a.value.on("annotationChange", (s) => {
684
- var l, h;
685
- if (s.action === "add" && s.changedItem) {
686
- const v = m.value.find((A) => A.id === _.value);
687
- v && (s.changedItem.label = v.name, s.changedItem.labelId = v.id);
690
+ })[s] || s;
691
+ kt(() => {
692
+ if (nt(), l.value) {
693
+ r.value = new he(l.value), r.value.on("annotationChange", (i) => {
694
+ var o, d;
695
+ if (i.action === "add" && i.changedItem) {
696
+ const f = C.value.find((I) => I.id === $.value);
697
+ f && (i.changedItem.label = f.name, i.changedItem.labelId = f.id);
688
698
  }
689
- s.action === "select" ? w.value = ((l = s.changedItem) == null ? void 0 : l.id) || "" : s.action === "delete" && ((h = s.changedItem) == null ? void 0 : h.id) === w.value && (w.value = ""), o("annotationChange", s), ht(s);
690
- }), W(), E();
691
- const n = new ResizeObserver(() => {
692
- var s;
693
- (s = a.value) == null || s.resize();
699
+ i.action === "select" ? D.value = ((o = i.changedItem) == null ? void 0 : o.id) || "" : i.action === "delete" && ((d = i.changedItem) == null ? void 0 : d.id) === D.value && (D.value = ""), c("annotationChange", i), y(i);
700
+ }), W(), U();
701
+ const s = new ResizeObserver(() => {
702
+ var i;
703
+ (i = r.value) == null || i.resize();
694
704
  });
695
- r.value && n.observe(r.value), e.defaultActiveType && p(e.defaultActiveType), o("ready", { meta: O() });
705
+ a.value && s.observe(a.value), e.defaultActiveType && j(e.defaultActiveType), at(() => Q()), c("ready", { meta: Y() });
696
706
  }
697
707
  });
698
- const E = () => {
699
- if (!a.value) return;
700
- const n = m.value.find((l) => l.id === _.value);
701
- n && a.value.setLabelStyle(n.color);
702
- const s = m.value.filter((l) => l.visible).map((l) => l.name);
703
- a.value.setVisibleLabels(s);
708
+ const U = () => {
709
+ if (!r.value) return;
710
+ const s = C.value.find((o) => o.id === $.value);
711
+ s && r.value.setLabelStyle(s.color);
712
+ const i = C.value.filter((o) => o.visible).map((o) => o.name);
713
+ r.value.setVisibleLabels(i);
704
714
  }, W = () => {
705
- var n;
706
- if (a.value)
707
- if (w.value = "", requestAnimationFrame(() => {
708
- var s;
709
- (s = a.value) == null || s.resize();
715
+ var s;
716
+ if (r.value)
717
+ if (D.value = "", requestAnimationFrame(() => {
718
+ var i;
719
+ (i = r.value) == null || i.resize();
710
720
  }), e.batchImages.length > 0) {
711
- const s = e.batchImages[u.value];
712
- a.value.loadImage(s.imageUrl), s.annotations ? a.value.setAnnotations(s.annotations) : a.value.setAnnotations([]);
713
- } else (n = e.image) != null && n.url && a.value.loadImage(e.image.url);
714
- }, p = (n) => {
715
- var s, l;
716
- if (d.value = n, w.value = "", n !== "pan" && n !== "select" && m.value.length === 0) {
721
+ const i = e.batchImages[x.value];
722
+ r.value.loadImage(i.imageUrl), i.annotations ? r.value.setAnnotations(i.annotations) : r.value.setAnnotations([]);
723
+ } else (s = e.image) != null && s.url && r.value.loadImage(e.image.url);
724
+ }, j = (s) => {
725
+ var i, o;
726
+ if (A.value = s, D.value = "", s !== "pan" && s !== "select" && C.value.length === 0) {
717
727
  alert("请先创建标签!");
718
728
  return;
719
729
  }
720
- n === "pan" || n === "select" ? (s = a.value) == null || s.setTool(n) : (l = a.value) == null || l.setTool(n), o("tool:change", { meta: O(), tool: n });
721
- }, b = () => {
722
- var n;
723
- (n = a.value) != null && n.activeAnnotation && a.value.deleteAnnotation(a.value.activeAnnotation.id);
724
- }, z = () => {
725
- a.value && o("viewport:change", {
726
- meta: O(),
727
- scale: a.value.scale,
728
- offset: { ...a.value.offset }
730
+ s === "pan" || s === "select" ? (i = r.value) == null || i.setTool(s) : (o = r.value) == null || o.setTool(s), c("tool:change", { meta: Y(), tool: s });
731
+ }, St = () => {
732
+ var s;
733
+ (s = r.value) != null && s.activeAnnotation && r.value.deleteAnnotation(r.value.activeAnnotation.id);
734
+ }, xt = () => {
735
+ r.value && c("viewport:change", {
736
+ meta: Y(),
737
+ scale: r.value.scale,
738
+ offset: { ...r.value.offset }
729
739
  });
730
- }, q = () => {
731
- var n;
732
- (n = a.value) == null || n.zoom(1), z();
740
+ }, Mt = () => {
741
+ var s;
742
+ (s = r.value) == null || s.zoom(1), xt();
743
+ }, Tt = () => {
744
+ var s;
745
+ (s = r.value) == null || s.zoom(-1), xt();
746
+ }, Dt = () => {
747
+ _.value = { name: "", color: "#2196F3" }, X.value = !0;
733
748
  }, dt = () => {
734
- var n;
735
- (n = a.value) == null || n.zoom(-1), z();
736
- }, xt = () => {
737
- k.value = { name: "", color: "#2196F3" }, U.value = !0;
738
- }, gt = () => {
739
- U.value = !1;
740
- }, bt = () => {
741
- if (!k.value.name.trim()) {
749
+ X.value = !1;
750
+ }, zt = () => {
751
+ if (!_.value.name.trim()) {
742
752
  alert("请输入标签名称");
743
753
  return;
744
754
  }
745
- const s = {
755
+ const i = {
746
756
  id: Date.now().toString(),
747
- name: k.value.name,
748
- color: k.value.color,
757
+ name: _.value.name,
758
+ color: _.value.color,
749
759
  visible: !0
750
760
  };
751
- m.value.push(s), o("labelChange", m.value), E(), m.value.length === 1 && G(s), gt();
752
- }, G = (n) => {
753
- var s;
754
- _.value = n.id, (s = a.value) == null || s.setLabelStyle(n.color);
755
- }, wt = (n, s) => {
756
- if (!n.startsWith("#")) return n;
757
- let l = 0, h = 0, v = 0;
758
- return n.length === 4 ? (l = parseInt(n[1] + n[1], 16), h = parseInt(n[2] + n[2], 16), v = parseInt(n[3] + n[3], 16)) : n.length === 7 && (l = parseInt(n.slice(1, 3), 16), h = parseInt(n.slice(3, 5), 16), v = parseInt(n.slice(5, 7), 16)), `rgba(${l}, ${h}, ${v}, ${s})`;
759
- }, Ct = (n) => {
760
- var s;
761
- if (n.id === _.value && ((s = a.value) == null || s.setLabelStyle(n.color)), a.value) {
762
- const l = a.value.getAnnotations();
763
- let h = !1;
764
- l.forEach((v) => {
765
- v.label === n.name && (v.style || (v.style = {}), v.style.strokeColor = n.color, v.style.fillColor = wt(n.color, 0.2), h = !0);
766
- }), h && a.value.render();
761
+ C.value.push(i), c("labelChange", C.value), U(), C.value.length === 1 && tt(i), dt();
762
+ }, tt = (s) => {
763
+ var i;
764
+ $.value = s.id, (i = r.value) == null || i.setLabelStyle(s.color);
765
+ }, Pt = (s, i) => {
766
+ if (!s.startsWith("#")) return s;
767
+ let o = 0, d = 0, f = 0;
768
+ return s.length === 4 ? (o = parseInt(s[1] + s[1], 16), d = parseInt(s[2] + s[2], 16), f = parseInt(s[3] + s[3], 16)) : s.length === 7 && (o = parseInt(s.slice(1, 3), 16), d = parseInt(s.slice(3, 5), 16), f = parseInt(s.slice(5, 7), 16)), `rgba(${o}, ${d}, ${f}, ${i})`;
769
+ }, $t = (s) => {
770
+ var i;
771
+ if (s.id === $.value && ((i = r.value) == null || i.setLabelStyle(s.color)), r.value) {
772
+ const o = r.value.getAnnotations();
773
+ let d = !1;
774
+ o.forEach((f) => {
775
+ f.label === s.name && (f.style || (f.style = {}), f.style.strokeColor = s.color, f.style.fillColor = Pt(s.color, 0.2), d = !0);
776
+ }), d && r.value.render();
767
777
  }
768
- o("labelChange", m.value), E();
769
- }, At = (n) => {
770
- n.visible = !n.visible, E();
771
- }, _t = (n) => {
772
- const s = m.value.findIndex((l) => l.id === n);
773
- s > -1 && (m.value.splice(s, 1), o("labelChange", m.value), _.value === n && (_.value = m.value.length > 0 ? m.value[0].id : "", _.value && G(m.value[0])), E());
778
+ c("labelChange", C.value), U();
779
+ }, Lt = (s) => {
780
+ s.visible = !s.visible, U();
781
+ }, Rt = (s) => {
782
+ const i = C.value.findIndex((o) => o.id === s);
783
+ i > -1 && (C.value.splice(i, 1), c("labelChange", C.value), $.value === s && ($.value = C.value.length > 0 ? C.value[0].id : "", $.value && tt(C.value[0])), U());
774
784
  };
775
- Y(() => e.labels, (n) => {
776
- const s = JSON.parse(JSON.stringify(n || []));
777
- if (m.value = s, m.value.length > 0)
778
- if (!_.value || !m.value.find((l) => l.id === _.value))
779
- G(m.value[0]);
785
+ K(() => e.labels, (s) => {
786
+ const i = JSON.parse(JSON.stringify(s || []));
787
+ if (C.value = i, C.value.length > 0)
788
+ if (!$.value || !C.value.find((o) => o.id === $.value))
789
+ tt(C.value[0]);
780
790
  else {
781
- const l = m.value.find((h) => h.id === _.value);
782
- l && G(l);
791
+ const o = C.value.find((d) => d.id === $.value);
792
+ o && tt(o);
783
793
  }
784
794
  else
785
- _.value = "";
786
- E();
795
+ $.value = "";
796
+ U();
787
797
  }, { immediate: !0, deep: !0 });
788
- const It = () => {
789
- u.value > 0 && (ot(), u.value--, W(), at());
790
- }, kt = () => {
791
- u.value < e.batchImages.length - 1 && (ot(), u.value++, W(), at());
792
- }, ot = () => {
793
- if (a.value) {
794
- const n = a.value.getAnnotations();
795
- e.batchImages[u.value].annotations = n;
798
+ const Bt = () => {
799
+ x.value > 0 && (gt(), x.value--, W(), ut());
800
+ }, Ht = () => {
801
+ x.value < e.batchImages.length - 1 && (gt(), x.value++, W(), ut());
802
+ }, Ut = () => {
803
+ x.value > 0 && ot(0);
804
+ }, Et = () => {
805
+ x.value < e.batchImages.length - 1 && ot(e.batchImages.length - 1);
806
+ }, gt = () => {
807
+ if (r.value) {
808
+ const s = r.value.getAnnotations();
809
+ e.batchImages[x.value].annotations = s;
796
810
  }
797
- }, at = () => {
798
- const n = e.batchImages[u.value];
799
- o("batchChange", {
800
- currentIndex: u.value,
811
+ }, ut = () => {
812
+ const s = e.batchImages[x.value];
813
+ c("batchChange", {
814
+ currentIndex: x.value,
801
815
  total: e.batchImages.length,
802
- currentImageUrl: n.imageUrl,
803
- currentAnnotations: n.annotations || []
816
+ currentImageUrl: s.imageUrl,
817
+ currentAnnotations: s.annotations || []
804
818
  });
805
- }, ut = (n = []) => {
806
- var v;
807
- if (!a.value) return;
808
- if (C.value = JSON.parse(JSON.stringify(n)), C.value.length === 0) {
809
- I.value = "none";
819
+ }, bt = (s = []) => {
820
+ var f;
821
+ if (!r.value) return;
822
+ if (p.value = JSON.parse(JSON.stringify(s)), p.value.length === 0) {
823
+ S.value = "none";
810
824
  return;
811
825
  }
812
- I.value = "loaded";
813
- const l = (a.value.getAnnotations() || []).filter((A) => !A.predictionId), h = C.value.map((A) => {
814
- const $ = JSON.parse(JSON.stringify(A.annotation));
815
- return $.id = $.id || `pred-${A.id}`, $.predictionId = A.id, $.modelRunId = A.modelRunId || $.modelRunId, $.confidence = A.confidence ?? $.confidence, $.reviewStatus = $.reviewStatus || "draft", $;
826
+ S.value = "loaded";
827
+ const o = (r.value.getAnnotations() || []).filter((I) => !I.predictionId), d = p.value.map((I) => {
828
+ const z = JSON.parse(JSON.stringify(I.annotation));
829
+ return z.id = z.id || `pred-${I.id}`, z.predictionId = I.id, z.modelRunId = I.modelRunId || z.modelRunId, z.confidence = I.confidence ?? z.confidence, z.reviewStatus = z.reviewStatus || "draft", z;
816
830
  });
817
- a.value.setAnnotations([...l, ...h]), o("prediction:loaded", {
818
- meta: O(),
819
- modelRunId: (v = C.value[0]) == null ? void 0 : v.modelRunId,
820
- candidates: C.value
831
+ r.value.setAnnotations([...o, ...d]), c("prediction:loaded", {
832
+ meta: Y(),
833
+ modelRunId: (f = p.value[0]) == null ? void 0 : f.modelRunId,
834
+ candidates: p.value
821
835
  });
822
- }, St = (n, s) => {
823
- var v;
824
- if (!a.value) return [];
825
- I.value = "applying";
826
- const h = (a.value.getAnnotations() || []).filter((A) => A.predictionId && n.includes(A.predictionId));
827
- return h.forEach((A) => {
828
- A.reviewStatus = "accepted";
829
- }), I.value = "applied", o("prediction:apply", {
830
- meta: O(),
831
- modelRunId: (v = h[0]) == null ? void 0 : v.modelRunId,
832
- candidateIds: n,
833
- threshold: s,
834
- acceptedAnnotations: h
835
- }), a.value.render(), h;
836
- }, Mt = (n, s) => {
837
- var v;
838
- if (!a.value) return;
839
- const l = a.value.getAnnotations() || [], h = l.filter((A) => !(A.predictionId && n.includes(A.predictionId)));
840
- a.value.setAnnotations(h), o("prediction:reject", {
841
- meta: O(),
842
- modelRunId: (v = l.find((A) => A.predictionId && n.includes(A.predictionId))) == null ? void 0 : v.modelRunId,
843
- candidateIds: n,
844
- reason: s
836
+ }, Vt = (s, i) => {
837
+ var f;
838
+ if (!r.value) return [];
839
+ S.value = "applying";
840
+ const d = (r.value.getAnnotations() || []).filter((I) => I.predictionId && s.includes(I.predictionId));
841
+ return d.forEach((I) => {
842
+ I.reviewStatus = "accepted";
843
+ }), S.value = "applied", c("prediction:apply", {
844
+ meta: Y(),
845
+ modelRunId: (f = d[0]) == null ? void 0 : f.modelRunId,
846
+ candidateIds: s,
847
+ threshold: i,
848
+ acceptedAnnotations: d
849
+ }), r.value.render(), d;
850
+ }, Ot = (s, i) => {
851
+ var f;
852
+ if (!r.value) return;
853
+ const o = r.value.getAnnotations() || [], d = o.filter((I) => !(I.predictionId && s.includes(I.predictionId)));
854
+ r.value.setAnnotations(d), c("prediction:reject", {
855
+ meta: Y(),
856
+ modelRunId: (f = o.find((I) => I.predictionId && s.includes(I.predictionId))) == null ? void 0 : f.modelRunId,
857
+ candidateIds: s,
858
+ reason: i
845
859
  });
846
- }, zt = (n, s = []) => {
847
- a.value && (a.value.loadImage(n.url), a.value.setAnnotations(s));
848
- }, $t = (n) => {
860
+ }, Ft = (s, i = []) => {
861
+ r.value && (r.value.loadImage(s.url), r.value.setAnnotations(i));
862
+ }, Nt = (s) => {
863
+ var i;
864
+ (i = r.value) == null || i.setAnnotations(s);
865
+ }, _t = () => {
849
866
  var s;
850
- (s = a.value) == null || s.setAnnotations(n);
851
- }, vt = () => {
852
- var n;
853
- return ((n = a.value) == null ? void 0 : n.getAnnotations()) || [];
854
- }, Tt = (n = "json") => {
855
- var l, h;
856
- const s = vt();
867
+ return ((s = r.value) == null ? void 0 : s.getAnnotations()) || [];
868
+ }, Wt = (s = "json") => {
869
+ var o, d;
870
+ const i = _t();
857
871
  return {
858
- format: n,
859
- image: ((l = e.batchImages[u.value]) == null ? void 0 : l.imageUrl) || ((h = e.image) == null ? void 0 : h.url) || "",
860
- annotations: s
872
+ format: s,
873
+ image: ((o = e.batchImages[x.value]) == null ? void 0 : o.imageUrl) || ((d = e.image) == null ? void 0 : d.url) || "",
874
+ annotations: i
861
875
  };
862
- }, mt = (n) => {
863
- n >= 0 && n < e.batchImages.length && (ot(), u.value = n, W(), at());
864
- }, Pt = (n) => {
865
- var s;
866
- return n === u.value && a.value ? a.value.getAnnotations() || [] : ((s = e.batchImages[n]) == null ? void 0 : s.annotations) || [];
867
- }, Ht = (n) => n.type === "rectangle", Lt = (n) => n.type === "polygon", Rt = (n) => n.type === "point", Bt = (n) => n.type === "rotatedRect", Z = (n) => {
868
- var l, h;
869
- const s = (l = m.value.find((v) => v.name === n.label)) == null ? void 0 : l.color;
870
- return ((h = n.style) == null ? void 0 : h.strokeColor) || s || "#409eff";
871
- }, ft = (n) => {
872
- const s = n.coordinates;
873
- return (s == null ? void 0 : s.points) || [];
874
- }, Q = (n) => {
875
- const s = e.batchImages[n];
876
- if (s != null && s.width && (s != null && s.height))
877
- return { width: s.width, height: s.height };
878
- const l = s != null && s.imageUrl ? R.value[s.imageUrl] : void 0;
879
- return l || (s != null && s.imageUrl && j(s.imageUrl), { width: 1, height: 1 });
880
- }, Dt = (n) => {
881
- const s = e.batchImages[n];
882
- return s != null && s.width && (s != null && s.height) ? !0 : s != null && s.imageUrl ? !!R.value[s.imageUrl] : !1;
883
- }, Ut = (n, s) => {
884
- const l = s.coordinates, h = Q(n), v = Z(s), A = Math.min(l.x1, l.x2), $ = Math.min(l.y1, l.y2), Nt = Math.max(l.x1, l.x2), Wt = Math.max(l.y1, l.y2);
876
+ }, ot = (s) => {
877
+ s >= 0 && s < e.batchImages.length && (gt(), x.value = s, W(), ut());
878
+ }, Gt = (s) => {
879
+ var i;
880
+ return s === x.value && r.value ? r.value.getAnnotations() || [] : ((i = e.batchImages[s]) == null ? void 0 : i.annotations) || [];
881
+ }, Jt = (s) => s.type === "rectangle", Yt = (s) => s.type === "polygon", jt = (s) => s.type === "point", Xt = (s) => s.type === "rotatedRect", qt = (s) => s.type === "category", et = (s) => {
882
+ var o, d;
883
+ const i = (o = C.value.find((f) => f.name === s.label)) == null ? void 0 : o.color;
884
+ return ((d = s.style) == null ? void 0 : d.strokeColor) || i || "#409eff";
885
+ }, Ct = (s) => {
886
+ const i = s.coordinates;
887
+ return (i == null ? void 0 : i.points) || [];
888
+ }, st = (s) => {
889
+ const i = e.batchImages[s];
890
+ if (i != null && i.width && (i != null && i.height))
891
+ return { width: i.width, height: i.height };
892
+ const o = i != null && i.imageUrl ? B.value[i.imageUrl] : void 0;
893
+ return o || (i != null && i.imageUrl && it(i.imageUrl), { width: 1, height: 1 });
894
+ }, Kt = (s) => {
895
+ const i = e.batchImages[s];
896
+ return i != null && i.width && (i != null && i.height) ? !0 : i != null && i.imageUrl ? !!B.value[i.imageUrl] : !1;
897
+ }, Zt = (s, i) => {
898
+ const o = i.coordinates, d = st(s), f = et(i), I = Math.min(o.x1, o.x2), z = Math.min(o.y1, o.y2), ne = Math.max(o.x1, o.x2), oe = Math.max(o.y1, o.y2);
885
899
  return {
886
- left: `${A / h.width * 100}%`,
887
- top: `${$ / h.height * 100}%`,
888
- width: `${(Nt - A) / h.width * 100}%`,
889
- height: `${(Wt - $) / h.height * 100}%`,
890
- borderColor: v,
891
- backgroundColor: `${v}22`
900
+ left: `${I / d.width * 100}%`,
901
+ top: `${z / d.height * 100}%`,
902
+ width: `${(ne - I) / d.width * 100}%`,
903
+ height: `${(oe - z) / d.height * 100}%`,
904
+ borderColor: f,
905
+ backgroundColor: `${f}22`
892
906
  };
893
- }, Ft = (n, s) => {
894
- const l = Q(n);
895
- return ft(s).map((h) => `${h.x / l.width * 100},${h.y / l.height * 100}`).join(" ");
896
- }, Ot = (n) => {
897
- const s = Z(n);
907
+ }, Qt = (s, i) => {
908
+ const o = st(s);
909
+ return Ct(i).map((d) => `${d.x / o.width * 100},${d.y / o.height * 100}`).join(" ");
910
+ }, te = (s) => {
911
+ const i = et(s);
898
912
  return {
899
- fill: `${s}33`,
900
- stroke: s,
913
+ fill: `${i}33`,
914
+ stroke: i,
901
915
  strokeWidth: "1.4"
902
916
  };
903
- }, Et = (n, s, l) => {
904
- const h = Q(n), v = Z(l);
917
+ }, ee = (s, i, o) => {
918
+ const d = st(s), f = et(o);
905
919
  return {
906
- left: `${s.x / h.width * 100}%`,
907
- top: `${s.y / h.height * 100}%`,
908
- backgroundColor: v
920
+ left: `${i.x / d.width * 100}%`,
921
+ top: `${i.y / d.height * 100}%`,
922
+ backgroundColor: f
909
923
  };
910
- }, Vt = (n, s) => {
911
- const l = s.coordinates, h = Q(n), v = Z(s), A = Math.abs(l.width), $ = Math.abs(l.height);
924
+ }, se = (s, i) => {
925
+ const o = i.coordinates, d = st(s), f = et(i), I = Math.abs(o.width), z = Math.abs(o.height);
912
926
  return {
913
- left: `${(l.x - A / 2) / h.width * 100}%`,
914
- top: `${(l.y - $ / 2) / h.height * 100}%`,
915
- width: `${A / h.width * 100}%`,
916
- height: `${$ / h.height * 100}%`,
917
- transform: `rotate(${l.angle || 0}deg)`,
918
- borderColor: v,
919
- backgroundColor: `${v}22`
927
+ left: `${(o.x - I / 2) / d.width * 100}%`,
928
+ top: `${(o.y - z / 2) / d.height * 100}%`,
929
+ width: `${I / d.width * 100}%`,
930
+ height: `${z / d.height * 100}%`,
931
+ transform: `rotate(${o.angle || 0}deg)`,
932
+ borderColor: f,
933
+ backgroundColor: `${f}22`
934
+ };
935
+ }, ie = (s, i) => {
936
+ const o = i.coordinates, d = st(s), f = et(i);
937
+ return {
938
+ left: `${o.x / d.width * 100}%`,
939
+ top: `${o.y / d.height * 100}%`,
940
+ backgroundColor: `${f}d9`
941
+ // ~85% opacity
920
942
  };
921
943
  };
922
944
  return t({
923
- jumpTo: mt,
924
- setImage: zt,
925
- setAnnotations: $t,
926
- getAnnotations: vt,
927
- selectTool: p,
928
- loadPredictionCandidates: ut,
929
- applyPredictions: St,
930
- rejectPredictions: Mt,
931
- exportAnnotations: Tt,
945
+ jumpTo: ot,
946
+ setImage: Ft,
947
+ setAnnotations: Nt,
948
+ getAnnotations: _t,
949
+ selectTool: j,
950
+ loadPredictionCandidates: bt,
951
+ applyPredictions: Vt,
952
+ rejectPredictions: Ot,
953
+ exportAnnotations: Wt,
932
954
  getAllAnnotations: () => {
933
- var n, s;
955
+ var s, i;
934
956
  return e.batchImages.length > 0 ? e.batchImages : [{
935
- imageUrl: ((n = e.image) == null ? void 0 : n.url) || "",
936
- annotations: ((s = a.value) == null ? void 0 : s.getAnnotations()) || []
957
+ imageUrl: ((s = e.image) == null ? void 0 : s.url) || "",
958
+ annotations: ((i = r.value) == null ? void 0 : i.getAnnotations()) || []
937
959
  }];
938
960
  },
939
961
  getCurrentAnnotation: () => {
940
- var n, s, l;
962
+ var s, i, o;
941
963
  return {
942
- imageUrl: ((n = e.batchImages[u.value]) == null ? void 0 : n.imageUrl) || ((s = e.image) == null ? void 0 : s.url) || "",
943
- annotations: ((l = a.value) == null ? void 0 : l.getAnnotations()) || []
964
+ imageUrl: ((s = e.batchImages[x.value]) == null ? void 0 : s.imageUrl) || ((i = e.image) == null ? void 0 : i.url) || "",
965
+ annotations: ((o = r.value) == null ? void 0 : o.getAnnotations()) || []
944
966
  };
945
967
  }
946
- }), Y(() => {
947
- var n;
948
- return (n = e.image) == null ? void 0 : n.url;
968
+ }), K(() => {
969
+ var s;
970
+ return (s = e.image) == null ? void 0 : s.url;
949
971
  }, () => {
950
- var n;
951
- e.batchImages.length === 0 && ((n = e.image) != null && n.url) && W();
952
- }), Y(() => e.predictionCandidates, (n) => {
953
- n && ut(n);
954
- }, { immediate: !0, deep: !0 }), Y(
955
- () => e.batchImages.map((n) => `${n.imageUrl}:${n.width || ""}x${n.height || ""}`),
972
+ var s;
973
+ e.batchImages.length === 0 && ((s = e.image) != null && s.url) && W();
974
+ }), K(() => e.predictionCandidates, (s) => {
975
+ s && bt(s);
976
+ }, { immediate: !0, deep: !0 }), K(
977
+ () => e.batchImages.map((s) => `${s.imageUrl}:${s.width || ""}x${s.height || ""}`),
956
978
  () => {
957
- X();
979
+ nt(), u.value = u.value.slice(0, e.batchImages.length), at(() => Q());
958
980
  },
959
981
  { immediate: !0 }
960
- ), (n, s) => (y(), x("div", {
961
- class: J(["annotation-container", f.theme])
982
+ ), K(
983
+ () => x.value,
984
+ () => {
985
+ at(() => Q());
986
+ }
987
+ ), (s, i) => (v(), m("div", {
988
+ class: q(["annotation-container", w.theme])
962
989
  }, [
963
- f.batchImages && f.batchImages.length > 0 ? (y(), x("div", ye, [
964
- g("div", pe, "批量图片(" + P(f.batchImages.length) + "", 1),
965
- g("div", xe, [
966
- (y(!0), x(B, null, F(f.batchImages, (l, h) => (y(), x("button", {
967
- key: `${l.imageUrl}-${h}`,
968
- class: J(["image-list-item", { active: h === u.value }]),
969
- onClick: (v) => mt(h)
990
+ w.batchImages && w.batchImages.length > 0 ? (v(), m("div", ze, [
991
+ h("div", Pe, "" + P(w.batchImages.length) + "", 1),
992
+ h("div", {
993
+ ref_key: "imageListScrollRef",
994
+ ref: g,
995
+ class: "image-list-scroll"
996
+ }, [
997
+ (v(!0), m(N, null, J(w.batchImages, (o, d) => (v(), m("button", {
998
+ key: `${o.imageUrl}-${d}`,
999
+ ref_for: !0,
1000
+ ref: (f) => ht(f, d),
1001
+ class: q(["image-list-item", { active: d === x.value }]),
1002
+ onClick: (f) => ot(d)
970
1003
  }, [
971
- g("div", we, [
972
- g("img", {
973
- src: l.imageUrl,
974
- alt: `第${h + 1}张`,
1004
+ h("div", Le, [
1005
+ h("img", {
1006
+ src: o.imageUrl,
1007
+ alt: `第${d + 1}张`,
975
1008
  class: "image-list-thumb"
976
- }, null, 8, Ce),
977
- Dt(h) ? (y(), x("div", Ae, [
978
- (y(!0), x(B, null, F(Pt(h), (v) => (y(), x(B, {
979
- key: v.id
1009
+ }, null, 8, Re),
1010
+ Kt(d) ? (v(), m("div", Be, [
1011
+ (v(!0), m(N, null, J(Gt(d), (f) => (v(), m(N, {
1012
+ key: f.id
980
1013
  }, [
981
- Ht(v) ? (y(), x("div", {
1014
+ Jt(f) ? (v(), m("div", {
982
1015
  key: 0,
983
1016
  class: "thumb-overlay-rect",
984
- style: V(Ut(h, v))
985
- }, null, 4)) : Lt(v) ? (y(), x("svg", _e, [
986
- g("polygon", {
987
- points: Ft(h, v),
988
- style: V(Ot(v))
989
- }, null, 12, Ie)
990
- ])) : Rt(v) ? (y(!0), x(B, { key: 2 }, F(ft(v), (A, $) => (y(), x("div", {
991
- key: `${v.id}-${$}`,
1017
+ style: E(Zt(d, f))
1018
+ }, null, 4)) : Yt(f) ? (v(), m("svg", He, [
1019
+ h("polygon", {
1020
+ points: Qt(d, f),
1021
+ style: E(te(f))
1022
+ }, null, 12, Ue)
1023
+ ])) : jt(f) ? (v(!0), m(N, { key: 2 }, J(Ct(f), (I, z) => (v(), m("div", {
1024
+ key: `${f.id}-${z}`,
992
1025
  class: "thumb-overlay-point",
993
- style: V(Et(h, A, v))
994
- }, null, 4))), 128)) : Bt(v) ? (y(), x("div", {
1026
+ style: E(ee(d, I, f))
1027
+ }, null, 4))), 128)) : Xt(f) ? (v(), m("div", {
995
1028
  key: 3,
996
1029
  class: "thumb-overlay-rotated",
997
- style: V(Vt(h, v))
998
- }, null, 4)) : T("", !0)
1030
+ style: E(se(d, f))
1031
+ }, null, 4)) : qt(f) ? (v(), m("div", {
1032
+ key: 4,
1033
+ class: "thumb-overlay-category",
1034
+ style: E(ie(d, f))
1035
+ }, P(f.label), 5)) : R("", !0)
999
1036
  ], 64))), 128))
1000
- ])) : T("", !0)
1037
+ ])) : R("", !0)
1001
1038
  ]),
1002
- g("span", ke, "第 " + P(h + 1) + " 张", 1)
1003
- ], 10, be))), 128))
1004
- ])
1005
- ])) : T("", !0),
1006
- f.readOnly ? T("", !0) : (y(), x("div", Se, [
1007
- g("div", {
1008
- class: J(["tool-btn", { active: d.value === "pan" }]),
1009
- onClick: s[0] || (s[0] = (l) => p("pan")),
1010
- title: "拖动"
1011
- }, [
1012
- L(H, { name: "rank" })
1013
- ], 2),
1014
- g("div", {
1015
- class: J(["tool-btn", { active: d.value === "select" }]),
1016
- onClick: s[1] || (s[1] = (l) => p("select")),
1017
- title: "选择"
1018
- }, [
1019
- L(H, { name: "pointer" })
1020
- ], 2),
1021
- s[5] || (s[5] = g("div", { class: "divider" }, null, -1)),
1022
- (y(!0), x(B, null, F(nt.value, (l) => (y(), x("div", {
1023
- key: l,
1024
- class: J(["tool-btn", { active: d.value === l }]),
1025
- onClick: (h) => p(l),
1026
- title: it(l)
1027
- }, [
1028
- L(H, {
1029
- name: st(l)
1030
- }, null, 8, ["name"])
1031
- ], 10, Me))), 128)),
1032
- s[6] || (s[6] = g("div", { class: "divider" }, null, -1)),
1033
- g("div", {
1034
- class: "tool-btn",
1035
- onClick: q,
1036
- title: "放大"
1037
- }, [
1038
- L(H, { name: "zoom-in" })
1039
- ]),
1040
- g("div", {
1041
- class: "tool-btn",
1042
- onClick: dt,
1043
- title: "缩小"
1044
- }, [
1045
- L(H, { name: "zoom-out" })
1046
- ]),
1047
- s[7] || (s[7] = g("div", { class: "divider" }, null, -1)),
1048
- N.value ? (y(), x("div", {
1049
- key: 0,
1050
- class: "tool-btn",
1051
- onClick: b,
1052
- title: "删除选中"
1053
- }, [
1054
- L(H, { name: "delete" })
1055
- ])) : T("", !0)
1056
- ])),
1057
- g("div", ze, [
1058
- f.readOnly ? T("", !0) : (y(), x("div", $e, [
1059
- g("div", Te, [
1060
- s[8] || (s[8] = g("span", { class: "label-text" }, "当前标签:", -1)),
1061
- g("div", Pe, [
1062
- (y(!0), x(B, null, F(m.value, (l) => (y(), x("div", {
1063
- key: l.id,
1064
- class: J(["tag-chip", { active: _.value === l.id }]),
1065
- style: V({ backgroundColor: l.color, borderColor: l.color }),
1066
- onClick: (h) => G(l)
1067
- }, P(l.name), 15, He))), 128)),
1068
- m.value.length === 0 ? (y(), x("div", Le, "请在右侧创建标签")) : T("", !0)
1069
- ])
1070
- ])
1071
- ])),
1072
- g("div", {
1039
+ h("span", Ee, "第 " + P(d + 1) + " 张", 1)
1040
+ ], 10, $e))), 128))
1041
+ ], 512)
1042
+ ])) : R("", !0),
1043
+ h("div", Ve, [
1044
+ w.readOnly ? R("", !0) : (v(), m("div", Oe, [
1045
+ h("div", {
1046
+ class: q(["tool-btn", { active: A.value === "select" }]),
1047
+ onClick: i[0] || (i[0] = (o) => j("select")),
1048
+ title: "选择"
1049
+ }, [
1050
+ H(L, { name: "pointer" })
1051
+ ], 2),
1052
+ i[4] || (i[4] = h("div", { class: "divider" }, null, -1)),
1053
+ (v(!0), m(N, null, J(b.value, (o) => (v(), m("div", {
1054
+ key: o,
1055
+ class: q(["tool-btn", { active: A.value === o }]),
1056
+ onClick: (d) => j(o),
1057
+ title: F(o)
1058
+ }, [
1059
+ H(L, {
1060
+ name: k(o)
1061
+ }, null, 8, ["name"])
1062
+ ], 10, Fe))), 128)),
1063
+ i[5] || (i[5] = h("div", { class: "divider" }, null, -1)),
1064
+ h("div", {
1065
+ class: "tool-btn",
1066
+ onClick: Mt,
1067
+ title: "放大"
1068
+ }, [
1069
+ H(L, { name: "zoom-in" })
1070
+ ]),
1071
+ h("div", {
1072
+ class: "tool-btn",
1073
+ onClick: Tt,
1074
+ title: "缩小"
1075
+ }, [
1076
+ H(L, { name: "zoom-out" })
1077
+ ]),
1078
+ O.value ? (v(), m("div", Ne)) : R("", !0),
1079
+ O.value ? (v(), m("div", {
1080
+ key: 1,
1081
+ class: "tool-btn",
1082
+ onClick: St,
1083
+ title: "删除选中"
1084
+ }, [
1085
+ H(L, { name: "delete" })
1086
+ ])) : R("", !0)
1087
+ ]))
1088
+ ]),
1089
+ h("div", We, [
1090
+ h("div", {
1073
1091
  class: "canvas-wrapper",
1074
1092
  ref_key: "canvasWrapper",
1075
- ref: r,
1076
- onWheel: s[2] || (s[2] = qt(() => {
1093
+ ref: a,
1094
+ onWheel: i[1] || (i[1] = It(() => {
1077
1095
  }, ["prevent"]))
1078
1096
  }, [
1079
- g("canvas", {
1097
+ h("canvas", {
1080
1098
  ref_key: "canvasRef",
1081
- ref: c
1082
- }, null, 512)
1099
+ ref: l
1100
+ }, null, 512),
1101
+ w.readOnly ? R("", !0) : (v(), m("div", Ge, [
1102
+ h("div", {
1103
+ class: "selector-trigger",
1104
+ onClick: yt
1105
+ }, [
1106
+ Z.value ? (v(), m("div", Je, [
1107
+ h("span", {
1108
+ class: "color-dot",
1109
+ style: E({ backgroundColor: Z.value.color })
1110
+ }, null, 4),
1111
+ h("span", Ye, P(Z.value.name), 1)
1112
+ ])) : (v(), m("div", je, [...i[6] || (i[6] = [
1113
+ h("span", { class: "label-name" }, "请选择标签", -1)
1114
+ ])])),
1115
+ H(L, {
1116
+ name: "right",
1117
+ class: q(["arrow-icon", { "is-open": G.value }])
1118
+ }, null, 8, ["class"])
1119
+ ]),
1120
+ G.value ? (v(), m("div", Xe, [
1121
+ C.value.length === 0 ? (v(), m("div", qe, "请在右侧创建标签")) : (v(!0), m(N, { key: 1 }, J(C.value, (o) => (v(), m("div", {
1122
+ key: o.id,
1123
+ class: q(["dropdown-item", { active: $.value === o.id }]),
1124
+ onClick: (d) => wt(o)
1125
+ }, [
1126
+ h("span", {
1127
+ class: "color-dot",
1128
+ style: E({ backgroundColor: o.color })
1129
+ }, null, 4),
1130
+ h("span", Ze, P(o.name), 1),
1131
+ $.value === o.id ? (v(), vt(L, {
1132
+ key: 0,
1133
+ name: "aim",
1134
+ class: "check-icon"
1135
+ })) : R("", !0)
1136
+ ], 10, Ke))), 128))
1137
+ ])) : R("", !0)
1138
+ ]))
1083
1139
  ], 544),
1084
- f.batchImages && f.batchImages.length > 0 ? (y(), x("div", Re, [
1085
- g("button", {
1086
- onClick: It,
1087
- disabled: u.value <= 0
1140
+ w.batchImages && w.batchImages.length > 0 ? (v(), m("div", Qe, [
1141
+ h("button", {
1142
+ class: "icon-btn",
1143
+ onClick: Ut,
1144
+ disabled: x.value <= 0,
1145
+ title: "第一张"
1146
+ }, [
1147
+ H(L, { name: "first" })
1148
+ ], 8, ts),
1149
+ h("button", {
1150
+ class: "icon-btn",
1151
+ onClick: Bt,
1152
+ disabled: x.value <= 0,
1153
+ title: "上一张"
1088
1154
  }, [
1089
- L(H, { name: "back" }),
1090
- s[9] || (s[9] = K(" 上一张 ", -1))
1091
- ], 8, Be),
1092
- g("span", null, P(u.value + 1) + " / " + P(f.batchImages.length), 1),
1093
- g("button", {
1094
- onClick: kt,
1095
- disabled: u.value >= f.batchImages.length - 1
1155
+ H(L, { name: "back" })
1156
+ ], 8, es),
1157
+ h("span", null, P(x.value + 1) + " / " + P(w.batchImages.length), 1),
1158
+ h("button", {
1159
+ class: "icon-btn",
1160
+ onClick: Ht,
1161
+ disabled: x.value >= w.batchImages.length - 1,
1162
+ title: "下一张"
1096
1163
  }, [
1097
- s[10] || (s[10] = K(" 下一张 ", -1)),
1098
- L(H, { name: "right" })
1099
- ], 8, De)
1100
- ])) : T("", !0)
1164
+ H(L, { name: "right" })
1165
+ ], 8, ss),
1166
+ h("button", {
1167
+ class: "icon-btn",
1168
+ onClick: Et,
1169
+ disabled: x.value >= w.batchImages.length - 1,
1170
+ title: "最后一张"
1171
+ }, [
1172
+ H(L, { name: "last" })
1173
+ ], 8, is)
1174
+ ])) : R("", !0)
1101
1175
  ]),
1102
- f.readOnly ? T("", !0) : (y(), x("div", Ue, [
1103
- g("div", { class: "sidebar-header" }, [
1104
- s[11] || (s[11] = g("h3", null, "标签管理", -1)),
1105
- g("button", {
1176
+ w.readOnly ? R("", !0) : (v(), m("div", ns, [
1177
+ h("div", { class: "sidebar-header" }, [
1178
+ i[7] || (i[7] = h("h3", null, "标签", -1)),
1179
+ h("button", {
1106
1180
  class: "add-btn",
1107
- onClick: xt
1181
+ onClick: Dt
1108
1182
  }, "添加标签")
1109
1183
  ]),
1110
- g("div", Fe, [
1111
- (y(!0), x(B, null, F(m.value, (l) => (y(), x("div", {
1112
- key: l.id,
1113
- class: "label-item"
1184
+ h("div", os, [
1185
+ (v(!0), m(N, null, J(C.value, (o) => (v(), m("div", {
1186
+ key: o.id,
1187
+ class: "label-item",
1188
+ style: E({ backgroundColor: o.color + "1A", color: o.color })
1114
1189
  }, [
1115
- g("div", Oe, [
1116
- g("label", {
1190
+ h("div", as, [
1191
+ h("label", {
1117
1192
  class: "color-wrapper",
1118
- style: V({ backgroundColor: l.color })
1193
+ style: E({ backgroundColor: o.color })
1119
1194
  }, [
1120
- lt(g("input", {
1195
+ ft(h("input", {
1121
1196
  type: "color",
1122
- "onUpdate:modelValue": (h) => l.color = h,
1123
- onChange: (h) => Ct(l),
1197
+ "onUpdate:modelValue": (d) => o.color = d,
1198
+ onChange: (d) => $t(o),
1124
1199
  style: { visibility: "hidden", width: "0", height: "0" }
1125
- }, null, 40, Ee), [
1126
- [rt, l.color]
1200
+ }, null, 40, ls), [
1201
+ [mt, o.color]
1127
1202
  ])
1128
1203
  ], 4),
1129
- g("span", {
1204
+ h("span", {
1130
1205
  class: "label-name",
1131
- title: l.name
1132
- }, P(l.name), 9, Ve),
1133
- g("span", {
1206
+ title: o.name
1207
+ }, P(o.name), 9, cs),
1208
+ h("span", {
1134
1209
  class: "action-icon eye",
1135
- onClick: (h) => At(l)
1210
+ onClick: (d) => Lt(o)
1136
1211
  }, [
1137
- l.visible ? (y(), yt(H, {
1212
+ o.visible ? (v(), vt(L, {
1138
1213
  key: 0,
1139
1214
  name: "view"
1140
- })) : (y(), yt(H, {
1215
+ })) : (v(), vt(L, {
1141
1216
  key: 1,
1142
1217
  name: "hide"
1143
1218
  }))
1144
- ], 8, Ne),
1145
- g("div", We, [
1146
- s[12] || (s[12] = g("span", { class: "dots" }, "•••", -1)),
1147
- g("span", {
1219
+ ], 8, rs),
1220
+ h("div", hs, [
1221
+ i[8] || (i[8] = h("span", { class: "dots" }, "•••", -1)),
1222
+ h("span", {
1148
1223
  class: "delete-btn",
1149
- onClick: (h) => _t(l.id),
1224
+ onClick: (d) => Rt(o.id),
1150
1225
  title: "删除"
1151
1226
  }, [
1152
- L(H, { name: "delete" })
1153
- ], 8, Je)
1227
+ H(L, { name: "delete" })
1228
+ ], 8, ds)
1154
1229
  ])
1155
1230
  ])
1156
- ]))), 128))
1231
+ ], 4))), 128))
1157
1232
  ])
1158
1233
  ])),
1159
- U.value ? (y(), x("div", je, [
1160
- g("div", Ye, [
1161
- s[15] || (s[15] = g("h3", null, "新增标签", -1)),
1162
- g("div", Xe, [
1163
- s[13] || (s[13] = g("label", null, "名称", -1)),
1164
- lt(g("input", {
1165
- "onUpdate:modelValue": s[3] || (s[3] = (l) => k.value.name = l),
1166
- placeholder: "请输入标签名称",
1167
- class: "modal-input"
1168
- }, null, 512), [
1169
- [rt, k.value.name]
1170
- ])
1171
- ]),
1172
- g("div", qe, [
1173
- s[14] || (s[14] = g("label", null, "颜色", -1)),
1174
- g("div", Ge, [
1175
- lt(g("input", {
1176
- type: "color",
1177
- "onUpdate:modelValue": s[4] || (s[4] = (l) => k.value.color = l),
1178
- class: "modal-color-picker"
1234
+ X.value ? (v(), m("div", {
1235
+ key: 2,
1236
+ class: "modal-overlay",
1237
+ onClick: It(dt, ["self"])
1238
+ }, [
1239
+ h("div", gs, [
1240
+ i[11] || (i[11] = h("div", { class: "modal-header" }, [
1241
+ h("h3", null, "新增标签")
1242
+ ], -1)),
1243
+ h("div", us, [
1244
+ h("div", vs, [
1245
+ i[9] || (i[9] = h("label", null, [
1246
+ lt("标签名称 "),
1247
+ h("span", { class: "required" }, "*")
1248
+ ], -1)),
1249
+ ft(h("input", {
1250
+ "onUpdate:modelValue": i[2] || (i[2] = (o) => _.value.name = o),
1251
+ placeholder: "请输入标签名称",
1252
+ class: "modal-input",
1253
+ autofocus: ""
1179
1254
  }, null, 512), [
1180
- [rt, k.value.color]
1181
- ]),
1182
- g("span", null, P(k.value.color), 1)
1255
+ [mt, _.value.name]
1256
+ ])
1257
+ ]),
1258
+ h("div", fs, [
1259
+ i[10] || (i[10] = h("label", null, "标签颜色", -1)),
1260
+ h("div", ms, [
1261
+ h("label", {
1262
+ class: "color-picker-box",
1263
+ style: E({ backgroundColor: _.value.color })
1264
+ }, [
1265
+ ft(h("input", {
1266
+ type: "color",
1267
+ "onUpdate:modelValue": i[3] || (i[3] = (o) => _.value.color = o),
1268
+ class: "modal-color-picker"
1269
+ }, null, 512), [
1270
+ [mt, _.value.color]
1271
+ ])
1272
+ ], 4),
1273
+ h("span", ps, P(_.value.color), 1)
1274
+ ])
1183
1275
  ])
1184
1276
  ]),
1185
- g("div", { class: "modal-actions" }, [
1186
- g("button", {
1187
- onClick: gt,
1277
+ h("div", ys, [
1278
+ h("button", {
1279
+ onClick: dt,
1188
1280
  class: "cancel-btn"
1189
1281
  }, "取消"),
1190
- g("button", {
1191
- onClick: bt,
1192
- class: "confirm-btn"
1193
- }, "确认")
1282
+ h("button", {
1283
+ onClick: zt,
1284
+ class: "confirm-btn",
1285
+ disabled: !_.value.name.trim()
1286
+ }, "确认", 8, ws)
1194
1287
  ])
1195
1288
  ])
1196
- ])) : T("", !0)
1289
+ ])) : R("", !0)
1197
1290
  ], 2));
1198
1291
  }
1199
- }), Ze = /* @__PURE__ */ et(Ke, [["__scopeId", "data-v-ccc538f3"]]), Qe = {
1292
+ }), bs = /* @__PURE__ */ rt(xs, [["__scopeId", "data-v-b6482ca8"]]), _s = {
1200
1293
  class: "thumbnail-wrapper",
1201
1294
  ref: "wrapper"
1202
- }, tn = ["src", "alt"], en = ["viewBox", "preserveAspectRatio"], nn = ["x", "y", "width", "height", "stroke", "stroke-width"], sn = ["points", "stroke", "stroke-width"], on = ["x", "y", "fill", "font-size"], an = {
1295
+ }, Cs = ["src", "alt"], ks = ["viewBox", "preserveAspectRatio"], Is = ["x", "y", "width", "height", "stroke", "stroke-width"], As = ["points", "stroke", "stroke-width"], Ss = ["transform"], Ms = ["x", "y", "width", "height", "stroke", "stroke-width"], Ts = { key: 3 }, Ds = ["cx", "cy", "r", "fill", "stroke-width"], zs = ["x", "y", "width", "height", "fill"], Ps = ["x", "y", "fill", "font-size", "font-weight", "text-anchor", "dominant-baseline"], $s = {
1203
1296
  key: 1,
1204
1297
  class: "loading-placeholder"
1205
- }, ln = /* @__PURE__ */ tt({
1298
+ }, Ls = /* @__PURE__ */ ct({
1206
1299
  __name: "AnnotationThumbnail",
1207
1300
  props: {
1208
1301
  src: {},
@@ -1213,89 +1306,134 @@ const Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1213
1306
  strokeWidth: {},
1214
1307
  fontSize: {}
1215
1308
  },
1216
- setup(f) {
1217
- const t = f, i = M(null), e = M(!1), o = M(0), c = M(0), r = () => {
1218
- i.value && (o.value = i.value.naturalWidth, c.value = i.value.naturalHeight, e.value = !0);
1219
- }, a = D(() => t.fit === "contain" ? "xMidYMid meet" : "xMidYMid slice"), d = D(() => t.strokeWidth ?? 10), u = D(() => t.fontSize ?? 30), w = (k) => {
1220
- var I;
1221
- if ((I = k.style) != null && I.strokeColor) return k.style.strokeColor;
1309
+ setup(w) {
1310
+ const t = w, n = M(null), e = M(!1), c = M(0), l = M(0), a = () => {
1311
+ n.value && (c.value = n.value.naturalWidth, l.value = n.value.naturalHeight, e.value = !0);
1312
+ }, g = V(() => t.fit === "contain" ? "xMidYMid meet" : "xMidYMid slice"), u = V(() => t.strokeWidth ?? 10), r = V(() => t.fontSize ?? 30), A = (_) => {
1313
+ var S;
1314
+ if ((S = _.style) != null && S.strokeColor) return _.style.strokeColor;
1222
1315
  if (t.labels) {
1223
- const C = t.labels.find((R) => R.name === k.label);
1224
- if (C) return C.color;
1316
+ const p = t.labels.find((B) => B.name === _.label);
1317
+ if (p) return p.color;
1225
1318
  }
1226
1319
  return "#FF0000";
1227
- }, m = (k) => {
1228
- const I = k.coordinates, C = Math.min(I.x1, I.x2), R = Math.min(I.y1, I.y2), N = Math.abs(I.x1 - I.x2), j = Math.abs(I.y1 - I.y2);
1229
- return { x: C, y: R, width: N, height: j };
1230
- }, _ = (k) => k.coordinates.points.map((C) => `${C.x},${C.y}`).join(" "), U = (k) => {
1231
- if (k.type === "rectangle") {
1232
- const I = m(k);
1233
- return { x: I.x, y: I.y - 5 };
1234
- } else if (k.type === "polygon") {
1235
- const I = k.coordinates.points;
1236
- if (I.length > 0) return { x: I[0].x, y: I[0].y - 5 };
1320
+ }, x = (_) => {
1321
+ const S = _.coordinates, p = Math.min(S.x1, S.x2), B = Math.min(S.y1, S.y2), O = Math.abs(S.x1 - S.x2), G = Math.abs(S.y1 - S.y2);
1322
+ return { x: p, y: B, width: O, height: G };
1323
+ }, D = (_) => _.coordinates.points.map((p) => `${p.x},${p.y}`).join(" "), C = (_) => {
1324
+ if (_.type === "rectangle") {
1325
+ const S = x(_);
1326
+ return { x: S.x, y: S.y - 5 };
1327
+ } else if (_.type === "polygon") {
1328
+ const S = _.coordinates.points;
1329
+ if (S.length > 0) return { x: S[0].x, y: S[0].y - 5 };
1330
+ } else {
1331
+ if (_.type === "rotatedRect")
1332
+ return { x: _.coordinates.x, y: _.coordinates.y - _.coordinates.height / 2 - 5 };
1333
+ if (_.type === "point") {
1334
+ const S = _.coordinates.points;
1335
+ if (S.length > 0) return { x: S[0].x, y: S[0].y - 15 };
1336
+ } else if (_.type === "category")
1337
+ return { x: _.coordinates.x, y: _.coordinates.y };
1237
1338
  }
1238
1339
  return { x: 0, y: 0 };
1239
- };
1240
- return (k, I) => (y(), x("div", Qe, [
1241
- g("img", {
1340
+ }, $ = (_) => {
1341
+ const { x: S, y: p, angle: B } = _.coordinates, O = B * 180 / Math.PI;
1342
+ return `translate(${S}, ${p}) rotate(${O})`;
1343
+ }, X = (_) => ({ x: _.coordinates.x, y: _.coordinates.y });
1344
+ return (_, S) => (v(), m("div", _s, [
1345
+ h("img", {
1242
1346
  ref_key: "img",
1243
- ref: i,
1244
- src: f.src,
1347
+ ref: n,
1348
+ src: w.src,
1245
1349
  class: "thumbnail-image",
1246
- style: V({ objectFit: f.fit }),
1247
- onLoad: r,
1248
- alt: f.alt
1249
- }, null, 44, tn),
1250
- e.value ? (y(), x("svg", {
1350
+ style: E({ objectFit: w.fit }),
1351
+ onLoad: a,
1352
+ alt: w.alt
1353
+ }, null, 44, Cs),
1354
+ e.value ? (v(), m("svg", {
1251
1355
  key: 0,
1252
1356
  class: "annotation-overlay",
1253
- viewBox: `0 0 ${o.value} ${c.value}`,
1254
- preserveAspectRatio: a.value
1357
+ viewBox: `0 0 ${c.value} ${l.value}`,
1358
+ preserveAspectRatio: g.value
1255
1359
  }, [
1256
- (y(!0), x(B, null, F(f.annotations, (C) => (y(), x(B, {
1257
- key: C.id
1360
+ (v(!0), m(N, null, J(w.annotations, (p) => (v(), m(N, {
1361
+ key: p.id
1258
1362
  }, [
1259
- C.type === "rectangle" ? (y(), x("rect", {
1363
+ p.type === "rectangle" ? (v(), m("rect", {
1260
1364
  key: 0,
1261
- x: m(C).x,
1262
- y: m(C).y,
1263
- width: m(C).width,
1264
- height: m(C).height,
1265
- stroke: w(C),
1266
- "stroke-width": d.value,
1365
+ x: x(p).x,
1366
+ y: x(p).y,
1367
+ width: x(p).width,
1368
+ height: x(p).height,
1369
+ stroke: A(p),
1370
+ "stroke-width": u.value,
1267
1371
  fill: "transparent"
1268
- }, null, 8, nn)) : T("", !0),
1269
- C.type === "polygon" ? (y(), x("polygon", {
1372
+ }, null, 8, Is)) : p.type === "polygon" ? (v(), m("polygon", {
1270
1373
  key: 1,
1271
- points: _(C),
1272
- stroke: w(C),
1273
- "stroke-width": d.value,
1374
+ points: D(p),
1375
+ stroke: A(p),
1376
+ "stroke-width": u.value,
1274
1377
  fill: "transparent"
1275
- }, null, 8, sn)) : T("", !0),
1276
- C.label ? (y(), x("text", {
1378
+ }, null, 8, As)) : p.type === "rotatedRect" ? (v(), m("g", {
1277
1379
  key: 2,
1278
- x: U(C).x,
1279
- y: U(C).y,
1280
- fill: w(C),
1281
- "font-size": u.value,
1282
- "font-weight": "bold",
1283
- class: "anno-label"
1284
- }, P(C.label), 9, on)) : T("", !0)
1380
+ transform: $(p)
1381
+ }, [
1382
+ h("rect", {
1383
+ x: -p.coordinates.width / 2,
1384
+ y: -p.coordinates.height / 2,
1385
+ width: p.coordinates.width,
1386
+ height: p.coordinates.height,
1387
+ stroke: A(p),
1388
+ "stroke-width": u.value,
1389
+ fill: "transparent"
1390
+ }, null, 8, Ms)
1391
+ ], 8, Ss)) : p.type === "point" ? (v(), m("g", Ts, [
1392
+ (v(!0), m(N, null, J(p.coordinates.points, (B, O) => (v(), m("circle", {
1393
+ key: O,
1394
+ cx: B.x,
1395
+ cy: B.y,
1396
+ r: u.value * 1.5,
1397
+ fill: A(p),
1398
+ stroke: "white",
1399
+ "stroke-width": u.value * 0.5
1400
+ }, null, 8, Ds))), 128))
1401
+ ])) : p.type === "category" ? (v(), m("rect", {
1402
+ key: 4,
1403
+ x: X(p).x - (p.label || "").length * r.value * 0.6 / 2 - 8,
1404
+ y: X(p).y - r.value / 2 - 4,
1405
+ width: (p.label || "").length * r.value * 0.6 + 16,
1406
+ height: r.value + 8,
1407
+ rx: "6",
1408
+ ry: "6",
1409
+ fill: A(p),
1410
+ "fill-opacity": "0.85"
1411
+ }, null, 8, zs)) : R("", !0),
1412
+ p.label ? (v(), m("text", {
1413
+ key: 5,
1414
+ x: C(p).x,
1415
+ y: C(p).y,
1416
+ fill: p.type === "category" ? "#ffffff" : A(p),
1417
+ "font-size": r.value,
1418
+ "font-weight": p.type === "category" ? "normal" : "bold",
1419
+ "text-anchor": p.type === "category" ? "middle" : "start",
1420
+ "dominant-baseline": p.type === "category" ? "middle" : "auto",
1421
+ class: q({ "anno-label": p.type !== "category" })
1422
+ }, P(p.label), 11, Ps)) : R("", !0)
1285
1423
  ], 64))), 128))
1286
- ], 8, en)) : (y(), x("div", an, "Loading..."))
1424
+ ], 8, ks)) : (v(), m("div", $s, "Loading..."))
1287
1425
  ], 512));
1288
1426
  }
1289
- }), rn = /* @__PURE__ */ et(ln, [["__scopeId", "data-v-d2fd08ec"]]), cn = {
1427
+ }), Rs = /* @__PURE__ */ rt(Ls, [["__scopeId", "data-v-159a7956"]]), Bs = {
1290
1428
  key: 0,
1291
1429
  class: "gallery-view"
1292
- }, hn = { class: "gallery-header" }, dn = { class: "label-summary" }, gn = ["onClick"], un = { class: "thumbnail-wrapper" }, vn = { class: "img-meta" }, mn = { class: "img-index" }, fn = { class: "anno-count" }, yn = {
1430
+ }, Hs = { class: "gallery-layout" }, Us = { class: "gallery-sidebar" }, Es = { class: "label-stats-table" }, Vs = { class: "label-cover-wrapper" }, Os = ["src"], Fs = { class: "gallery-content" }, Ns = ["onClick"], Ws = { class: "thumbnail-wrapper" }, Gs = { class: "img-meta" }, Js = { class: "img-index" }, Ys = { class: "anno-count" }, js = {
1293
1431
  key: 0,
1294
1432
  class: "bottom-bar"
1295
- }, pn = {
1433
+ }, Xs = {
1296
1434
  key: 1,
1297
1435
  class: "editor-view"
1298
- }, xn = { class: "editor-header" }, bn = { class: "header-left" }, wn = { class: "editor-title" }, Cn = { class: "editor-content" }, An = /* @__PURE__ */ tt({
1436
+ }, qs = { class: "editor-header" }, Ks = { class: "header-left" }, Zs = { class: "editor-title" }, Qs = { class: "editor-content" }, ti = /* @__PURE__ */ ct({
1299
1437
  __name: "BatchAnnotator",
1300
1438
  props: {
1301
1439
  images: {},
@@ -1306,165 +1444,226 @@ const Qt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1306
1444
  thumbFontSize: {}
1307
1445
  },
1308
1446
  emits: ["export", "update:images", "imageClick", "update:labels"],
1309
- setup(f, { expose: t, emit: i }) {
1310
- const e = f, o = i, c = M("gallery"), r = M([]), a = M([]), d = M(0), u = M(null), w = M(null), m = M(null), _ = D(() => {
1311
- var p, b;
1312
- return ((b = (p = e.actionBar) == null ? void 0 : p.annotateButton) == null ? void 0 : b.show) === !0;
1313
- }), U = D(() => {
1314
- var p, b;
1315
- return ((b = (p = e.actionBar) == null ? void 0 : p.exportButton) == null ? void 0 : b.show) === !0;
1316
- }), k = D(() => _.value || U.value), I = D(() => {
1317
- var p, b;
1318
- return ((b = (p = e.actionBar) == null ? void 0 : p.annotateButton) == null ? void 0 : b.text) || "手动标注";
1319
- }), C = D(() => {
1320
- var p, b;
1321
- return ((b = (p = e.actionBar) == null ? void 0 : p.exportButton) == null ? void 0 : b.text) || "导出";
1322
- }), R = D(() => e.clickToEnterEditor !== !1);
1323
- Y(() => e.images, (p) => {
1324
- r.value = JSON.parse(JSON.stringify(p));
1325
- }, { immediate: !0, deep: !0 }), Y(() => e.labels, (p) => {
1326
- a.value = JSON.parse(JSON.stringify(p || []));
1447
+ setup(w, { expose: t, emit: n }) {
1448
+ const e = w, c = n, l = M("gallery"), a = M([]), g = M([]), u = M(0), r = M(null), A = M(null), x = M(null), D = V(() => {
1449
+ var y, b;
1450
+ return ((b = (y = e.actionBar) == null ? void 0 : y.annotateButton) == null ? void 0 : b.show) === !0;
1451
+ }), C = V(() => {
1452
+ var y, b;
1453
+ return ((b = (y = e.actionBar) == null ? void 0 : y.exportButton) == null ? void 0 : b.show) === !0;
1454
+ }), $ = V(() => D.value || C.value), X = V(() => {
1455
+ var y, b;
1456
+ return ((b = (y = e.actionBar) == null ? void 0 : y.annotateButton) == null ? void 0 : b.text) || "手动标注";
1457
+ }), _ = V(() => {
1458
+ var y, b;
1459
+ return ((b = (y = e.actionBar) == null ? void 0 : y.exportButton) == null ? void 0 : b.text) || "导出";
1460
+ }), S = V(() => e.clickToEnterEditor !== !1), p = V(() => {
1461
+ const y = {};
1462
+ g.value.forEach((k) => {
1463
+ y[k.name] = { count: 0, cover: "" };
1464
+ });
1465
+ let b = 0;
1466
+ return a.value.forEach((k) => {
1467
+ k.annotations && k.annotations.forEach((F) => {
1468
+ var W;
1469
+ const U = F.label || (F.labelId ? (W = g.value.find((j) => j.id === F.labelId)) == null ? void 0 : W.name : null);
1470
+ U && y[U] && (y[U].count++, b++, y[U].cover || (y[U].cover = k.imageUrl));
1471
+ });
1472
+ }), g.value.map((k) => {
1473
+ var W, j;
1474
+ const F = ((W = y[k.name]) == null ? void 0 : W.count) || 0, U = b === 0 ? "0.00%" : (F / b * 100).toFixed(2) + "%";
1475
+ return {
1476
+ id: k.id,
1477
+ name: k.name,
1478
+ color: k.color,
1479
+ count: F,
1480
+ percentage: U,
1481
+ cover: ((j = y[k.name]) == null ? void 0 : j.cover) || ""
1482
+ };
1483
+ });
1484
+ }), B = (y) => ({
1485
+ color: y.color,
1486
+ backgroundColor: y.color + "1A"
1487
+ // 1A represents ~10% opacity in hex
1488
+ });
1489
+ K(() => e.images, (y) => {
1490
+ a.value = JSON.parse(JSON.stringify(y));
1491
+ }, { immediate: !0, deep: !0 }), K(() => e.labels, (y) => {
1492
+ g.value = JSON.parse(JSON.stringify(y || []));
1327
1493
  }, { immediate: !0, deep: !0 });
1328
- const N = (p) => {
1329
- d.value = p, c.value = "editor", m.value && (m.value.scrollTop = 0), Gt(() => {
1330
- w.value && (w.value.scrollTop = 0), window.scrollTo(0, 0), requestAnimationFrame(() => {
1331
- var b, z;
1332
- (z = (b = u.value) == null ? void 0 : b.jumpTo) == null || z.call(b, p);
1494
+ const O = (y) => {
1495
+ u.value = y, l.value = "editor", x.value && (x.value.scrollTop = 0), at(() => {
1496
+ A.value && (A.value.scrollTop = 0), window.scrollTo(0, 0), requestAnimationFrame(() => {
1497
+ var b, k;
1498
+ (k = (b = r.value) == null ? void 0 : b.jumpTo) == null || k.call(b, y);
1333
1499
  });
1334
1500
  });
1335
- }, j = (p, b) => {
1336
- if (R.value) {
1337
- N(p);
1501
+ }, G = (y, b) => {
1502
+ if (S.value) {
1503
+ O(y);
1338
1504
  return;
1339
1505
  }
1340
- o("imageClick", { index: p, imageId: b.id, image: b });
1341
- }, X = (p) => r.value.findIndex((b) => b.id === p);
1506
+ c("imageClick", { index: y, imageId: b.id, image: b });
1507
+ }, Z = (y) => a.value.findIndex((b) => b.id === y);
1342
1508
  t({
1343
- openImageById: (p) => {
1344
- const b = X(p);
1345
- return b < 0 ? !1 : (N(b), !0);
1509
+ openImageById: (y) => {
1510
+ const b = Z(y);
1511
+ return b < 0 ? !1 : (O(b), !0);
1346
1512
  },
1347
- triggerImageClickById: (p) => {
1348
- const b = X(p);
1513
+ triggerImageClickById: (y) => {
1514
+ const b = Z(y);
1349
1515
  if (b < 0)
1350
1516
  return !1;
1351
- const z = r.value[b];
1352
- return z ? (o("imageClick", { index: b, imageId: z.id, image: z }), !0) : !1;
1517
+ const k = a.value[b];
1518
+ return k ? (c("imageClick", { index: b, imageId: k.id, image: k }), !0) : !1;
1353
1519
  },
1354
1520
  getFinalData: () => ({
1355
- images: JSON.parse(JSON.stringify(r.value)),
1356
- labels: JSON.parse(JSON.stringify(a.value))
1521
+ images: JSON.parse(JSON.stringify(a.value)),
1522
+ labels: JSON.parse(JSON.stringify(g.value))
1357
1523
  })
1358
1524
  });
1359
- const nt = () => {
1360
- if (u.value && u.value.getCurrentAnnotation) {
1361
- const p = u.value.getCurrentAnnotation();
1362
- r.value[d.value] && (r.value[d.value].annotations = p.annotations);
1525
+ const it = () => {
1526
+ if (r.value && r.value.getCurrentAnnotation) {
1527
+ const y = r.value.getCurrentAnnotation();
1528
+ a.value[u.value] && (a.value[u.value].annotations = y.annotations);
1363
1529
  }
1364
- c.value = "gallery";
1365
- }, st = () => {
1366
- o("export", r.value);
1367
- }, it = (p) => {
1368
- d.value = p.currentIndex, r.value[p.currentIndex] && (r.value[p.currentIndex].annotations = p.currentAnnotations);
1369
- }, E = (p) => {
1370
- if (u.value && u.value.getCurrentAnnotation) {
1371
- const b = u.value.getCurrentAnnotation();
1372
- r.value[d.value] && (r.value[d.value].annotations = b.annotations, o("update:images", r.value));
1530
+ l.value = "gallery";
1531
+ }, nt = () => {
1532
+ c("export", a.value);
1533
+ }, ht = (y) => {
1534
+ u.value = y.currentIndex, a.value[y.currentIndex] && (a.value[y.currentIndex].annotations = y.currentAnnotations);
1535
+ }, Q = (y) => {
1536
+ if (r.value && r.value.getCurrentAnnotation) {
1537
+ const b = r.value.getCurrentAnnotation();
1538
+ a.value[u.value] && (a.value[u.value].annotations = b.annotations, c("update:images", a.value));
1373
1539
  }
1374
- }, W = (p) => {
1375
- a.value = JSON.parse(JSON.stringify(p || [])), o("update:labels", a.value);
1540
+ }, Y = (y) => {
1541
+ g.value = JSON.parse(JSON.stringify(y || [])), c("update:labels", g.value);
1376
1542
  };
1377
- return (p, b) => (y(), x("div", {
1543
+ return (y, b) => (v(), m("div", {
1378
1544
  ref_key: "batchRootRef",
1379
- ref: w,
1545
+ ref: A,
1380
1546
  class: "batch-annotator"
1381
1547
  }, [
1382
- c.value === "gallery" ? (y(), x("div", cn, [
1383
- g("div", hn, [
1384
- g("h3", null, "批量查看与标注 (" + P(r.value.length) + " 张)", 1),
1385
- g("div", dn, [
1386
- (y(!0), x(B, null, F(a.value, (z) => (y(), x("span", {
1387
- key: z.id,
1388
- class: "label-badge",
1389
- style: V({ backgroundColor: z.color })
1390
- }, P(z.name), 5))), 128))
1548
+ l.value === "gallery" ? (v(), m("div", Bs, [
1549
+ h("div", Hs, [
1550
+ h("div", Us, [
1551
+ h("table", Es, [
1552
+ b[1] || (b[1] = h("thead", null, [
1553
+ h("tr", null, [
1554
+ h("th", null, "标签封面"),
1555
+ h("th", null, "标签名称"),
1556
+ h("th", null, "标注数"),
1557
+ h("th", null, "占比")
1558
+ ])
1559
+ ], -1)),
1560
+ h("tbody", null, [
1561
+ (v(!0), m(N, null, J(p.value, (k) => (v(), m("tr", {
1562
+ key: k.id,
1563
+ style: E(B(k))
1564
+ }, [
1565
+ h("td", null, [
1566
+ h("div", Vs, [
1567
+ k.cover ? (v(), m("img", {
1568
+ key: 0,
1569
+ src: k.cover,
1570
+ class: "label-cover"
1571
+ }, null, 8, Os)) : (v(), m("div", {
1572
+ key: 1,
1573
+ class: "label-cover-empty",
1574
+ style: E({ backgroundColor: k.color })
1575
+ }, null, 4))
1576
+ ])
1577
+ ]),
1578
+ h("td", null, P(k.name), 1),
1579
+ h("td", null, P(k.count), 1),
1580
+ h("td", null, P(k.percentage), 1)
1581
+ ], 4))), 128))
1582
+ ])
1583
+ ])
1584
+ ]),
1585
+ h("div", Fs, [
1586
+ h("div", {
1587
+ ref_key: "galleryGridRef",
1588
+ ref: x,
1589
+ class: "gallery-grid"
1590
+ }, [
1591
+ (v(!0), m(N, null, J(a.value, (k, F) => (v(), m("div", {
1592
+ key: F,
1593
+ class: "gallery-item",
1594
+ onClick: (U) => G(F, k)
1595
+ }, [
1596
+ h("div", Ws, [
1597
+ H(Rs, {
1598
+ src: k.imageUrl,
1599
+ annotations: k.annotations || [],
1600
+ labels: g.value,
1601
+ fit: "cover",
1602
+ strokeWidth: e.thumbStrokeWidth,
1603
+ fontSize: e.thumbFontSize
1604
+ }, null, 8, ["src", "annotations", "labels", "strokeWidth", "fontSize"])
1605
+ ]),
1606
+ h("div", Gs, [
1607
+ h("span", Js, "#" + P(F + 1), 1),
1608
+ h("span", Ys, P((k.annotations || []).length) + " 标注", 1)
1609
+ ])
1610
+ ], 8, Ns))), 128))
1611
+ ], 512)
1391
1612
  ])
1392
1613
  ]),
1393
- g("div", {
1394
- ref_key: "galleryGridRef",
1395
- ref: m,
1396
- class: "gallery-grid"
1397
- }, [
1398
- (y(!0), x(B, null, F(r.value, (z, q) => (y(), x("div", {
1399
- key: q,
1400
- class: "gallery-item",
1401
- onClick: (dt) => j(q, z)
1402
- }, [
1403
- g("div", un, [
1404
- L(rn, {
1405
- src: z.imageUrl,
1406
- annotations: z.annotations || [],
1407
- labels: a.value,
1408
- fit: "cover",
1409
- strokeWidth: e.thumbStrokeWidth,
1410
- fontSize: e.thumbFontSize
1411
- }, null, 8, ["src", "annotations", "labels", "strokeWidth", "fontSize"])
1412
- ]),
1413
- g("div", vn, [
1414
- g("span", mn, "#" + P(q + 1), 1),
1415
- g("span", fn, P((z.annotations || []).length) + " 标注", 1)
1416
- ])
1417
- ], 8, gn))), 128))
1418
- ], 512),
1419
- k.value ? (y(), x("div", yn, [
1420
- _.value ? (y(), x("button", {
1614
+ $.value ? (v(), m("div", js, [
1615
+ D.value ? (v(), m("button", {
1421
1616
  key: 0,
1422
1617
  class: "action-btn primary",
1423
- onClick: b[0] || (b[0] = (z) => N(0))
1618
+ onClick: b[0] || (b[0] = (k) => O(0))
1424
1619
  }, [
1425
- L(H, { name: "edit" }),
1426
- K(" " + P(I.value), 1)
1427
- ])) : T("", !0),
1428
- U.value ? (y(), x("button", {
1620
+ H(L, { name: "edit" }),
1621
+ lt(" " + P(X.value), 1)
1622
+ ])) : R("", !0),
1623
+ C.value ? (v(), m("button", {
1429
1624
  key: 1,
1430
1625
  class: "action-btn success",
1431
- onClick: st
1626
+ onClick: nt
1432
1627
  }, [
1433
- L(H, { name: "download" }),
1434
- K(" " + P(C.value), 1)
1435
- ])) : T("", !0)
1436
- ])) : T("", !0)
1437
- ])) : (y(), x("div", pn, [
1438
- g("div", xn, [
1439
- g("div", bn, [
1440
- g("button", {
1628
+ H(L, { name: "download" }),
1629
+ lt(" " + P(_.value), 1)
1630
+ ])) : R("", !0)
1631
+ ])) : R("", !0)
1632
+ ])) : (v(), m("div", Xs, [
1633
+ h("div", qs, [
1634
+ h("div", Ks, [
1635
+ h("button", {
1441
1636
  class: "back-btn",
1442
- onClick: nt
1637
+ onClick: it
1443
1638
  }, [
1444
- L(H, { name: "back" }),
1445
- b[1] || (b[1] = K(" 返回列表 ", -1))
1639
+ H(L, {
1640
+ name: "back",
1641
+ class: "back-icon"
1642
+ }),
1643
+ b[2] || (b[2] = lt()),
1644
+ b[3] || (b[3] = h("span", { class: "back-text" }, "返回", -1))
1446
1645
  ]),
1447
- g("span", wn, "正在标注: " + P(d.value + 1) + " / " + P(r.value.length), 1)
1646
+ h("span", Zs, "正在标注: " + P(u.value + 1) + " / " + P(a.value.length), 1)
1448
1647
  ])
1449
1648
  ]),
1450
- g("div", Cn, [
1451
- L(Ze, {
1649
+ h("div", Qs, [
1650
+ H(bs, {
1452
1651
  ref_key: "annotatorRef",
1453
- ref: u,
1454
- batchImages: r.value,
1455
- labels: a.value,
1456
- annotationTypes: ["rectangle", "polygon", "point", "rotatedRect"],
1457
- onBatchChange: it,
1458
- onAnnotationChange: E,
1459
- onLabelChange: W
1652
+ ref: r,
1653
+ batchImages: a.value,
1654
+ labels: g.value,
1655
+ annotationTypes: ["rectangle", "polygon", "point", "rotatedRect", "category"],
1656
+ onBatchChange: ht,
1657
+ onAnnotationChange: Q,
1658
+ onLabelChange: Y
1460
1659
  }, null, 8, ["batchImages", "labels"])
1461
1660
  ])
1462
1661
  ]))
1463
1662
  ], 512));
1464
1663
  }
1465
- }), kn = /* @__PURE__ */ et(An, [["__scopeId", "data-v-0ae1040a"]]);
1664
+ }), ii = /* @__PURE__ */ rt(ti, [["__scopeId", "data-v-369475fa"]]);
1466
1665
  export {
1467
- kn as BatchAnnotator,
1468
- Ze as ImageAnnotator,
1469
- kn as default
1666
+ ii as BatchAnnotator,
1667
+ bs as ImageAnnotator,
1668
+ ii as default
1470
1669
  };