luo-image-annotator 0.0.8 → 0.0.9

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 +1 @@
1
- .svg-icon[data-v-3928607b]{display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;fill:currentColor;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.svg-icon[data-v-3928607b] svg{width:1em;height:1em;fill:currentColor}.size-small[data-v-3928607b]{font-size:12px}.size-large[data-v-3928607b]{font-size:20px}.annotation-container[data-v-22c2957b]{display:flex;height:100%;width:100%;border:1px solid #e0e0e0;background:#f5f5f5;overflow:hidden}.image-list-sidebar[data-v-22c2957b]{width:180px;background:#fafbfc;border-right:1px solid #e0e0e0;display:flex;flex-direction:column}.image-list-title[data-v-22c2957b]{height:44px;display:flex;align-items:center;padding:0 12px;font-size:13px;color:#303133;border-bottom:1px solid #e8edf3;font-weight:600}.image-list-scroll[data-v-22c2957b]{flex:1;padding:8px;display:flex;flex-direction:column;gap:8px;overflow-y:auto}.image-list-item[data-v-22c2957b]{border:1px solid #e4e7ed;border-radius:6px;background:#fff;padding:6px;display:flex;flex-direction:column;gap:6px;cursor:pointer;text-align:left}.image-list-item[data-v-22c2957b]:hover{border-color:#b3d8ff}.image-list-item.active[data-v-22c2957b]{border-color:#409eff;box-shadow:0 0 0 1px #409eff inset}.image-list-stage[data-v-22c2957b]{width:100%;height:78px;position:relative;border-radius:4px;overflow:hidden}.image-list-thumb[data-v-22c2957b]{width:100%;height:100%;object-fit:cover;border-radius:4px}.image-list-text[data-v-22c2957b]{font-size:12px;color:#606266}.thumb-overlay-layer[data-v-22c2957b]{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.thumb-overlay-rect[data-v-22c2957b]{position:absolute;border:1px solid;box-sizing:border-box;border-radius:2px}.thumb-overlay-svg[data-v-22c2957b]{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%}.thumb-overlay-point[data-v-22c2957b]{position:absolute;width:8px;height:8px;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #fff}.thumb-overlay-rotated[data-v-22c2957b]{position:absolute;border:1px solid;box-sizing:border-box;border-radius:2px;transform-origin:center center}.left-sidebar[data-v-22c2957b]{width:50px;background:#fff;border-right:1px solid #e0e0e0;display:flex;flex-direction:column;align-items:center;padding:8px 0;gap:8px;z-index:10}.tool-btn[data-v-22c2957b]{width:36px;height:36px;display:flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:4px;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:18px;transition:all .2s}.tool-btn[data-v-22c2957b]:hover{background:#f0f0f0}.tool-btn.active[data-v-22c2957b]{background:#e3f2fd;border-color:#2196f3;color:#2196f3}.divider[data-v-22c2957b]{width:80%;height:1px;background:#ddd;margin:4px 0}.center-area[data-v-22c2957b]{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden}.top-bar[data-v-22c2957b]{height:50px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;padding:0 16px}.label-selector[data-v-22c2957b]{display:flex;align-items:center;gap:12px;width:100%;overflow-x:auto}.label-text[data-v-22c2957b]{font-size:14px;font-weight:700;color:#555;white-space:nowrap}.tags-row[data-v-22c2957b]{display:flex;gap:8px}.tag-chip[data-v-22c2957b]{padding:4px 12px;border-radius:16px;font-size:12px;color:#fff;cursor:pointer;border:2px solid transparent;opacity:.7;transition:all .2s;white-space:nowrap}.tag-chip.active[data-v-22c2957b]{opacity:1;transform:scale(1.05);box-shadow:0 2px 4px #0003}.canvas-wrapper[data-v-22c2957b]{flex:1;background:#333;position:relative;overflow:hidden}.batch-nav[data-v-22c2957b]{height:48px;background:#fff;border-top:1px solid #e0e0e0;display:flex;justify-content:center;align-items:center;gap:16px}.batch-nav button[data-v-22c2957b]{padding:6px 16px;background:#f5f5f5;border:1px solid #ddd;border-radius:4px;cursor:pointer}.batch-nav button[data-v-22c2957b]:hover:not(:disabled){background:#e0e0e0}.right-sidebar[data-v-22c2957b]{width:250px;background:#fff;border-left:1px solid #e0e0e0;display:flex;flex-direction:column;z-index:10}.sidebar-header[data-v-22c2957b]{padding:16px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center}.sidebar-header h3[data-v-22c2957b]{margin:0;font-size:16px}.add-btn[data-v-22c2957b]{padding:4px 8px;background:#2196f3;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:12px}.label-list[data-v-22c2957b]{flex:1;overflow-y:auto;padding:8px}.label-item[data-v-22c2957b]{margin-bottom:8px;padding:8px;background:#f9f9f9;border-radius:4px;border:1px solid #eee}.label-row[data-v-22c2957b]{display:flex;align-items:center;gap:8px}.eye-icon[data-v-22c2957b],.delete-icon[data-v-22c2957b]{cursor:pointer;font-size:16px;-webkit-user-select:none;user-select:none;opacity:.7}.eye-icon[data-v-22c2957b]:hover,.delete-icon[data-v-22c2957b]:hover{opacity:1}.color-picker[data-v-22c2957b]{width:24px;height:24px;padding:0;border:none;cursor:pointer;background:none}.name-input[data-v-22c2957b]{flex:1;border:1px solid transparent;background:transparent;font-size:14px;padding:2px 4px}.name-input[data-v-22c2957b]:focus{border-color:#2196f3;background:#fff;outline:none}.color-wrapper[data-v-22c2957b]{width:16px;height:16px;border-radius:50%;cursor:pointer;border:1px solid rgba(0,0,0,.1);flex-shrink:0}.label-name[data-v-22c2957b]{flex:1;font-size:14px;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.action-icon[data-v-22c2957b]{cursor:pointer;font-size:16px;-webkit-user-select:none;user-select:none;width:24px;text-align:center;opacity:.6}.action-icon[data-v-22c2957b]:hover{opacity:1}.more-actions[data-v-22c2957b]{position:relative;display:flex;justify-content:center;align-items:center}.more-actions .delete-btn[data-v-22c2957b]{display:none;font-size:14px}.more-actions:hover .dots[data-v-22c2957b]{display:none}.more-actions:hover .delete-btn[data-v-22c2957b]{display:inline-block;color:#f44336}.modal-overlay[data-v-22c2957b]{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.modal-content[data-v-22c2957b]{background:#fff;padding:20px;border-radius:8px;width:300px;box-shadow:0 4px 12px #00000026}.modal-content h3[data-v-22c2957b]{margin:0 0 16px;font-size:18px;color:#333}.form-group[data-v-22c2957b]{margin-bottom:16px}.form-group label[data-v-22c2957b]{display:block;margin-bottom:8px;font-size:14px;color:#666}.modal-input[data-v-22c2957b]{width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;font-size:14px;box-sizing:border-box}.color-input-wrapper[data-v-22c2957b]{display:flex;align-items:center;gap:8px}.modal-color-picker[data-v-22c2957b]{width:40px;height:30px;padding:0;border:none;background:none;cursor:pointer}.modal-actions[data-v-22c2957b]{display:flex;justify-content:flex-end;gap:12px;margin-top:24px}.cancel-btn[data-v-22c2957b]{padding:6px 16px;background:#f5f5f5;border:1px solid #ddd;border-radius:4px;cursor:pointer;color:#666}.confirm-btn[data-v-22c2957b]{padding:6px 16px;background:#2196f3;border:none;border-radius:4px;cursor:pointer;color:#fff}.cancel-btn[data-v-22c2957b]:hover{background:#e0e0e0}.confirm-btn[data-v-22c2957b]:hover{background:#1976d2}.thumbnail-wrapper[data-v-78bcbe0c]{position:relative;width:100%;height:100%;overflow:hidden;border-radius:4px;background:#f0f0f0}.thumbnail-image[data-v-78bcbe0c]{width:100%;height:100%;object-fit:cover;display:block}.annotation-overlay[data-v-78bcbe0c]{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.loading-placeholder[data-v-78bcbe0c]{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#999;font-size:12px}.anno-label[data-v-78bcbe0c]{paint-order:stroke;stroke:#fff;stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}.batch-annotator[data-v-419d7955]{width:100%;height:100vh;display:flex;flex-direction:column;background:#f5f5f5}.gallery-view[data-v-419d7955]{flex:1;display:flex;flex-direction:column;overflow:hidden;padding:20px;position:relative}.gallery-header[data-v-419d7955]{margin-bottom:20px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.gallery-header h3[data-v-419d7955]{margin:0;font-size:20px;color:#333}.label-summary[data-v-419d7955]{display:flex;gap:8px}.label-badge[data-v-419d7955]{padding:4px 10px;border-radius:12px;color:#fff;font-size:12px;font-weight:700}.gallery-grid[data-v-419d7955]{flex:1;display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:20px;overflow-y:auto;padding-bottom:80px}.gallery-item[data-v-419d7955]{background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a;cursor:pointer;transition:transform .2s,box-shadow .2s;display:flex;flex-direction:column;height:240px}.gallery-item[data-v-419d7955]:hover{transform:translateY(-4px);box-shadow:0 4px 12px #00000026}.thumbnail-wrapper[data-v-419d7955]{flex:1;overflow:hidden;position:relative}.img-meta[data-v-419d7955]{padding:8px;font-size:12px;color:#666;display:flex;justify-content:space-between;background:#fff;border-top:1px solid #eee;height:32px;align-items:center}.bottom-bar[data-v-419d7955]{position:absolute;bottom:0;left:0;width:100%;height:60px;background:#fff;border-top:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center;padding:0 40px;box-shadow:0 -2px 10px #0000000d;z-index:100}.action-btn[data-v-419d7955]{display:flex;align-items:center;gap:8px;padding:10px 24px;border:none;border-radius:4px;font-size:16px;cursor:pointer;transition:background .2s}.action-btn.primary[data-v-419d7955]{background:#2196f3;color:#fff}.action-btn.primary[data-v-419d7955]:hover{background:#1976d2}.action-btn.success[data-v-419d7955]{background:#4caf50;color:#fff}.action-btn.success[data-v-419d7955]:hover{background:#388e3c}.editor-view[data-v-419d7955]{flex:1;display:flex;flex-direction:column;height:100%}.editor-header[data-v-419d7955]{height:50px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;padding:0 16px;justify-content:space-between;flex-shrink:0}.header-left[data-v-419d7955]{display:flex;align-items:center;gap:16px}.back-btn[data-v-419d7955]{display:flex;align-items:center;gap:4px;background:transparent;border:1px solid #ddd;padding:6px 12px;border-radius:4px;cursor:pointer;font-size:14px;color:#666}.back-btn[data-v-419d7955]:hover{background:#f5f5f5;color:#333}.editor-content[data-v-419d7955]{flex:1;overflow:hidden;position:relative}
1
+ .svg-icon[data-v-3928607b]{display:inline-flex;align-items:center;justify-content:center;width:1em;height:1em;fill:currentColor;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.svg-icon[data-v-3928607b] svg{width:1em;height:1em;fill:currentColor}.size-small[data-v-3928607b]{font-size:12px}.size-large[data-v-3928607b]{font-size:20px}.annotation-container[data-v-22c2957b]{display:flex;height:100%;width:100%;border:1px solid #e0e0e0;background:#f5f5f5;overflow:hidden}.image-list-sidebar[data-v-22c2957b]{width:180px;background:#fafbfc;border-right:1px solid #e0e0e0;display:flex;flex-direction:column}.image-list-title[data-v-22c2957b]{height:44px;display:flex;align-items:center;padding:0 12px;font-size:13px;color:#303133;border-bottom:1px solid #e8edf3;font-weight:600}.image-list-scroll[data-v-22c2957b]{flex:1;padding:8px;display:flex;flex-direction:column;gap:8px;overflow-y:auto}.image-list-item[data-v-22c2957b]{border:1px solid #e4e7ed;border-radius:6px;background:#fff;padding:6px;display:flex;flex-direction:column;gap:6px;cursor:pointer;text-align:left}.image-list-item[data-v-22c2957b]:hover{border-color:#b3d8ff}.image-list-item.active[data-v-22c2957b]{border-color:#409eff;box-shadow:0 0 0 1px #409eff inset}.image-list-stage[data-v-22c2957b]{width:100%;height:78px;position:relative;border-radius:4px;overflow:hidden}.image-list-thumb[data-v-22c2957b]{width:100%;height:100%;object-fit:cover;border-radius:4px}.image-list-text[data-v-22c2957b]{font-size:12px;color:#606266}.thumb-overlay-layer[data-v-22c2957b]{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.thumb-overlay-rect[data-v-22c2957b]{position:absolute;border:1px solid;box-sizing:border-box;border-radius:2px}.thumb-overlay-svg[data-v-22c2957b]{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%}.thumb-overlay-point[data-v-22c2957b]{position:absolute;width:8px;height:8px;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #fff}.thumb-overlay-rotated[data-v-22c2957b]{position:absolute;border:1px solid;box-sizing:border-box;border-radius:2px;transform-origin:center center}.left-sidebar[data-v-22c2957b]{width:50px;background:#fff;border-right:1px solid #e0e0e0;display:flex;flex-direction:column;align-items:center;padding:8px 0;gap:8px;z-index:10}.tool-btn[data-v-22c2957b]{width:36px;height:36px;display:flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:4px;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:18px;transition:all .2s}.tool-btn[data-v-22c2957b]:hover{background:#f0f0f0}.tool-btn.active[data-v-22c2957b]{background:#e3f2fd;border-color:#2196f3;color:#2196f3}.divider[data-v-22c2957b]{width:80%;height:1px;background:#ddd;margin:4px 0}.center-area[data-v-22c2957b]{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden}.top-bar[data-v-22c2957b]{height:50px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;padding:0 16px}.label-selector[data-v-22c2957b]{display:flex;align-items:center;gap:12px;width:100%;overflow-x:auto}.label-text[data-v-22c2957b]{font-size:14px;font-weight:700;color:#555;white-space:nowrap}.tags-row[data-v-22c2957b]{display:flex;gap:8px}.tag-chip[data-v-22c2957b]{padding:4px 12px;border-radius:16px;font-size:12px;color:#fff;cursor:pointer;border:2px solid transparent;opacity:.7;transition:all .2s;white-space:nowrap}.tag-chip.active[data-v-22c2957b]{opacity:1;transform:scale(1.05);box-shadow:0 2px 4px #0003}.canvas-wrapper[data-v-22c2957b]{flex:1;background:#333;position:relative;overflow:hidden}.batch-nav[data-v-22c2957b]{height:48px;background:#fff;border-top:1px solid #e0e0e0;display:flex;justify-content:center;align-items:center;gap:16px}.batch-nav button[data-v-22c2957b]{padding:6px 16px;background:#f5f5f5;border:1px solid #ddd;border-radius:4px;cursor:pointer}.batch-nav button[data-v-22c2957b]:hover:not(:disabled){background:#e0e0e0}.right-sidebar[data-v-22c2957b]{width:250px;background:#fff;border-left:1px solid #e0e0e0;display:flex;flex-direction:column;z-index:10}.sidebar-header[data-v-22c2957b]{padding:16px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center}.sidebar-header h3[data-v-22c2957b]{margin:0;font-size:16px}.add-btn[data-v-22c2957b]{padding:4px 8px;background:#2196f3;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:12px}.label-list[data-v-22c2957b]{flex:1;overflow-y:auto;padding:8px}.label-item[data-v-22c2957b]{margin-bottom:8px;padding:8px;background:#f9f9f9;border-radius:4px;border:1px solid #eee}.label-row[data-v-22c2957b]{display:flex;align-items:center;gap:8px}.eye-icon[data-v-22c2957b],.delete-icon[data-v-22c2957b]{cursor:pointer;font-size:16px;-webkit-user-select:none;user-select:none;opacity:.7}.eye-icon[data-v-22c2957b]:hover,.delete-icon[data-v-22c2957b]:hover{opacity:1}.color-picker[data-v-22c2957b]{width:24px;height:24px;padding:0;border:none;cursor:pointer;background:none}.name-input[data-v-22c2957b]{flex:1;border:1px solid transparent;background:transparent;font-size:14px;padding:2px 4px}.name-input[data-v-22c2957b]:focus{border-color:#2196f3;background:#fff;outline:none}.color-wrapper[data-v-22c2957b]{width:16px;height:16px;border-radius:50%;cursor:pointer;border:1px solid rgba(0,0,0,.1);flex-shrink:0}.label-name[data-v-22c2957b]{flex:1;font-size:14px;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.action-icon[data-v-22c2957b]{cursor:pointer;font-size:16px;-webkit-user-select:none;user-select:none;width:24px;text-align:center;opacity:.6}.action-icon[data-v-22c2957b]:hover{opacity:1}.more-actions[data-v-22c2957b]{position:relative;display:flex;justify-content:center;align-items:center}.more-actions .delete-btn[data-v-22c2957b]{display:none;font-size:14px}.more-actions:hover .dots[data-v-22c2957b]{display:none}.more-actions:hover .delete-btn[data-v-22c2957b]{display:inline-block;color:#f44336}.modal-overlay[data-v-22c2957b]{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.modal-content[data-v-22c2957b]{background:#fff;padding:20px;border-radius:8px;width:300px;box-shadow:0 4px 12px #00000026}.modal-content h3[data-v-22c2957b]{margin:0 0 16px;font-size:18px;color:#333}.form-group[data-v-22c2957b]{margin-bottom:16px}.form-group label[data-v-22c2957b]{display:block;margin-bottom:8px;font-size:14px;color:#666}.modal-input[data-v-22c2957b]{width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;font-size:14px;box-sizing:border-box}.color-input-wrapper[data-v-22c2957b]{display:flex;align-items:center;gap:8px}.modal-color-picker[data-v-22c2957b]{width:40px;height:30px;padding:0;border:none;background:none;cursor:pointer}.modal-actions[data-v-22c2957b]{display:flex;justify-content:flex-end;gap:12px;margin-top:24px}.cancel-btn[data-v-22c2957b]{padding:6px 16px;background:#f5f5f5;border:1px solid #ddd;border-radius:4px;cursor:pointer;color:#666}.confirm-btn[data-v-22c2957b]{padding:6px 16px;background:#2196f3;border:none;border-radius:4px;cursor:pointer;color:#fff}.cancel-btn[data-v-22c2957b]:hover{background:#e0e0e0}.confirm-btn[data-v-22c2957b]:hover{background:#1976d2}.thumbnail-wrapper[data-v-78bcbe0c]{position:relative;width:100%;height:100%;overflow:hidden;border-radius:4px;background:#f0f0f0}.thumbnail-image[data-v-78bcbe0c]{width:100%;height:100%;object-fit:cover;display:block}.annotation-overlay[data-v-78bcbe0c]{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.loading-placeholder[data-v-78bcbe0c]{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#999;font-size:12px}.anno-label[data-v-78bcbe0c]{paint-order:stroke;stroke:#fff;stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}.batch-annotator[data-v-d19b4a14]{width:100%;display:flex;flex-direction:column;background:transparent;height:100%}.gallery-view[data-v-d19b4a14]{flex:1;display:flex;flex-direction:column;overflow:hidden;padding:20px;position:relative}.gallery-header[data-v-d19b4a14]{margin-bottom:20px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.gallery-header h3[data-v-d19b4a14]{margin:0;color:#333}.label-summary[data-v-d19b4a14]{display:flex;gap:8px}.label-badge[data-v-d19b4a14]{padding:4px 10px;border-radius:12px;color:#fff;font-size:12px;font-weight:700}.gallery-grid[data-v-d19b4a14]{flex:1;height:calc(100% - 110px);display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:20px;overflow:auto;padding-bottom:80px}.gallery-item[data-v-d19b4a14]{background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px #0000001a;cursor:pointer;transition:transform .2s,box-shadow .2s;display:flex;flex-direction:column;height:240px}.gallery-item[data-v-d19b4a14]:hover{transform:translateY(-4px);box-shadow:0 4px 12px #00000026}.thumbnail-wrapper[data-v-d19b4a14]{flex:1;overflow:hidden;position:relative}.img-meta[data-v-d19b4a14]{padding:8px;font-size:12px;color:#666;display:flex;justify-content:space-between;background:#fff;border-top:1px solid #eee;height:32px;align-items:center}.bottom-bar[data-v-d19b4a14]{position:absolute;bottom:0;left:0;width:100%;height:60px;background:#fff;border-top:1px solid #e0e0e0;display:flex;justify-content:space-between;align-items:center;padding:0 40px;box-shadow:0 -2px 10px #0000000d;z-index:100}.action-btn[data-v-d19b4a14]{display:flex;align-items:center;gap:8px;padding:10px 24px;border:none;border-radius:4px;font-size:16px;cursor:pointer;transition:background .2s}.action-btn.primary[data-v-d19b4a14]{background:#2196f3;color:#fff}.action-btn.primary[data-v-d19b4a14]:hover{background:#1976d2}.action-btn.success[data-v-d19b4a14]{background:#4caf50;color:#fff}.action-btn.success[data-v-d19b4a14]:hover{background:#388e3c}.editor-view[data-v-d19b4a14]{flex:1;display:flex;flex-direction:column}.editor-header[data-v-d19b4a14]{height:50px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;padding:0 16px;justify-content:space-between;flex-shrink:0}.header-left[data-v-d19b4a14]{display:flex;align-items:center;gap:16px}.back-btn[data-v-d19b4a14]{display:flex;align-items:center;gap:4px;background:transparent;border:1px solid #ddd;padding:6px 12px;border-radius:4px;cursor:pointer;font-size:14px;color:#666}.back-btn[data-v-d19b4a14]:hover{background:#f5f5f5;color:#333}.editor-content[data-v-d19b4a14]{flex:1;overflow:hidden;position:relative}
@@ -1414,7 +1414,7 @@ const Zt = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" widt
1414
1414
  ]))
1415
1415
  ]));
1416
1416
  }
1417
- }), Sn = /* @__PURE__ */ K(An, [["__scopeId", "data-v-419d7955"]]);
1417
+ }), Sn = /* @__PURE__ */ K(An, [["__scopeId", "data-v-d19b4a14"]]);
1418
1418
  export {
1419
1419
  Sn as BatchAnnotator,
1420
1420
  Ke as ImageAnnotator,
@@ -30,4 +30,4 @@
30
30
  <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM416 448h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64h96v-96a32 32 0 0 1 64 0v96z" fill="currentColor"/>\r
31
31
  </svg>`,bt=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1em" height="1em">\r
32
32
  <path d="M637.12 693.376l182.208 182.208a32 32 0 1 1-45.248 45.248L591.872 738.624a352 352 0 1 1 45.248-45.248z m-45.248-45.248A288 288 0 1 0 183.872 240.128a288 288 0 0 0 408 408zM256 448h320a32 32 0 1 1 0 64H256a32 32 0 1 1 0-64z" fill="currentColor"/>\r
33
- </svg>`,wt=["innerHTML"],kt=t.defineComponent({__name:"SvgIcon",props:{name:{},size:{}},setup(y){const e=y,i=t.ref(""),n=Object.assign({"../assets/svg/aim.svg":it,"../assets/svg/back.svg":at,"../assets/svg/connection.svg":lt,"../assets/svg/crop.svg":rt,"../assets/svg/delete.svg":ct,"../assets/svg/download.svg":ht,"../assets/svg/edit.svg":dt,"../assets/svg/hide.svg":gt,"../assets/svg/pointer.svg":mt,"../assets/svg/price-tag.svg":ft,"../assets/svg/rank.svg":ut,"../assets/svg/refresh-right.svg":pt,"../assets/svg/right.svg":yt,"../assets/svg/view.svg":vt,"../assets/svg/zoom-in.svg":xt,"../assets/svg/zoom-out.svg":bt});return t.watchEffect(()=>{const r=`../assets/svg/${e.name}.svg`,c=n[r];c?i.value=c:(console.warn(`Icon ${e.name} not found at path ${r}`),i.value="")}),(r,c)=>(t.openBlock(),t.createElementBlock("i",{class:t.normalizeClass(["svg-icon",[y.size?`size-${y.size}`:""]]),innerHTML:i.value},null,10,wt))}}),P=(y,e)=>{const i=y.__vccOpts||y;for(const[n,r]of e)i[n]=r;return i},E=P(kt,[["__scopeId","data-v-3928607b"]]),Ct={key:0,class:"image-list-sidebar"},_t={class:"image-list-title"},At={class:"image-list-scroll"},It=["onClick"],Bt={class:"image-list-stage"},Et=["src","alt"],St={key:0,class:"thumb-overlay-layer"},Vt={key:1,class:"thumb-overlay-svg",viewBox:"0 0 100 100",preserveAspectRatio:"none"},Nt=["points"],zt={class:"image-list-text"},Mt={key:1,class:"left-sidebar"},Tt=["onClick","title"],$t={class:"center-area"},Pt={key:0,class:"top-bar"},Dt={class:"label-selector"},Lt={class:"tags-row"},Ht=["onClick"],Rt={key:0,class:"no-labels"},Ut={key:1,class:"batch-nav"},Ft=["disabled"],Ot=["disabled"],Wt={key:2,class:"right-sidebar"},jt={class:"label-list"},Jt={class:"label-row"},Xt=["onUpdate:modelValue","onChange"],Yt=["title"],qt=["onClick"],Gt={class:"action-icon more-actions"},Kt=["onClick"],Zt={key:3,class:"modal-overlay"},Qt={class:"modal-content"},te={class:"form-group"},ee={class:"form-group"},ne={class:"color-input-wrapper"},X=P(t.defineComponent({__name:"ImageAnnotator",props:{annotationTypes:{default:()=>["rectangle","polygon","point","rotatedRect"]},batchImages:{default:()=>[]},labels:{default:()=>[]},defaultActiveType:{},theme:{default:"light"},readOnly:{type:Boolean,default:!1},image:{},predictionCandidates:{},session:{},requestId:{},minZoom:{},maxZoom:{}},emits:["annotationChange","batchChange","labelChange","ready","error","tool:change","viewport:change","annotation:add","annotation:update","annotation:delete","annotation:select","prediction:loaded","prediction:apply","prediction:reject"],setup(y,{expose:e,emit:i}){const n=y,r=i,c=t.ref(null),h=t.ref(null),a=t.ref(null),d=t.ref(null),p=t.ref(0),b=t.ref(""),m=t.ref([]),u=t.ref(""),k=t.ref(!1),B=t.ref({name:"",color:"#FF0000"}),S=t.ref("none"),V=t.ref([]),T=t.ref({}),q=t.computed(()=>d.value==="select"&&!!b.value),R=o=>{if(!o||T.value[o])return;const s=new Image;s.onload=()=>{const l=s.naturalWidth||1,g=s.naturalHeight||1;T.value={...T.value,[o]:{width:l,height:g}}},s.src=o},D=()=>{n.batchImages.forEach(o=>{R(o.imageUrl)})},N=()=>{var l,g,f,w;const o=n.batchImages[p.value],s=(o==null?void 0:o.imageUrl)||((l=n.image)==null?void 0:l.url);return{eventId:`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,timestamp:Date.now(),requestId:n.requestId,taskId:(g=n.session)==null?void 0:g.taskId,imageId:((f=n.image)==null?void 0:f.id)||s,operator:(w=n.session)==null?void 0:w.userId}},U=o=>{var g;const s=o==null?void 0:o.action;if(!s)return;const l={meta:N(),action:s,current:o==null?void 0:o.changedItem,source:(g=o==null?void 0:o.changedItem)!=null&&g.predictionId?"prediction":"manual"};s==="add"&&r("annotation:add",l),s==="update"&&r("annotation:update",l),s==="delete"&&r("annotation:delete",l),s==="select"&&r("annotation:select",l)},F=t.computed(()=>n.annotationTypes.filter(o=>o!=="category")),O=o=>({rectangle:"crop",polygon:"connection",point:"aim",rotatedRect:"refresh-right",category:"price-tag"})[o]||o,v=o=>({rectangle:"矩形框",polygon:"多边形",point:"关键点",rotatedRect:"旋转矩形",category:"分类标签"})[o]||o;t.onMounted(()=>{if(D(),c.value){a.value=new st(c.value),a.value.on("annotationChange",s=>{var l,g;if(s.action==="add"&&s.changedItem){const f=m.value.find(w=>w.id===u.value);f&&(s.changedItem.label=f.name,s.changedItem.labelId=f.id)}s.action==="select"?b.value=((l=s.changedItem)==null?void 0:l.id)||"":s.action==="delete"&&((g=s.changedItem)==null?void 0:g.id)===b.value&&(b.value=""),r("annotationChange",s),U(s)}),_(),x();const o=new ResizeObserver(()=>{var s;(s=a.value)==null||s.resize()});h.value&&o.observe(h.value),n.defaultActiveType&&z(n.defaultActiveType),r("ready",{meta:N()})}});const x=()=>{if(!a.value)return;const o=m.value.find(l=>l.id===u.value);o&&a.value.setLabelStyle(o.color);const s=m.value.filter(l=>l.visible).map(l=>l.name);a.value.setVisibleLabels(s)},_=()=>{var o;if(a.value)if(b.value="",n.batchImages.length>0){const s=n.batchImages[p.value];a.value.loadImage(s.imageUrl),s.annotations?a.value.setAnnotations(s.annotations):a.value.setAnnotations([])}else(o=n.image)!=null&&o.url&&a.value.loadImage(n.image.url)},z=o=>{var s,l;if(d.value=o,b.value="",o!=="pan"&&o!=="select"&&m.value.length===0){alert("请先创建标签!");return}o==="pan"||o==="select"?(s=a.value)==null||s.setTool(o):(l=a.value)==null||l.setTool(o),r("tool:change",{meta:N(),tool:o})},G=()=>{var o;(o=a.value)!=null&&o.activeAnnotation&&a.value.deleteAnnotation(a.value.activeAnnotation.id)},K=()=>{a.value&&r("viewport:change",{meta:N(),scale:a.value.scale,offset:{...a.value.offset}})},Be=()=>{var o;(o=a.value)==null||o.zoom(1),K()},Ee=()=>{var o;(o=a.value)==null||o.zoom(-1),K()},Se=()=>{B.value={name:"",color:"#2196F3"},k.value=!0},Z=()=>{k.value=!1},Ve=()=>{if(!B.value.name.trim()){alert("请输入标签名称");return}const s={id:Date.now().toString(),name:B.value.name,color:B.value.color,visible:!0};m.value.push(s),r("labelChange",m.value),m.value.length===1&&$(s),Z()},$=o=>{var s;u.value=o.id,(s=a.value)==null||s.setLabelStyle(o.color)},Ne=(o,s)=>{if(!o.startsWith("#"))return o;let l=0,g=0,f=0;return o.length===4?(l=parseInt(o[1]+o[1],16),g=parseInt(o[2]+o[2],16),f=parseInt(o[3]+o[3],16)):o.length===7&&(l=parseInt(o.slice(1,3),16),g=parseInt(o.slice(3,5),16),f=parseInt(o.slice(5,7),16)),`rgba(${l}, ${g}, ${f}, ${s})`},ze=o=>{var s;if(o.id===u.value&&((s=a.value)==null||s.setLabelStyle(o.color)),a.value){const l=a.value.getAnnotations();let g=!1;l.forEach(f=>{f.label===o.name&&(f.style||(f.style={}),f.style.strokeColor=o.color,f.style.fillColor=Ne(o.color,.2),g=!0)}),g&&a.value.render()}r("labelChange",m.value)},Me=o=>{o.visible=!o.visible,x()},Te=o=>{const s=m.value.findIndex(l=>l.id===o);s>-1&&(m.value.splice(s,1),r("labelChange",m.value),u.value===o&&(u.value=m.value.length>0?m.value[0].id:"",u.value&&$(m.value[0])),x())};t.watch(()=>n.labels,o=>{const s=JSON.parse(JSON.stringify(o||[]));if(m.value=s,m.value.length>0)if(!u.value||!m.value.find(l=>l.id===u.value))$(m.value[0]);else{const l=m.value.find(g=>g.id===u.value);l&&$(l)}else u.value="";x()},{immediate:!0,deep:!0});const $e=()=>{p.value>0&&(W(),p.value--,_(),j())},Pe=()=>{p.value<n.batchImages.length-1&&(W(),p.value++,_(),j())},W=()=>{if(a.value){const o=a.value.getAnnotations();n.batchImages[p.value].annotations=o}},j=()=>{const o=n.batchImages[p.value];r("batchChange",{currentIndex:p.value,total:n.batchImages.length,currentImageUrl:o.imageUrl,currentAnnotations:o.annotations||[]})},Q=(o=[])=>{var f;if(!a.value)return;if(V.value=JSON.parse(JSON.stringify(o)),V.value.length===0){S.value="none";return}S.value="loaded";const l=(a.value.getAnnotations()||[]).filter(w=>!w.predictionId),g=V.value.map(w=>{const A=JSON.parse(JSON.stringify(w.annotation));return A.id=A.id||`pred-${w.id}`,A.predictionId=w.id,A.modelRunId=w.modelRunId||A.modelRunId,A.confidence=w.confidence??A.confidence,A.reviewStatus=A.reviewStatus||"draft",A});a.value.setAnnotations([...l,...g]),r("prediction:loaded",{meta:N(),modelRunId:(f=V.value[0])==null?void 0:f.modelRunId,candidates:V.value})},De=(o,s)=>{var f;if(!a.value)return[];S.value="applying";const g=(a.value.getAnnotations()||[]).filter(w=>w.predictionId&&o.includes(w.predictionId));return g.forEach(w=>{w.reviewStatus="accepted"}),S.value="applied",r("prediction:apply",{meta:N(),modelRunId:(f=g[0])==null?void 0:f.modelRunId,candidateIds:o,threshold:s,acceptedAnnotations:g}),a.value.render(),g},Le=(o,s)=>{var f;if(!a.value)return;const l=a.value.getAnnotations()||[],g=l.filter(w=>!(w.predictionId&&o.includes(w.predictionId)));a.value.setAnnotations(g),r("prediction:reject",{meta:N(),modelRunId:(f=l.find(w=>w.predictionId&&o.includes(w.predictionId)))==null?void 0:f.modelRunId,candidateIds:o,reason:s})},He=(o,s=[])=>{a.value&&(a.value.loadImage(o.url),a.value.setAnnotations(s))},Re=o=>{var s;(s=a.value)==null||s.setAnnotations(o)},tt=()=>{var o;return((o=a.value)==null?void 0:o.getAnnotations())||[]},Ue=(o="json")=>{var l,g;const s=tt();return{format:o,image:((l=n.batchImages[p.value])==null?void 0:l.imageUrl)||((g=n.image)==null?void 0:g.url)||"",annotations:s}},et=o=>{o>=0&&o<n.batchImages.length&&(W(),p.value=o,_(),j())},Fe=o=>{var s;return o===p.value&&a.value?a.value.getAnnotations()||[]:((s=n.batchImages[o])==null?void 0:s.annotations)||[]},Oe=o=>o.type==="rectangle",We=o=>o.type==="polygon",je=o=>o.type==="point",Je=o=>o.type==="rotatedRect",L=o=>{var l,g;const s=(l=m.value.find(f=>f.name===o.label))==null?void 0:l.color;return((g=o.style)==null?void 0:g.strokeColor)||s||"#409eff"},nt=o=>{const s=o.coordinates;return(s==null?void 0:s.points)||[]},H=o=>{const s=n.batchImages[o];if(s!=null&&s.width&&(s!=null&&s.height))return{width:s.width,height:s.height};const l=s!=null&&s.imageUrl?T.value[s.imageUrl]:void 0;return l||(s!=null&&s.imageUrl&&R(s.imageUrl),{width:1,height:1})},Xe=o=>{const s=n.batchImages[o];return s!=null&&s.width&&(s!=null&&s.height)?!0:s!=null&&s.imageUrl?!!T.value[s.imageUrl]:!1},Ye=(o,s)=>{const l=s.coordinates,g=H(o),f=L(s),w=Math.min(l.x1,l.x2),A=Math.min(l.y1,l.y2),Qe=Math.max(l.x1,l.x2),tn=Math.max(l.y1,l.y2);return{left:`${w/g.width*100}%`,top:`${A/g.height*100}%`,width:`${(Qe-w)/g.width*100}%`,height:`${(tn-A)/g.height*100}%`,borderColor:f,backgroundColor:`${f}22`}},qe=(o,s)=>{const l=H(o);return nt(s).map(g=>`${g.x/l.width*100},${g.y/l.height*100}`).join(" ")},Ge=o=>{const s=L(o);return{fill:`${s}33`,stroke:s,strokeWidth:"1.4"}},Ke=(o,s,l)=>{const g=H(o),f=L(l);return{left:`${s.x/g.width*100}%`,top:`${s.y/g.height*100}%`,backgroundColor:f}},Ze=(o,s)=>{const l=s.coordinates,g=H(o),f=L(s),w=Math.abs(l.width),A=Math.abs(l.height);return{left:`${(l.x-w/2)/g.width*100}%`,top:`${(l.y-A/2)/g.height*100}%`,width:`${w/g.width*100}%`,height:`${A/g.height*100}%`,transform:`rotate(${l.angle||0}deg)`,borderColor:f,backgroundColor:`${f}22`}};return e({jumpTo:et,setImage:He,setAnnotations:Re,getAnnotations:tt,selectTool:z,loadPredictionCandidates:Q,applyPredictions:De,rejectPredictions:Le,exportAnnotations:Ue,getAllAnnotations:()=>{var o,s;return n.batchImages.length>0?n.batchImages:[{imageUrl:((o=n.image)==null?void 0:o.url)||"",annotations:((s=a.value)==null?void 0:s.getAnnotations())||[]}]},getCurrentAnnotation:()=>{var o,s,l;return{imageUrl:((o=n.batchImages[p.value])==null?void 0:o.imageUrl)||((s=n.image)==null?void 0:s.url)||"",annotations:((l=a.value)==null?void 0:l.getAnnotations())||[]}}}),t.watch(()=>{var o;return(o=n.image)==null?void 0:o.url},()=>{var o;n.batchImages.length===0&&((o=n.image)!=null&&o.url)&&_()}),t.watch(()=>n.predictionCandidates,o=>{o&&Q(o)},{immediate:!0,deep:!0}),t.watch(()=>n.batchImages.map(o=>`${o.imageUrl}:${o.width||""}x${o.height||""}`),()=>{D()},{immediate:!0}),(o,s)=>(t.openBlock(),t.createElementBlock("div",{class:t.normalizeClass(["annotation-container",y.theme])},[y.batchImages&&y.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",Ct,[t.createElementVNode("div",_t,"批量图片("+t.toDisplayString(y.batchImages.length)+")",1),t.createElementVNode("div",At,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.batchImages,(l,g)=>(t.openBlock(),t.createElementBlock("button",{key:`${l.imageUrl}-${g}`,class:t.normalizeClass(["image-list-item",{active:g===p.value}]),onClick:f=>et(g)},[t.createElementVNode("div",Bt,[t.createElementVNode("img",{src:l.imageUrl,alt:`第${g+1}张`,class:"image-list-thumb"},null,8,Et),Xe(g)?(t.openBlock(),t.createElementBlock("div",St,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(Fe(g),f=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:f.id},[Oe(f)?(t.openBlock(),t.createElementBlock("div",{key:0,class:"thumb-overlay-rect",style:t.normalizeStyle(Ye(g,f))},null,4)):We(f)?(t.openBlock(),t.createElementBlock("svg",Vt,[t.createElementVNode("polygon",{points:qe(g,f),style:t.normalizeStyle(Ge(f))},null,12,Nt)])):je(f)?(t.openBlock(!0),t.createElementBlock(t.Fragment,{key:2},t.renderList(nt(f),(w,A)=>(t.openBlock(),t.createElementBlock("div",{key:`${f.id}-${A}`,class:"thumb-overlay-point",style:t.normalizeStyle(Ke(g,w,f))},null,4))),128)):Je(f)?(t.openBlock(),t.createElementBlock("div",{key:3,class:"thumb-overlay-rotated",style:t.normalizeStyle(Ze(g,f))},null,4)):t.createCommentVNode("",!0)],64))),128))])):t.createCommentVNode("",!0)]),t.createElementVNode("span",zt,"第 "+t.toDisplayString(g+1)+" 张",1)],10,It))),128))])])):t.createCommentVNode("",!0),y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Mt,[t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:d.value==="pan"}]),onClick:s[0]||(s[0]=l=>z("pan")),title:"拖动"},[t.createVNode(E,{name:"rank"})],2),t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:d.value==="select"}]),onClick:s[1]||(s[1]=l=>z("select")),title:"选择"},[t.createVNode(E,{name:"pointer"})],2),s[4]||(s[4]=t.createElementVNode("div",{class:"divider"},null,-1)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(F.value,l=>(t.openBlock(),t.createElementBlock("div",{key:l,class:t.normalizeClass(["tool-btn",{active:d.value===l}]),onClick:g=>z(l),title:v(l)},[t.createVNode(E,{name:O(l)},null,8,["name"])],10,Tt))),128)),s[5]||(s[5]=t.createElementVNode("div",{class:"divider"},null,-1)),t.createElementVNode("div",{class:"tool-btn",onClick:Be,title:"放大"},[t.createVNode(E,{name:"zoom-in"})]),t.createElementVNode("div",{class:"tool-btn",onClick:Ee,title:"缩小"},[t.createVNode(E,{name:"zoom-out"})]),s[6]||(s[6]=t.createElementVNode("div",{class:"divider"},null,-1)),q.value?(t.openBlock(),t.createElementBlock("div",{key:0,class:"tool-btn",onClick:G,title:"删除选中"},[t.createVNode(E,{name:"delete"})])):t.createCommentVNode("",!0)])),t.createElementVNode("div",$t,[y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Pt,[t.createElementVNode("div",Dt,[s[7]||(s[7]=t.createElementVNode("span",{class:"label-text"},"当前标签:",-1)),t.createElementVNode("div",Lt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(m.value,l=>(t.openBlock(),t.createElementBlock("div",{key:l.id,class:t.normalizeClass(["tag-chip",{active:u.value===l.id}]),style:t.normalizeStyle({backgroundColor:l.color,borderColor:l.color}),onClick:g=>$(l)},t.toDisplayString(l.name),15,Ht))),128)),m.value.length===0?(t.openBlock(),t.createElementBlock("div",Rt,"请在右侧创建标签")):t.createCommentVNode("",!0)])])])),t.createElementVNode("div",{class:"canvas-wrapper",ref_key:"canvasWrapper",ref:h},[t.createElementVNode("canvas",{ref_key:"canvasRef",ref:c},null,512)],512),y.batchImages&&y.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",Ut,[t.createElementVNode("button",{onClick:$e,disabled:p.value<=0},[t.createVNode(E,{name:"back"}),s[8]||(s[8]=t.createTextVNode(" 上一张 ",-1))],8,Ft),t.createElementVNode("span",null,t.toDisplayString(p.value+1)+" / "+t.toDisplayString(y.batchImages.length),1),t.createElementVNode("button",{onClick:Pe,disabled:p.value>=y.batchImages.length-1},[s[9]||(s[9]=t.createTextVNode(" 下一张 ",-1)),t.createVNode(E,{name:"right"})],8,Ot)])):t.createCommentVNode("",!0)]),y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Wt,[t.createElementVNode("div",{class:"sidebar-header"},[s[10]||(s[10]=t.createElementVNode("h3",null,"标签管理",-1)),t.createElementVNode("button",{class:"add-btn",onClick:Se},"添加标签")]),t.createElementVNode("div",jt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(m.value,l=>(t.openBlock(),t.createElementBlock("div",{key:l.id,class:"label-item"},[t.createElementVNode("div",Jt,[t.createElementVNode("label",{class:"color-wrapper",style:t.normalizeStyle({backgroundColor:l.color})},[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":g=>l.color=g,onChange:g=>ze(l),style:{visibility:"hidden",width:"0",height:"0"}},null,40,Xt),[[t.vModelText,l.color]])],4),t.createElementVNode("span",{class:"label-name",title:l.name},t.toDisplayString(l.name),9,Yt),t.createElementVNode("span",{class:"action-icon eye",onClick:g=>Me(l)},[l.visible?(t.openBlock(),t.createBlock(E,{key:0,name:"view"})):(t.openBlock(),t.createBlock(E,{key:1,name:"hide"}))],8,qt),t.createElementVNode("div",Gt,[s[11]||(s[11]=t.createElementVNode("span",{class:"dots"},"•••",-1)),t.createElementVNode("span",{class:"delete-btn",onClick:g=>Te(l.id),title:"删除"},[t.createVNode(E,{name:"delete"})],8,Kt)])])]))),128))])])),k.value?(t.openBlock(),t.createElementBlock("div",Zt,[t.createElementVNode("div",Qt,[s[14]||(s[14]=t.createElementVNode("h3",null,"新增标签",-1)),t.createElementVNode("div",te,[s[12]||(s[12]=t.createElementVNode("label",null,"名称",-1)),t.withDirectives(t.createElementVNode("input",{"onUpdate:modelValue":s[2]||(s[2]=l=>B.value.name=l),placeholder:"请输入标签名称",class:"modal-input"},null,512),[[t.vModelText,B.value.name]])]),t.createElementVNode("div",ee,[s[13]||(s[13]=t.createElementVNode("label",null,"颜色",-1)),t.createElementVNode("div",ne,[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":s[3]||(s[3]=l=>B.value.color=l),class:"modal-color-picker"},null,512),[[t.vModelText,B.value.color]]),t.createElementVNode("span",null,t.toDisplayString(B.value.color),1)])]),t.createElementVNode("div",{class:"modal-actions"},[t.createElementVNode("button",{onClick:Z,class:"cancel-btn"},"取消"),t.createElementVNode("button",{onClick:Ve,class:"confirm-btn"},"确认")])])])):t.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-22c2957b"]]),oe={class:"thumbnail-wrapper",ref:"wrapper"},se=["src","alt"],ie=["viewBox"],ae=["x","y","width","height","stroke"],le=["points","stroke"],re=["x","y","fill"],ce={key:1,class:"loading-placeholder"},he=P(t.defineComponent({__name:"AnnotationThumbnail",props:{src:{},annotations:{},alt:{},labels:{}},setup(y){const e=y,i=t.ref(null),n=t.ref(!1),r=t.ref(0),c=t.ref(0),h=()=>{i.value&&(r.value=i.value.naturalWidth,c.value=i.value.naturalHeight,n.value=!0)},a=m=>{var u;if((u=m.style)!=null&&u.strokeColor)return m.style.strokeColor;if(e.labels){const k=e.labels.find(B=>B.name===m.label);if(k)return k.color}return"#FF0000"},d=m=>{const u=m.coordinates,k=Math.min(u.x1,u.x2),B=Math.min(u.y1,u.y2),S=Math.abs(u.x1-u.x2),V=Math.abs(u.y1-u.y2);return{x:k,y:B,width:S,height:V}},p=m=>m.coordinates.points.map(k=>`${k.x},${k.y}`).join(" "),b=m=>{if(m.type==="rectangle"){const u=d(m);return{x:u.x,y:u.y-5}}else if(m.type==="polygon"){const u=m.coordinates.points;if(u.length>0)return{x:u[0].x,y:u[0].y-5}}return{x:0,y:0}};return(m,u)=>(t.openBlock(),t.createElementBlock("div",oe,[t.createElementVNode("img",{ref_key:"img",ref:i,src:y.src,class:"thumbnail-image",onLoad:h,alt:y.alt},null,40,se),n.value?(t.openBlock(),t.createElementBlock("svg",{key:0,class:"annotation-overlay",viewBox:`0 0 ${r.value} ${c.value}`,preserveAspectRatio:"none"},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.annotations,k=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:k.id},[k.type==="rectangle"?(t.openBlock(),t.createElementBlock("rect",{key:0,x:d(k).x,y:d(k).y,width:d(k).width,height:d(k).height,stroke:a(k),"stroke-width":"2",fill:"transparent"},null,8,ae)):t.createCommentVNode("",!0),k.type==="polygon"?(t.openBlock(),t.createElementBlock("polygon",{key:1,points:p(k),stroke:a(k),"stroke-width":"2",fill:"transparent"},null,8,le)):t.createCommentVNode("",!0),k.label?(t.openBlock(),t.createElementBlock("text",{key:2,x:b(k).x,y:b(k).y,fill:a(k),"font-size":"14","font-weight":"bold",class:"anno-label"},t.toDisplayString(k.label),9,re)):t.createCommentVNode("",!0)],64))),128))],8,ie)):(t.openBlock(),t.createElementBlock("div",ce,"Loading..."))],512))}}),[["__scopeId","data-v-78bcbe0c"]]),de={class:"batch-annotator"},ge={key:0,class:"gallery-view"},me={class:"gallery-header"},fe={class:"label-summary"},ue={class:"gallery-grid"},pe=["onClick"],ye={class:"thumbnail-wrapper"},ve={class:"img-meta"},xe={class:"img-index"},be={class:"anno-count"},we={key:0,class:"bottom-bar"},ke={key:1,class:"editor-view"},Ce={class:"editor-header"},_e={class:"header-left"},Ae={class:"editor-title"},Ie={class:"editor-content"},Y=P(t.defineComponent({__name:"BatchAnnotator",props:{images:{},labels:{},actionBar:{},clickToEnterEditor:{type:Boolean}},emits:["export","update:images","imageClick"],setup(y,{expose:e,emit:i}){const n=y,r=i,c=t.ref("gallery"),h=t.ref([]),a=t.ref(0),d=t.ref(null),p=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.annotateButton)==null?void 0:x.show)===!0}),b=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.exportButton)==null?void 0:x.show)===!0}),m=t.computed(()=>p.value||b.value),u=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.annotateButton)==null?void 0:x.text)||"手动标注"}),k=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.exportButton)==null?void 0:x.text)||"导出"}),B=t.computed(()=>n.clickToEnterEditor!==!1);t.watch(()=>n.images,v=>{h.value=JSON.parse(JSON.stringify(v))},{immediate:!0,deep:!0});const S=v=>{a.value=v,c.value="editor",t.nextTick(()=>{d.value&&d.value.jumpTo&&d.value.jumpTo(v)})},V=(v,x)=>{if(B.value){S(v);return}r("imageClick",{index:v,imageId:x.id,image:x})},T=v=>h.value.findIndex(x=>x.id===v);e({openImageById:v=>{const x=T(v);return x<0?!1:(S(x),!0)},triggerImageClickById:v=>{const x=T(v);if(x<0)return!1;const _=h.value[x];return _?(r("imageClick",{index:x,imageId:_.id,image:_}),!0):!1}});const D=()=>{if(d.value&&d.value.getCurrentAnnotation){const v=d.value.getCurrentAnnotation();h.value[a.value]&&(h.value[a.value].annotations=v.annotations)}c.value="gallery"},N=()=>{r("export",h.value)},U=v=>{a.value=v.currentIndex,h.value[v.currentIndex]&&(h.value[v.currentIndex].annotations=v.currentAnnotations)},F=v=>{if(d.value&&d.value.getCurrentAnnotation){const x=d.value.getCurrentAnnotation();h.value[a.value]&&(h.value[a.value].annotations=x.annotations,r("update:images",h.value))}},O=v=>{};return(v,x)=>(t.openBlock(),t.createElementBlock("div",de,[c.value==="gallery"?(t.openBlock(),t.createElementBlock("div",ge,[t.createElementVNode("div",me,[t.createElementVNode("h3",null,"批量查看与标注 ("+t.toDisplayString(h.value.length)+" 张)",1),t.createElementVNode("div",fe,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.labels,_=>(t.openBlock(),t.createElementBlock("span",{key:_.id,class:"label-badge",style:t.normalizeStyle({backgroundColor:_.color})},t.toDisplayString(_.name),5))),128))])]),t.createElementVNode("div",ue,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(h.value,(_,z)=>(t.openBlock(),t.createElementBlock("div",{key:z,class:"gallery-item",onClick:G=>V(z,_)},[t.createElementVNode("div",ye,[t.createVNode(he,{src:_.imageUrl,annotations:_.annotations||[],labels:y.labels},null,8,["src","annotations","labels"])]),t.createElementVNode("div",ve,[t.createElementVNode("span",xe,"#"+t.toDisplayString(z+1),1),t.createElementVNode("span",be,t.toDisplayString((_.annotations||[]).length)+" 标注",1)])],8,pe))),128))]),m.value?(t.openBlock(),t.createElementBlock("div",we,[p.value?(t.openBlock(),t.createElementBlock("button",{key:0,class:"action-btn primary",onClick:x[0]||(x[0]=_=>S(0))},[t.createVNode(E,{name:"edit"}),t.createTextVNode(" "+t.toDisplayString(u.value),1)])):t.createCommentVNode("",!0),b.value?(t.openBlock(),t.createElementBlock("button",{key:1,class:"action-btn success",onClick:N},[t.createVNode(E,{name:"download"}),t.createTextVNode(" "+t.toDisplayString(k.value),1)])):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0)])):(t.openBlock(),t.createElementBlock("div",ke,[t.createElementVNode("div",Ce,[t.createElementVNode("div",_e,[t.createElementVNode("button",{class:"back-btn",onClick:D},[t.createVNode(E,{name:"back"}),x[1]||(x[1]=t.createTextVNode(" 返回列表 ",-1))]),t.createElementVNode("span",Ae,"正在标注: "+t.toDisplayString(a.value+1)+" / "+t.toDisplayString(h.value.length),1)])]),t.createElementVNode("div",Ie,[t.createVNode(X,{ref_key:"annotatorRef",ref:d,batchImages:h.value,labels:y.labels,annotationTypes:["rectangle","polygon","point","rotatedRect"],onBatchChange:U,onAnnotationChange:F,onLabelChange:O},null,8,["batchImages","labels"])])]))]))}}),[["__scopeId","data-v-419d7955"]]);I.BatchAnnotator=Y,I.ImageAnnotator=X,I.default=Y,Object.defineProperties(I,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
33
+ </svg>`,wt=["innerHTML"],kt=t.defineComponent({__name:"SvgIcon",props:{name:{},size:{}},setup(y){const e=y,i=t.ref(""),n=Object.assign({"../assets/svg/aim.svg":it,"../assets/svg/back.svg":at,"../assets/svg/connection.svg":lt,"../assets/svg/crop.svg":rt,"../assets/svg/delete.svg":ct,"../assets/svg/download.svg":ht,"../assets/svg/edit.svg":dt,"../assets/svg/hide.svg":gt,"../assets/svg/pointer.svg":mt,"../assets/svg/price-tag.svg":ft,"../assets/svg/rank.svg":ut,"../assets/svg/refresh-right.svg":pt,"../assets/svg/right.svg":yt,"../assets/svg/view.svg":vt,"../assets/svg/zoom-in.svg":xt,"../assets/svg/zoom-out.svg":bt});return t.watchEffect(()=>{const r=`../assets/svg/${e.name}.svg`,c=n[r];c?i.value=c:(console.warn(`Icon ${e.name} not found at path ${r}`),i.value="")}),(r,c)=>(t.openBlock(),t.createElementBlock("i",{class:t.normalizeClass(["svg-icon",[y.size?`size-${y.size}`:""]]),innerHTML:i.value},null,10,wt))}}),P=(y,e)=>{const i=y.__vccOpts||y;for(const[n,r]of e)i[n]=r;return i},E=P(kt,[["__scopeId","data-v-3928607b"]]),Ct={key:0,class:"image-list-sidebar"},_t={class:"image-list-title"},At={class:"image-list-scroll"},It=["onClick"],Bt={class:"image-list-stage"},Et=["src","alt"],St={key:0,class:"thumb-overlay-layer"},Vt={key:1,class:"thumb-overlay-svg",viewBox:"0 0 100 100",preserveAspectRatio:"none"},Nt=["points"],zt={class:"image-list-text"},Mt={key:1,class:"left-sidebar"},Tt=["onClick","title"],$t={class:"center-area"},Pt={key:0,class:"top-bar"},Dt={class:"label-selector"},Lt={class:"tags-row"},Ht=["onClick"],Rt={key:0,class:"no-labels"},Ut={key:1,class:"batch-nav"},Ft=["disabled"],Ot=["disabled"],Wt={key:2,class:"right-sidebar"},jt={class:"label-list"},Jt={class:"label-row"},Xt=["onUpdate:modelValue","onChange"],Yt=["title"],qt=["onClick"],Gt={class:"action-icon more-actions"},Kt=["onClick"],Zt={key:3,class:"modal-overlay"},Qt={class:"modal-content"},te={class:"form-group"},ee={class:"form-group"},ne={class:"color-input-wrapper"},X=P(t.defineComponent({__name:"ImageAnnotator",props:{annotationTypes:{default:()=>["rectangle","polygon","point","rotatedRect"]},batchImages:{default:()=>[]},labels:{default:()=>[]},defaultActiveType:{},theme:{default:"light"},readOnly:{type:Boolean,default:!1},image:{},predictionCandidates:{},session:{},requestId:{},minZoom:{},maxZoom:{}},emits:["annotationChange","batchChange","labelChange","ready","error","tool:change","viewport:change","annotation:add","annotation:update","annotation:delete","annotation:select","prediction:loaded","prediction:apply","prediction:reject"],setup(y,{expose:e,emit:i}){const n=y,r=i,c=t.ref(null),h=t.ref(null),a=t.ref(null),d=t.ref(null),p=t.ref(0),b=t.ref(""),m=t.ref([]),u=t.ref(""),k=t.ref(!1),B=t.ref({name:"",color:"#FF0000"}),S=t.ref("none"),V=t.ref([]),T=t.ref({}),q=t.computed(()=>d.value==="select"&&!!b.value),R=o=>{if(!o||T.value[o])return;const s=new Image;s.onload=()=>{const l=s.naturalWidth||1,g=s.naturalHeight||1;T.value={...T.value,[o]:{width:l,height:g}}},s.src=o},D=()=>{n.batchImages.forEach(o=>{R(o.imageUrl)})},N=()=>{var l,g,f,w;const o=n.batchImages[p.value],s=(o==null?void 0:o.imageUrl)||((l=n.image)==null?void 0:l.url);return{eventId:`${Date.now()}-${Math.random().toString(36).slice(2,10)}`,timestamp:Date.now(),requestId:n.requestId,taskId:(g=n.session)==null?void 0:g.taskId,imageId:((f=n.image)==null?void 0:f.id)||s,operator:(w=n.session)==null?void 0:w.userId}},U=o=>{var g;const s=o==null?void 0:o.action;if(!s)return;const l={meta:N(),action:s,current:o==null?void 0:o.changedItem,source:(g=o==null?void 0:o.changedItem)!=null&&g.predictionId?"prediction":"manual"};s==="add"&&r("annotation:add",l),s==="update"&&r("annotation:update",l),s==="delete"&&r("annotation:delete",l),s==="select"&&r("annotation:select",l)},F=t.computed(()=>n.annotationTypes.filter(o=>o!=="category")),O=o=>({rectangle:"crop",polygon:"connection",point:"aim",rotatedRect:"refresh-right",category:"price-tag"})[o]||o,v=o=>({rectangle:"矩形框",polygon:"多边形",point:"关键点",rotatedRect:"旋转矩形",category:"分类标签"})[o]||o;t.onMounted(()=>{if(D(),c.value){a.value=new st(c.value),a.value.on("annotationChange",s=>{var l,g;if(s.action==="add"&&s.changedItem){const f=m.value.find(w=>w.id===u.value);f&&(s.changedItem.label=f.name,s.changedItem.labelId=f.id)}s.action==="select"?b.value=((l=s.changedItem)==null?void 0:l.id)||"":s.action==="delete"&&((g=s.changedItem)==null?void 0:g.id)===b.value&&(b.value=""),r("annotationChange",s),U(s)}),_(),x();const o=new ResizeObserver(()=>{var s;(s=a.value)==null||s.resize()});h.value&&o.observe(h.value),n.defaultActiveType&&z(n.defaultActiveType),r("ready",{meta:N()})}});const x=()=>{if(!a.value)return;const o=m.value.find(l=>l.id===u.value);o&&a.value.setLabelStyle(o.color);const s=m.value.filter(l=>l.visible).map(l=>l.name);a.value.setVisibleLabels(s)},_=()=>{var o;if(a.value)if(b.value="",n.batchImages.length>0){const s=n.batchImages[p.value];a.value.loadImage(s.imageUrl),s.annotations?a.value.setAnnotations(s.annotations):a.value.setAnnotations([])}else(o=n.image)!=null&&o.url&&a.value.loadImage(n.image.url)},z=o=>{var s,l;if(d.value=o,b.value="",o!=="pan"&&o!=="select"&&m.value.length===0){alert("请先创建标签!");return}o==="pan"||o==="select"?(s=a.value)==null||s.setTool(o):(l=a.value)==null||l.setTool(o),r("tool:change",{meta:N(),tool:o})},G=()=>{var o;(o=a.value)!=null&&o.activeAnnotation&&a.value.deleteAnnotation(a.value.activeAnnotation.id)},K=()=>{a.value&&r("viewport:change",{meta:N(),scale:a.value.scale,offset:{...a.value.offset}})},Be=()=>{var o;(o=a.value)==null||o.zoom(1),K()},Ee=()=>{var o;(o=a.value)==null||o.zoom(-1),K()},Se=()=>{B.value={name:"",color:"#2196F3"},k.value=!0},Z=()=>{k.value=!1},Ve=()=>{if(!B.value.name.trim()){alert("请输入标签名称");return}const s={id:Date.now().toString(),name:B.value.name,color:B.value.color,visible:!0};m.value.push(s),r("labelChange",m.value),m.value.length===1&&$(s),Z()},$=o=>{var s;u.value=o.id,(s=a.value)==null||s.setLabelStyle(o.color)},Ne=(o,s)=>{if(!o.startsWith("#"))return o;let l=0,g=0,f=0;return o.length===4?(l=parseInt(o[1]+o[1],16),g=parseInt(o[2]+o[2],16),f=parseInt(o[3]+o[3],16)):o.length===7&&(l=parseInt(o.slice(1,3),16),g=parseInt(o.slice(3,5),16),f=parseInt(o.slice(5,7),16)),`rgba(${l}, ${g}, ${f}, ${s})`},ze=o=>{var s;if(o.id===u.value&&((s=a.value)==null||s.setLabelStyle(o.color)),a.value){const l=a.value.getAnnotations();let g=!1;l.forEach(f=>{f.label===o.name&&(f.style||(f.style={}),f.style.strokeColor=o.color,f.style.fillColor=Ne(o.color,.2),g=!0)}),g&&a.value.render()}r("labelChange",m.value)},Me=o=>{o.visible=!o.visible,x()},Te=o=>{const s=m.value.findIndex(l=>l.id===o);s>-1&&(m.value.splice(s,1),r("labelChange",m.value),u.value===o&&(u.value=m.value.length>0?m.value[0].id:"",u.value&&$(m.value[0])),x())};t.watch(()=>n.labels,o=>{const s=JSON.parse(JSON.stringify(o||[]));if(m.value=s,m.value.length>0)if(!u.value||!m.value.find(l=>l.id===u.value))$(m.value[0]);else{const l=m.value.find(g=>g.id===u.value);l&&$(l)}else u.value="";x()},{immediate:!0,deep:!0});const $e=()=>{p.value>0&&(W(),p.value--,_(),j())},Pe=()=>{p.value<n.batchImages.length-1&&(W(),p.value++,_(),j())},W=()=>{if(a.value){const o=a.value.getAnnotations();n.batchImages[p.value].annotations=o}},j=()=>{const o=n.batchImages[p.value];r("batchChange",{currentIndex:p.value,total:n.batchImages.length,currentImageUrl:o.imageUrl,currentAnnotations:o.annotations||[]})},Q=(o=[])=>{var f;if(!a.value)return;if(V.value=JSON.parse(JSON.stringify(o)),V.value.length===0){S.value="none";return}S.value="loaded";const l=(a.value.getAnnotations()||[]).filter(w=>!w.predictionId),g=V.value.map(w=>{const A=JSON.parse(JSON.stringify(w.annotation));return A.id=A.id||`pred-${w.id}`,A.predictionId=w.id,A.modelRunId=w.modelRunId||A.modelRunId,A.confidence=w.confidence??A.confidence,A.reviewStatus=A.reviewStatus||"draft",A});a.value.setAnnotations([...l,...g]),r("prediction:loaded",{meta:N(),modelRunId:(f=V.value[0])==null?void 0:f.modelRunId,candidates:V.value})},De=(o,s)=>{var f;if(!a.value)return[];S.value="applying";const g=(a.value.getAnnotations()||[]).filter(w=>w.predictionId&&o.includes(w.predictionId));return g.forEach(w=>{w.reviewStatus="accepted"}),S.value="applied",r("prediction:apply",{meta:N(),modelRunId:(f=g[0])==null?void 0:f.modelRunId,candidateIds:o,threshold:s,acceptedAnnotations:g}),a.value.render(),g},Le=(o,s)=>{var f;if(!a.value)return;const l=a.value.getAnnotations()||[],g=l.filter(w=>!(w.predictionId&&o.includes(w.predictionId)));a.value.setAnnotations(g),r("prediction:reject",{meta:N(),modelRunId:(f=l.find(w=>w.predictionId&&o.includes(w.predictionId)))==null?void 0:f.modelRunId,candidateIds:o,reason:s})},He=(o,s=[])=>{a.value&&(a.value.loadImage(o.url),a.value.setAnnotations(s))},Re=o=>{var s;(s=a.value)==null||s.setAnnotations(o)},tt=()=>{var o;return((o=a.value)==null?void 0:o.getAnnotations())||[]},Ue=(o="json")=>{var l,g;const s=tt();return{format:o,image:((l=n.batchImages[p.value])==null?void 0:l.imageUrl)||((g=n.image)==null?void 0:g.url)||"",annotations:s}},et=o=>{o>=0&&o<n.batchImages.length&&(W(),p.value=o,_(),j())},Fe=o=>{var s;return o===p.value&&a.value?a.value.getAnnotations()||[]:((s=n.batchImages[o])==null?void 0:s.annotations)||[]},Oe=o=>o.type==="rectangle",We=o=>o.type==="polygon",je=o=>o.type==="point",Je=o=>o.type==="rotatedRect",L=o=>{var l,g;const s=(l=m.value.find(f=>f.name===o.label))==null?void 0:l.color;return((g=o.style)==null?void 0:g.strokeColor)||s||"#409eff"},nt=o=>{const s=o.coordinates;return(s==null?void 0:s.points)||[]},H=o=>{const s=n.batchImages[o];if(s!=null&&s.width&&(s!=null&&s.height))return{width:s.width,height:s.height};const l=s!=null&&s.imageUrl?T.value[s.imageUrl]:void 0;return l||(s!=null&&s.imageUrl&&R(s.imageUrl),{width:1,height:1})},Xe=o=>{const s=n.batchImages[o];return s!=null&&s.width&&(s!=null&&s.height)?!0:s!=null&&s.imageUrl?!!T.value[s.imageUrl]:!1},Ye=(o,s)=>{const l=s.coordinates,g=H(o),f=L(s),w=Math.min(l.x1,l.x2),A=Math.min(l.y1,l.y2),Qe=Math.max(l.x1,l.x2),tn=Math.max(l.y1,l.y2);return{left:`${w/g.width*100}%`,top:`${A/g.height*100}%`,width:`${(Qe-w)/g.width*100}%`,height:`${(tn-A)/g.height*100}%`,borderColor:f,backgroundColor:`${f}22`}},qe=(o,s)=>{const l=H(o);return nt(s).map(g=>`${g.x/l.width*100},${g.y/l.height*100}`).join(" ")},Ge=o=>{const s=L(o);return{fill:`${s}33`,stroke:s,strokeWidth:"1.4"}},Ke=(o,s,l)=>{const g=H(o),f=L(l);return{left:`${s.x/g.width*100}%`,top:`${s.y/g.height*100}%`,backgroundColor:f}},Ze=(o,s)=>{const l=s.coordinates,g=H(o),f=L(s),w=Math.abs(l.width),A=Math.abs(l.height);return{left:`${(l.x-w/2)/g.width*100}%`,top:`${(l.y-A/2)/g.height*100}%`,width:`${w/g.width*100}%`,height:`${A/g.height*100}%`,transform:`rotate(${l.angle||0}deg)`,borderColor:f,backgroundColor:`${f}22`}};return e({jumpTo:et,setImage:He,setAnnotations:Re,getAnnotations:tt,selectTool:z,loadPredictionCandidates:Q,applyPredictions:De,rejectPredictions:Le,exportAnnotations:Ue,getAllAnnotations:()=>{var o,s;return n.batchImages.length>0?n.batchImages:[{imageUrl:((o=n.image)==null?void 0:o.url)||"",annotations:((s=a.value)==null?void 0:s.getAnnotations())||[]}]},getCurrentAnnotation:()=>{var o,s,l;return{imageUrl:((o=n.batchImages[p.value])==null?void 0:o.imageUrl)||((s=n.image)==null?void 0:s.url)||"",annotations:((l=a.value)==null?void 0:l.getAnnotations())||[]}}}),t.watch(()=>{var o;return(o=n.image)==null?void 0:o.url},()=>{var o;n.batchImages.length===0&&((o=n.image)!=null&&o.url)&&_()}),t.watch(()=>n.predictionCandidates,o=>{o&&Q(o)},{immediate:!0,deep:!0}),t.watch(()=>n.batchImages.map(o=>`${o.imageUrl}:${o.width||""}x${o.height||""}`),()=>{D()},{immediate:!0}),(o,s)=>(t.openBlock(),t.createElementBlock("div",{class:t.normalizeClass(["annotation-container",y.theme])},[y.batchImages&&y.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",Ct,[t.createElementVNode("div",_t,"批量图片("+t.toDisplayString(y.batchImages.length)+")",1),t.createElementVNode("div",At,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.batchImages,(l,g)=>(t.openBlock(),t.createElementBlock("button",{key:`${l.imageUrl}-${g}`,class:t.normalizeClass(["image-list-item",{active:g===p.value}]),onClick:f=>et(g)},[t.createElementVNode("div",Bt,[t.createElementVNode("img",{src:l.imageUrl,alt:`第${g+1}张`,class:"image-list-thumb"},null,8,Et),Xe(g)?(t.openBlock(),t.createElementBlock("div",St,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(Fe(g),f=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:f.id},[Oe(f)?(t.openBlock(),t.createElementBlock("div",{key:0,class:"thumb-overlay-rect",style:t.normalizeStyle(Ye(g,f))},null,4)):We(f)?(t.openBlock(),t.createElementBlock("svg",Vt,[t.createElementVNode("polygon",{points:qe(g,f),style:t.normalizeStyle(Ge(f))},null,12,Nt)])):je(f)?(t.openBlock(!0),t.createElementBlock(t.Fragment,{key:2},t.renderList(nt(f),(w,A)=>(t.openBlock(),t.createElementBlock("div",{key:`${f.id}-${A}`,class:"thumb-overlay-point",style:t.normalizeStyle(Ke(g,w,f))},null,4))),128)):Je(f)?(t.openBlock(),t.createElementBlock("div",{key:3,class:"thumb-overlay-rotated",style:t.normalizeStyle(Ze(g,f))},null,4)):t.createCommentVNode("",!0)],64))),128))])):t.createCommentVNode("",!0)]),t.createElementVNode("span",zt,"第 "+t.toDisplayString(g+1)+" 张",1)],10,It))),128))])])):t.createCommentVNode("",!0),y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Mt,[t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:d.value==="pan"}]),onClick:s[0]||(s[0]=l=>z("pan")),title:"拖动"},[t.createVNode(E,{name:"rank"})],2),t.createElementVNode("div",{class:t.normalizeClass(["tool-btn",{active:d.value==="select"}]),onClick:s[1]||(s[1]=l=>z("select")),title:"选择"},[t.createVNode(E,{name:"pointer"})],2),s[4]||(s[4]=t.createElementVNode("div",{class:"divider"},null,-1)),(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(F.value,l=>(t.openBlock(),t.createElementBlock("div",{key:l,class:t.normalizeClass(["tool-btn",{active:d.value===l}]),onClick:g=>z(l),title:v(l)},[t.createVNode(E,{name:O(l)},null,8,["name"])],10,Tt))),128)),s[5]||(s[5]=t.createElementVNode("div",{class:"divider"},null,-1)),t.createElementVNode("div",{class:"tool-btn",onClick:Be,title:"放大"},[t.createVNode(E,{name:"zoom-in"})]),t.createElementVNode("div",{class:"tool-btn",onClick:Ee,title:"缩小"},[t.createVNode(E,{name:"zoom-out"})]),s[6]||(s[6]=t.createElementVNode("div",{class:"divider"},null,-1)),q.value?(t.openBlock(),t.createElementBlock("div",{key:0,class:"tool-btn",onClick:G,title:"删除选中"},[t.createVNode(E,{name:"delete"})])):t.createCommentVNode("",!0)])),t.createElementVNode("div",$t,[y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Pt,[t.createElementVNode("div",Dt,[s[7]||(s[7]=t.createElementVNode("span",{class:"label-text"},"当前标签:",-1)),t.createElementVNode("div",Lt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(m.value,l=>(t.openBlock(),t.createElementBlock("div",{key:l.id,class:t.normalizeClass(["tag-chip",{active:u.value===l.id}]),style:t.normalizeStyle({backgroundColor:l.color,borderColor:l.color}),onClick:g=>$(l)},t.toDisplayString(l.name),15,Ht))),128)),m.value.length===0?(t.openBlock(),t.createElementBlock("div",Rt,"请在右侧创建标签")):t.createCommentVNode("",!0)])])])),t.createElementVNode("div",{class:"canvas-wrapper",ref_key:"canvasWrapper",ref:h},[t.createElementVNode("canvas",{ref_key:"canvasRef",ref:c},null,512)],512),y.batchImages&&y.batchImages.length>0?(t.openBlock(),t.createElementBlock("div",Ut,[t.createElementVNode("button",{onClick:$e,disabled:p.value<=0},[t.createVNode(E,{name:"back"}),s[8]||(s[8]=t.createTextVNode(" 上一张 ",-1))],8,Ft),t.createElementVNode("span",null,t.toDisplayString(p.value+1)+" / "+t.toDisplayString(y.batchImages.length),1),t.createElementVNode("button",{onClick:Pe,disabled:p.value>=y.batchImages.length-1},[s[9]||(s[9]=t.createTextVNode(" 下一张 ",-1)),t.createVNode(E,{name:"right"})],8,Ot)])):t.createCommentVNode("",!0)]),y.readOnly?t.createCommentVNode("",!0):(t.openBlock(),t.createElementBlock("div",Wt,[t.createElementVNode("div",{class:"sidebar-header"},[s[10]||(s[10]=t.createElementVNode("h3",null,"标签管理",-1)),t.createElementVNode("button",{class:"add-btn",onClick:Se},"添加标签")]),t.createElementVNode("div",jt,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(m.value,l=>(t.openBlock(),t.createElementBlock("div",{key:l.id,class:"label-item"},[t.createElementVNode("div",Jt,[t.createElementVNode("label",{class:"color-wrapper",style:t.normalizeStyle({backgroundColor:l.color})},[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":g=>l.color=g,onChange:g=>ze(l),style:{visibility:"hidden",width:"0",height:"0"}},null,40,Xt),[[t.vModelText,l.color]])],4),t.createElementVNode("span",{class:"label-name",title:l.name},t.toDisplayString(l.name),9,Yt),t.createElementVNode("span",{class:"action-icon eye",onClick:g=>Me(l)},[l.visible?(t.openBlock(),t.createBlock(E,{key:0,name:"view"})):(t.openBlock(),t.createBlock(E,{key:1,name:"hide"}))],8,qt),t.createElementVNode("div",Gt,[s[11]||(s[11]=t.createElementVNode("span",{class:"dots"},"•••",-1)),t.createElementVNode("span",{class:"delete-btn",onClick:g=>Te(l.id),title:"删除"},[t.createVNode(E,{name:"delete"})],8,Kt)])])]))),128))])])),k.value?(t.openBlock(),t.createElementBlock("div",Zt,[t.createElementVNode("div",Qt,[s[14]||(s[14]=t.createElementVNode("h3",null,"新增标签",-1)),t.createElementVNode("div",te,[s[12]||(s[12]=t.createElementVNode("label",null,"名称",-1)),t.withDirectives(t.createElementVNode("input",{"onUpdate:modelValue":s[2]||(s[2]=l=>B.value.name=l),placeholder:"请输入标签名称",class:"modal-input"},null,512),[[t.vModelText,B.value.name]])]),t.createElementVNode("div",ee,[s[13]||(s[13]=t.createElementVNode("label",null,"颜色",-1)),t.createElementVNode("div",ne,[t.withDirectives(t.createElementVNode("input",{type:"color","onUpdate:modelValue":s[3]||(s[3]=l=>B.value.color=l),class:"modal-color-picker"},null,512),[[t.vModelText,B.value.color]]),t.createElementVNode("span",null,t.toDisplayString(B.value.color),1)])]),t.createElementVNode("div",{class:"modal-actions"},[t.createElementVNode("button",{onClick:Z,class:"cancel-btn"},"取消"),t.createElementVNode("button",{onClick:Ve,class:"confirm-btn"},"确认")])])])):t.createCommentVNode("",!0)],2))}}),[["__scopeId","data-v-22c2957b"]]),oe={class:"thumbnail-wrapper",ref:"wrapper"},se=["src","alt"],ie=["viewBox"],ae=["x","y","width","height","stroke"],le=["points","stroke"],re=["x","y","fill"],ce={key:1,class:"loading-placeholder"},he=P(t.defineComponent({__name:"AnnotationThumbnail",props:{src:{},annotations:{},alt:{},labels:{}},setup(y){const e=y,i=t.ref(null),n=t.ref(!1),r=t.ref(0),c=t.ref(0),h=()=>{i.value&&(r.value=i.value.naturalWidth,c.value=i.value.naturalHeight,n.value=!0)},a=m=>{var u;if((u=m.style)!=null&&u.strokeColor)return m.style.strokeColor;if(e.labels){const k=e.labels.find(B=>B.name===m.label);if(k)return k.color}return"#FF0000"},d=m=>{const u=m.coordinates,k=Math.min(u.x1,u.x2),B=Math.min(u.y1,u.y2),S=Math.abs(u.x1-u.x2),V=Math.abs(u.y1-u.y2);return{x:k,y:B,width:S,height:V}},p=m=>m.coordinates.points.map(k=>`${k.x},${k.y}`).join(" "),b=m=>{if(m.type==="rectangle"){const u=d(m);return{x:u.x,y:u.y-5}}else if(m.type==="polygon"){const u=m.coordinates.points;if(u.length>0)return{x:u[0].x,y:u[0].y-5}}return{x:0,y:0}};return(m,u)=>(t.openBlock(),t.createElementBlock("div",oe,[t.createElementVNode("img",{ref_key:"img",ref:i,src:y.src,class:"thumbnail-image",onLoad:h,alt:y.alt},null,40,se),n.value?(t.openBlock(),t.createElementBlock("svg",{key:0,class:"annotation-overlay",viewBox:`0 0 ${r.value} ${c.value}`,preserveAspectRatio:"none"},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.annotations,k=>(t.openBlock(),t.createElementBlock(t.Fragment,{key:k.id},[k.type==="rectangle"?(t.openBlock(),t.createElementBlock("rect",{key:0,x:d(k).x,y:d(k).y,width:d(k).width,height:d(k).height,stroke:a(k),"stroke-width":"2",fill:"transparent"},null,8,ae)):t.createCommentVNode("",!0),k.type==="polygon"?(t.openBlock(),t.createElementBlock("polygon",{key:1,points:p(k),stroke:a(k),"stroke-width":"2",fill:"transparent"},null,8,le)):t.createCommentVNode("",!0),k.label?(t.openBlock(),t.createElementBlock("text",{key:2,x:b(k).x,y:b(k).y,fill:a(k),"font-size":"14","font-weight":"bold",class:"anno-label"},t.toDisplayString(k.label),9,re)):t.createCommentVNode("",!0)],64))),128))],8,ie)):(t.openBlock(),t.createElementBlock("div",ce,"Loading..."))],512))}}),[["__scopeId","data-v-78bcbe0c"]]),de={class:"batch-annotator"},ge={key:0,class:"gallery-view"},me={class:"gallery-header"},fe={class:"label-summary"},ue={class:"gallery-grid"},pe=["onClick"],ye={class:"thumbnail-wrapper"},ve={class:"img-meta"},xe={class:"img-index"},be={class:"anno-count"},we={key:0,class:"bottom-bar"},ke={key:1,class:"editor-view"},Ce={class:"editor-header"},_e={class:"header-left"},Ae={class:"editor-title"},Ie={class:"editor-content"},Y=P(t.defineComponent({__name:"BatchAnnotator",props:{images:{},labels:{},actionBar:{},clickToEnterEditor:{type:Boolean}},emits:["export","update:images","imageClick"],setup(y,{expose:e,emit:i}){const n=y,r=i,c=t.ref("gallery"),h=t.ref([]),a=t.ref(0),d=t.ref(null),p=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.annotateButton)==null?void 0:x.show)===!0}),b=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.exportButton)==null?void 0:x.show)===!0}),m=t.computed(()=>p.value||b.value),u=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.annotateButton)==null?void 0:x.text)||"手动标注"}),k=t.computed(()=>{var v,x;return((x=(v=n.actionBar)==null?void 0:v.exportButton)==null?void 0:x.text)||"导出"}),B=t.computed(()=>n.clickToEnterEditor!==!1);t.watch(()=>n.images,v=>{h.value=JSON.parse(JSON.stringify(v))},{immediate:!0,deep:!0});const S=v=>{a.value=v,c.value="editor",t.nextTick(()=>{d.value&&d.value.jumpTo&&d.value.jumpTo(v)})},V=(v,x)=>{if(B.value){S(v);return}r("imageClick",{index:v,imageId:x.id,image:x})},T=v=>h.value.findIndex(x=>x.id===v);e({openImageById:v=>{const x=T(v);return x<0?!1:(S(x),!0)},triggerImageClickById:v=>{const x=T(v);if(x<0)return!1;const _=h.value[x];return _?(r("imageClick",{index:x,imageId:_.id,image:_}),!0):!1}});const D=()=>{if(d.value&&d.value.getCurrentAnnotation){const v=d.value.getCurrentAnnotation();h.value[a.value]&&(h.value[a.value].annotations=v.annotations)}c.value="gallery"},N=()=>{r("export",h.value)},U=v=>{a.value=v.currentIndex,h.value[v.currentIndex]&&(h.value[v.currentIndex].annotations=v.currentAnnotations)},F=v=>{if(d.value&&d.value.getCurrentAnnotation){const x=d.value.getCurrentAnnotation();h.value[a.value]&&(h.value[a.value].annotations=x.annotations,r("update:images",h.value))}},O=v=>{};return(v,x)=>(t.openBlock(),t.createElementBlock("div",de,[c.value==="gallery"?(t.openBlock(),t.createElementBlock("div",ge,[t.createElementVNode("div",me,[t.createElementVNode("h3",null,"批量查看与标注 ("+t.toDisplayString(h.value.length)+" 张)",1),t.createElementVNode("div",fe,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(y.labels,_=>(t.openBlock(),t.createElementBlock("span",{key:_.id,class:"label-badge",style:t.normalizeStyle({backgroundColor:_.color})},t.toDisplayString(_.name),5))),128))])]),t.createElementVNode("div",ue,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(h.value,(_,z)=>(t.openBlock(),t.createElementBlock("div",{key:z,class:"gallery-item",onClick:G=>V(z,_)},[t.createElementVNode("div",ye,[t.createVNode(he,{src:_.imageUrl,annotations:_.annotations||[],labels:y.labels},null,8,["src","annotations","labels"])]),t.createElementVNode("div",ve,[t.createElementVNode("span",xe,"#"+t.toDisplayString(z+1),1),t.createElementVNode("span",be,t.toDisplayString((_.annotations||[]).length)+" 标注",1)])],8,pe))),128))]),m.value?(t.openBlock(),t.createElementBlock("div",we,[p.value?(t.openBlock(),t.createElementBlock("button",{key:0,class:"action-btn primary",onClick:x[0]||(x[0]=_=>S(0))},[t.createVNode(E,{name:"edit"}),t.createTextVNode(" "+t.toDisplayString(u.value),1)])):t.createCommentVNode("",!0),b.value?(t.openBlock(),t.createElementBlock("button",{key:1,class:"action-btn success",onClick:N},[t.createVNode(E,{name:"download"}),t.createTextVNode(" "+t.toDisplayString(k.value),1)])):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0)])):(t.openBlock(),t.createElementBlock("div",ke,[t.createElementVNode("div",Ce,[t.createElementVNode("div",_e,[t.createElementVNode("button",{class:"back-btn",onClick:D},[t.createVNode(E,{name:"back"}),x[1]||(x[1]=t.createTextVNode(" 返回列表 ",-1))]),t.createElementVNode("span",Ae,"正在标注: "+t.toDisplayString(a.value+1)+" / "+t.toDisplayString(h.value.length),1)])]),t.createElementVNode("div",Ie,[t.createVNode(X,{ref_key:"annotatorRef",ref:d,batchImages:h.value,labels:y.labels,annotationTypes:["rectangle","polygon","point","rotatedRect"],onBatchChange:U,onAnnotationChange:F,onLabelChange:O},null,8,["batchImages","labels"])])]))]))}}),[["__scopeId","data-v-d19b4a14"]]);I.BatchAnnotator=Y,I.ImageAnnotator=X,I.default=Y,Object.defineProperties(I,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luo-image-annotator",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "A simple image annotation component for Vue 3",
5
5
  "scripts": {
6
6
  "dev": "vite",