@servantcdh/ez-planet-labeling 0.1.0

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.
@@ -0,0 +1,836 @@
1
+ import { Canvas } from 'fabric';
2
+ import { fabric } from 'fabric';
3
+ import { FabricObject } from 'fabric';
4
+ import { JSX as JSX_2 } from 'react/jsx-runtime';
5
+ import { ReactNode } from 'react';
6
+ import { StoreApi } from 'zustand';
7
+ import { TemporalState } from 'zundo';
8
+ import { UseBoundStore } from 'zustand';
9
+
10
+ export declare interface Annotation {
11
+ /** Host app assigns this freely (DB PK, UUID, temp ID, etc.) */
12
+ id: string;
13
+ type: AnnotationType;
14
+ label: AnnotationLabel;
15
+ style: AnnotationStyle;
16
+ geometry: AnnotationGeometry | null;
17
+ }
18
+
19
+ export declare type AnnotationGeometry = BoxGeometry | SegmentationGeometry | PolygonGeometry | BrushGeometry | RecognitionGeometry;
20
+
21
+ export declare interface AnnotationLabel {
22
+ name: string;
23
+ index: number;
24
+ }
25
+
26
+ export declare interface AnnotationStyle {
27
+ color: string;
28
+ opacity: number;
29
+ lineColor?: string;
30
+ lineWidth?: number;
31
+ zIndex?: number;
32
+ }
33
+
34
+ /**
35
+ * Convert an Annotation back to Fabric object options (for canvas loading).
36
+ * This creates the configuration that can be used with Fabric's enlivenObjects.
37
+ */
38
+ export declare const annotationToFabricProps: (annotation: Annotation, imageWidth: number, imageHeight: number) => Record<string, unknown>;
39
+
40
+ export declare type AnnotationType = 'box' | 'segmentation' | 'polygon' | 'brush' | 'classification' | 'recognition';
41
+
42
+ export declare const basicBrushes: {
43
+ id: number;
44
+ lineCap: string;
45
+ lineWidth: number;
46
+ }[];
47
+
48
+ export declare const basicColors: string[];
49
+
50
+ export declare const blankRectTool: () => LabelingTool;
51
+
52
+ export declare interface BoxGeometry {
53
+ type: 'box';
54
+ /** Normalized coordinates (0~1 ratio, image-size independent) */
55
+ x: number;
56
+ y: number;
57
+ width: number;
58
+ height: number;
59
+ }
60
+
61
+ export declare interface BrushGeometry {
62
+ type: 'brush';
63
+ /** SVG path or fabric path data */
64
+ path: string;
65
+ }
66
+
67
+ declare interface BrushState {
68
+ brush: {
69
+ id: number;
70
+ lineCap: string;
71
+ lineWidth: number;
72
+ };
73
+ setBrush: (brush: {
74
+ id: number;
75
+ lineCap: string;
76
+ lineWidth: number;
77
+ }) => void;
78
+ }
79
+
80
+ export declare const brushTool: () => LabelingTool;
81
+
82
+ export declare type CanvasAction = {
83
+ type: 'add';
84
+ annotation: Annotation;
85
+ } | {
86
+ type: 'update';
87
+ annotation: Annotation;
88
+ prev: Annotation;
89
+ } | {
90
+ type: 'delete';
91
+ id: string;
92
+ } | {
93
+ type: 'batch';
94
+ added: Annotation[];
95
+ updated: Annotation[];
96
+ deleted: string[];
97
+ };
98
+
99
+ export declare interface CanvasChangeEvent {
100
+ annotations: Annotation[];
101
+ action: CanvasAction;
102
+ }
103
+
104
+ declare interface CanvasExportJSON {
105
+ version: string;
106
+ objects: Record<string, unknown>[];
107
+ }
108
+
109
+ declare interface CanvasJSON {
110
+ version: string;
111
+ objects: LabeledFabricObject[];
112
+ }
113
+
114
+ declare interface CanvasObjectsState {
115
+ objects: LabeledFabricObject[];
116
+ setObjects: (objects: LabeledFabricObject[]) => void;
117
+ }
118
+
119
+ export declare interface CanvasPointerEvent {
120
+ x: number;
121
+ y: number;
122
+ shiftKey: boolean;
123
+ ctrlKey: boolean;
124
+ altKey: boolean;
125
+ }
126
+
127
+ declare interface CanvasState_2 {
128
+ annotations: Annotation[];
129
+ canvasJSON: object;
130
+ image: {
131
+ width: number;
132
+ height: number;
133
+ };
134
+ }
135
+ export { CanvasState_2 as CanvasState }
136
+
137
+ /**
138
+ * Convert all canvas objects to Annotations.
139
+ */
140
+ export declare const canvasToAnnotations: (objects: LabeledFabricObject[], imageWidth: number, imageHeight: number) => Promise<Annotation[]>;
141
+
142
+ /**
143
+ * Create an HTMLImageElement from a URL.
144
+ */
145
+ export declare const createImage: (src: string) => Promise<HTMLImageElement>;
146
+
147
+ export declare const createTemporalHistoryStore: <T>() => UseBoundStore<Omit<StoreApi<TemporalHistoryState<T>>, "temporal"> & {
148
+ temporal: StoreApi<TemporalState< {
149
+ snapshot: T | null;
150
+ }>>;
151
+ }>;
152
+
153
+ /**
154
+ * Crop image data to the bounding box of non-transparent pixels.
155
+ */
156
+ export declare const cropAlphaArea: (imgData: ImageData) => {
157
+ canvas: HTMLCanvasElement;
158
+ minX: number;
159
+ minY: number;
160
+ };
161
+
162
+ export declare const emitLabelEvent: (action: LabelEventType, data?: LabelEventData) => void;
163
+
164
+ export declare const ensureCanvas: () => FabricCanvas;
165
+
166
+ export declare const eraserTool: () => LabelingTool;
167
+
168
+ export declare const EXCEPTION_TOOLS: string[];
169
+
170
+ export declare const EXPORT_PROPS: string[];
171
+
172
+ export declare interface ExtensionContext {
173
+ image: {
174
+ url: string;
175
+ width: number;
176
+ height: number;
177
+ };
178
+ annotations: Annotation[];
179
+ selectedIds: string[];
180
+ activeTool: string;
181
+ addAnnotations: (annotations: Annotation[]) => void;
182
+ updateAnnotation: (id: string, annotation: Partial<Annotation>) => void;
183
+ removeAnnotations: (ids: string[]) => void;
184
+ setTool: (tool: string) => void;
185
+ canvas: {
186
+ toJSON: () => object;
187
+ getImageDataURL: () => string;
188
+ };
189
+ }
190
+
191
+ declare type FabricCanvas = Canvas & {
192
+ lowerCanvasEl?: HTMLCanvasElement | null;
193
+ upperCanvasEl?: HTMLCanvasElement | null;
194
+ };
195
+
196
+ /**
197
+ * Convert a Fabric object to an Annotation.
198
+ */
199
+ export declare const fabricObjectToAnnotation: (object: LabeledFabricObject, imageWidth: number, imageHeight: number) => Promise<Annotation | null>;
200
+
201
+ export declare const filledRectTool: () => LabelingTool;
202
+
203
+ export declare const getActiveLabeledObjects: (targetCanvas?: FabricCanvas) => LabeledFabricObject[];
204
+
205
+ export declare const getCanvasInstance: () => FabricCanvas;
206
+
207
+ export declare const getCanvasJSON: (targetCanvas?: FabricCanvas) => CanvasJSON;
208
+
209
+ export declare const getLabeledObjects: (targetCanvas?: FabricCanvas) => LabeledFabricObject[];
210
+
211
+ export declare const getToolSelectionStore: () => ToolSelectionState;
212
+
213
+ declare interface LabeledFabricObject extends FabricObject {
214
+ info?: string;
215
+ unique?: string;
216
+ hex?: string;
217
+ alpha?: string;
218
+ selected?: boolean;
219
+ class?: string;
220
+ added?: boolean;
221
+ index?: number;
222
+ seq?: number;
223
+ copied?: boolean;
224
+ combinded?: boolean;
225
+ labeler?: string;
226
+ undo?: boolean;
227
+ redo?: boolean;
228
+ passStack?: boolean;
229
+ replaced?: boolean;
230
+ removed?: boolean;
231
+ trueLeft?: number;
232
+ trueTop?: number;
233
+ toHex?: string;
234
+ eraser?: unknown;
235
+ labelType?: string;
236
+ labelPayload?: Record<string, unknown>;
237
+ _objects?: LabeledFabricObject[];
238
+ labelInsertData?: Record<string, unknown>;
239
+ [key: string]: unknown;
240
+ }
241
+
242
+ declare interface LabelEventData {
243
+ uniques?: string[];
244
+ unique?: string;
245
+ selected?: boolean;
246
+ objects?: LabeledFabricObject[];
247
+ info?: string;
248
+ canvasJSON?: CanvasExportJSON;
249
+ seq?: Array<{
250
+ unique: string;
251
+ seq: number;
252
+ }>;
253
+ callback?: (json: CanvasExportJSON | string) => void;
254
+ direction?: ZoomPayload['direction'];
255
+ level?: number;
256
+ onChange?: ZoomPayload['onChange'];
257
+ class?: string;
258
+ hex?: string;
259
+ opacity?: number;
260
+ onDone?: () => void;
261
+ imageWidth?: number;
262
+ imageHeight?: number;
263
+ action?: string;
264
+ point?: {
265
+ x: number;
266
+ y: number;
267
+ };
268
+ labelInsertData?: Record<string, unknown>;
269
+ [key: string]: unknown;
270
+ }
271
+
272
+ declare type LabelEventListener = (action: LabelEventType, data?: LabelEventData) => void | Promise<void>;
273
+
274
+ declare type LabelEventType = 'load' | 'selected' | 'deleted' | 'zoom' | 'copy' | 'paste' | 'deleteSelected' | 'selectAll' | 'reset' | 'combine' | 'seq' | 'addClass' | 'deleteObjectsOfTool' | 'addObjects' | 'deselectAll' | 'undo' | 'redo' | 'changed' | 'blur' | 'focus' | 'init';
275
+
276
+ export declare function LabelingCanvas({ image, annotations, onChange, readOnly, width, height, }: LabelingCanvasProps): JSX_2.Element;
277
+
278
+ declare interface LabelingCanvasProps {
279
+ image: string | {
280
+ url: string;
281
+ width: number;
282
+ height: number;
283
+ };
284
+ annotations: Annotation[];
285
+ onChange?: (event: CanvasChangeEvent) => void;
286
+ readOnly?: boolean;
287
+ width?: number;
288
+ height?: number;
289
+ }
290
+
291
+ export declare interface LabelingClass {
292
+ id: string;
293
+ name: string;
294
+ color: string;
295
+ hotkey?: string;
296
+ group?: string;
297
+ }
298
+
299
+ declare interface LabelingContextValue {
300
+ image: string | {
301
+ url: string;
302
+ width: number;
303
+ height: number;
304
+ };
305
+ annotations: Annotation[];
306
+ onChange: (event: CanvasChangeEvent) => void;
307
+ records: WorkspaceRecord[];
308
+ activeRecordId: string;
309
+ onRecordSelect: (record: WorkspaceRecord) => void;
310
+ classes: LabelingClass[];
311
+ onClassSelect?: (cls: LabelingClass) => void;
312
+ selectedClassId: string | null;
313
+ setSelectedClassId: (id: string | null) => void;
314
+ selectedAnnotationId: string | null;
315
+ setSelectedAnnotationId: (id: string | null) => void;
316
+ onSave: (state: CanvasState_2) => void | Promise<void>;
317
+ isSaving: boolean;
318
+ mode: WorkspaceMode;
319
+ onModeChange?: (mode: WorkspaceMode) => void;
320
+ validationResults: ValidationResult[];
321
+ indicator?: WorkspaceIndicator;
322
+ extensions: LabelingExtension[];
323
+ tools: ToolType[];
324
+ theme?: Partial<LabelingTheme>;
325
+ layout: WorkspaceLayout;
326
+ navDirection: 'horizontal' | 'vertical';
327
+ setNavDirection: (dir: 'horizontal' | 'vertical') => void;
328
+ navVisible: boolean;
329
+ setNavVisible: (visible: boolean) => void;
330
+ }
331
+
332
+ export declare interface LabelingExtension {
333
+ id: string;
334
+ slot: 'tool' | 'sidePanel' | 'toolbar';
335
+ render: (context: ExtensionContext) => ReactNode;
336
+ }
337
+
338
+ export declare function LabelingFloatingToolbar({ items, show, verticalNav, children, }: LabelingFloatingToolbarProps): JSX_2.Element | null;
339
+
340
+ declare interface LabelingFloatingToolbarProps {
341
+ items: ToolbarItem[];
342
+ show?: boolean;
343
+ verticalNav?: boolean;
344
+ children?: ReactNode;
345
+ }
346
+
347
+ export declare function LabelingIndicator({ indicator }: LabelingIndicatorProps): JSX_2.Element | null;
348
+
349
+ declare interface LabelingIndicatorProps {
350
+ indicator?: WorkspaceIndicator;
351
+ }
352
+
353
+ export declare function LabelingInfoPanel({ classes, annotations, selectedAnnotationId, onClassSelect, onAnnotationSelect, onAnnotationDelete, disabled, }: LabelingInfoPanelProps): JSX_2.Element;
354
+
355
+ declare interface LabelingInfoPanelProps {
356
+ classes: LabelingClass[];
357
+ annotations: Annotation[];
358
+ selectedAnnotationId?: string | null;
359
+ onClassSelect?: (cls: LabelingClass) => void;
360
+ onAnnotationSelect?: (annotation: Annotation) => void;
361
+ onAnnotationDelete?: (annotationId: string) => void;
362
+ disabled?: boolean;
363
+ }
364
+
365
+ export declare function LabelingIssuePanel({ annotations, validationResults, selectedAnnotationId, onAnnotationSelect, onValidate, onValidationUpdate: _onValidationUpdate, onValidationDelete, }: LabelingIssuePanelProps): JSX_2.Element;
366
+
367
+ declare interface LabelingIssuePanelProps {
368
+ annotations: Annotation[];
369
+ validationResults: ValidationResult[];
370
+ selectedAnnotationId?: string | null;
371
+ onAnnotationSelect?: (annotation: Annotation) => void;
372
+ onValidate?: (event: ValidateEvent) => void | Promise<void>;
373
+ onValidationUpdate?: (event: ValidationUpdateEvent) => void | Promise<void>;
374
+ onValidationDelete?: (event: ValidationDeleteEvent) => void | Promise<void>;
375
+ }
376
+
377
+ export declare function LabelingNavigation({ records, activeRecordId, onRecordSelect, direction, onDirectionChange, hidden, }: LabelingNavigationProps): JSX_2.Element;
378
+
379
+ declare interface LabelingNavigationProps {
380
+ records: WorkspaceRecord[];
381
+ activeRecordId: string;
382
+ onRecordSelect: (record: WorkspaceRecord) => void;
383
+ direction?: 'horizontal' | 'vertical';
384
+ onDirectionChange?: (direction: 'horizontal' | 'vertical') => void;
385
+ hidden?: boolean;
386
+ }
387
+
388
+ export declare function LabelingProvider({ image, annotations, onChange, records, activeRecordId, onRecordSelect, classes, onClassSelect, onSave, isSaving, mode, onModeChange, validationResults, indicator, extensions, tools, theme, layout, children, }: LabelingProviderProps): JSX_2.Element;
389
+
390
+ declare interface LabelingProviderProps {
391
+ image: string | {
392
+ url: string;
393
+ width: number;
394
+ height: number;
395
+ };
396
+ annotations: Annotation[];
397
+ onChange: (event: CanvasChangeEvent) => void;
398
+ records: WorkspaceRecord[];
399
+ activeRecordId: string;
400
+ onRecordSelect: (record: WorkspaceRecord) => void;
401
+ classes: LabelingClass[];
402
+ onClassSelect?: (cls: LabelingClass) => void;
403
+ onSave: (state: CanvasState_2) => void | Promise<void>;
404
+ isSaving?: boolean;
405
+ mode?: WorkspaceMode;
406
+ onModeChange?: (mode: WorkspaceMode) => void;
407
+ validationResults?: ValidationResult[];
408
+ indicator?: WorkspaceIndicator;
409
+ extensions?: LabelingExtension[];
410
+ tools?: ToolType[];
411
+ theme?: Partial<LabelingTheme>;
412
+ layout?: WorkspaceLayout;
413
+ children: ReactNode;
414
+ }
415
+
416
+ export declare interface LabelingTheme {
417
+ primary: string;
418
+ background: string;
419
+ surface: string;
420
+ border: string;
421
+ text: string;
422
+ textSecondary: string;
423
+ hover: string;
424
+ primaryLight: string;
425
+ fontFamily: string;
426
+ radius: number;
427
+ spacing: {
428
+ sm: number;
429
+ md: number;
430
+ lg: number;
431
+ };
432
+ }
433
+
434
+ declare interface LabelingTool {
435
+ id: string;
436
+ init: (...args: any[]) => Promise<(() => void) | void | undefined> | (() => void) | void;
437
+ }
438
+
439
+ export declare function LabelingToolbar({ tools, sections: _sections, onSave, isSaving, onPrev, onNext, hasPrev, hasNext, children, }: LabelingToolbarInternalProps): JSX_2.Element;
440
+
441
+ declare interface LabelingToolbarInternalProps extends LabelingToolbarProps {
442
+ tools?: ToolType[];
443
+ children?: ReactNode;
444
+ }
445
+
446
+ export declare interface LabelingToolbarProps {
447
+ orientation?: 'horizontal' | 'vertical';
448
+ sections?: ToolbarSection[];
449
+ onSave?: () => void;
450
+ isSaving?: boolean;
451
+ onPrev?: () => void;
452
+ onNext?: () => void;
453
+ hasPrev?: boolean;
454
+ hasNext?: boolean;
455
+ }
456
+
457
+ /**
458
+ * Level 1: All-in-one labeling workspace.
459
+ * Renders Navigation + Toolbar + Canvas + InfoPanel in a single component.
460
+ */
461
+ export declare function LabelingWorkspace(props: LabelingWorkspaceProps): JSX_2.Element;
462
+
463
+ export declare interface LabelingWorkspaceProps {
464
+ image: string | {
465
+ url: string;
466
+ width: number;
467
+ height: number;
468
+ };
469
+ annotations: Annotation[];
470
+ onChange: (event: CanvasChangeEvent) => void;
471
+ records: WorkspaceRecord[];
472
+ activeRecordId: string;
473
+ onRecordSelect: (record: WorkspaceRecord) => void;
474
+ totalRecords?: number;
475
+ onPageChange?: (page: number) => void;
476
+ classes: LabelingClass[];
477
+ onClassSelect?: (cls: LabelingClass) => void;
478
+ onSave: (state: CanvasState_2) => void | Promise<void>;
479
+ isSaving?: boolean;
480
+ mode?: WorkspaceMode;
481
+ onModeChange?: (mode: WorkspaceMode) => void;
482
+ validationResults?: ValidationResult[];
483
+ onValidate?: (event: ValidateEvent) => void | Promise<void>;
484
+ onValidationUpdate?: (event: ValidationUpdateEvent) => void | Promise<void>;
485
+ onValidationDelete?: (event: ValidationDeleteEvent) => void | Promise<void>;
486
+ indicator?: WorkspaceIndicator;
487
+ extensions?: LabelingExtension[];
488
+ tools?: ToolType[];
489
+ theme?: Partial<LabelingTheme>;
490
+ layout?: WorkspaceLayout;
491
+ }
492
+
493
+ export declare const LAYER_MODE: Record<string, LayerMode>;
494
+
495
+ declare type LayerMode = [number, number] | [number];
496
+
497
+ declare interface LayerModeState {
498
+ mode: LayerMode;
499
+ setMode: (mode: LayerMode) => void;
500
+ cycleMode: () => void;
501
+ }
502
+
503
+ export declare const loadFabric: () => Promise<fabric>;
504
+
505
+ export declare const magicbrushTool: () => LabelingTool;
506
+
507
+ declare interface OpacityState {
508
+ opacity: number;
509
+ setOpacity: (opacity: number) => void;
510
+ }
511
+
512
+ declare interface PaletteState {
513
+ colorCode: string;
514
+ setColorCode: (colorCode: string) => void;
515
+ }
516
+
517
+ export declare interface PolygonGeometry {
518
+ type: 'polygon';
519
+ /** Normalized vertex coordinates */
520
+ points: Array<{
521
+ x: number;
522
+ y: number;
523
+ }>;
524
+ }
525
+
526
+ export declare const polygonTool: () => LabelingTool;
527
+
528
+ export declare interface RecognitionGeometry {
529
+ type: 'recognition';
530
+ start: number;
531
+ end: number;
532
+ text?: string;
533
+ }
534
+
535
+ export declare type RecordStatus = 'unlabeled' | 'labeled' | 'validated' | 'issue';
536
+
537
+ export declare const renderAllSafe: (targetCanvas?: FabricCanvas) => void;
538
+
539
+ export declare const segmentAnythingTool: () => LabelingTool;
540
+
541
+ export declare interface SegmentationGeometry {
542
+ type: 'segmentation';
543
+ /** Base64 PNG mask */
544
+ mask: string;
545
+ /** Fabric object vector for restoration (optional) */
546
+ vector?: string;
547
+ }
548
+
549
+ export declare const selectionTool: () => LabelingTool;
550
+
551
+ export declare const setCanvasInstance: (instance: FabricCanvas | null) => void;
552
+
553
+ export declare const setMagicBrushModule: (module: any) => void;
554
+
555
+ export declare const setSuperpixelModules: (modules: {
556
+ SLIC: any;
557
+ MagicBrush: any;
558
+ }) => void;
559
+
560
+ export declare const subscribeLabelEvents: (listener: LabelEventListener) => () => void;
561
+
562
+ export declare const superpixelTool: () => LabelingTool;
563
+
564
+ declare interface TemporalHistoryState<T> {
565
+ snapshot: T | null;
566
+ setSnapshot: (snapshot: T) => void;
567
+ reset: () => void;
568
+ }
569
+
570
+ export declare const toHex: (color: string) => {
571
+ hex: string;
572
+ alpha: string;
573
+ };
574
+
575
+ export declare const TOOL_INFO_BOUNDED_BOX = "Bounded Box";
576
+
577
+ export declare const TOOL_INFO_BRUSH = "Brush";
578
+
579
+ export declare const TOOL_INFO_COMBINED_LABELS = "Combined Label";
580
+
581
+ export declare const TOOL_INFO_ERASER = "Eraser";
582
+
583
+ export declare const TOOL_INFO_FILLED_BOX = "Filled Box";
584
+
585
+ export declare const TOOL_INFO_FILLED_POLYGON = "Filled Polygon";
586
+
587
+ export declare const TOOL_INFO_MAGIC_BRUSH = "Magic Brush";
588
+
589
+ export declare const TOOL_INFO_SUPERPIXEL = "Superpixel";
590
+
591
+ export declare interface ToolbarButtonItem {
592
+ variant: 'button';
593
+ id?: string;
594
+ icon?: ReactNode;
595
+ title?: string;
596
+ tooltip?: string;
597
+ disabled?: boolean;
598
+ active?: boolean;
599
+ slim?: boolean;
600
+ onClick?: () => void;
601
+ subItems?: ToolbarItem[];
602
+ }
603
+
604
+ export declare interface ToolbarDividerItem {
605
+ variant: 'divider';
606
+ }
607
+
608
+ export declare type ToolbarItem = ToolbarButtonItem | ToolbarRadioItem | ToolbarDividerItem;
609
+
610
+ export declare interface ToolbarRadioItem {
611
+ variant: 'radio';
612
+ id: string;
613
+ name: string;
614
+ icon?: ReactNode;
615
+ title?: string;
616
+ disabled?: boolean;
617
+ checked?: boolean;
618
+ onClick?: () => void;
619
+ }
620
+
621
+ export declare type ToolbarSection = 'tools' | 'brush' | 'palette' | 'zoom' | 'history' | 'layers' | 'viewMode' | 'validation' | 'navigation' | 'save';
622
+
623
+ export declare interface ToolExtension extends LabelingExtension {
624
+ slot: 'tool';
625
+ icon: ReactNode;
626
+ label: string;
627
+ shortcut?: string;
628
+ canvasHandlers?: {
629
+ onMouseDown?: (e: CanvasPointerEvent) => void;
630
+ onMouseMove?: (e: CanvasPointerEvent) => void;
631
+ onMouseUp?: (e: CanvasPointerEvent) => void;
632
+ };
633
+ }
634
+
635
+ declare interface ToolSelectionState {
636
+ tool: LabelingTool | null;
637
+ setTool: (tool: LabelingTool | null) => void;
638
+ overedUniques: string[];
639
+ setOveredUniques: (overedUniques: string[]) => void;
640
+ undoStack: string[];
641
+ redoStack: string[];
642
+ setUndoStack: (undoStack: string[]) => void;
643
+ setRedoStack: (redoStack: string[]) => void;
644
+ }
645
+
646
+ export declare type ToolType = 'selection' | 'brush' | 'blankRect' | 'filledRect' | 'polygon' | 'eraser' | 'magicbrush' | 'superpixel';
647
+
648
+ export declare const toRgba: (hex: string, opacity: number) => string;
649
+
650
+ export declare const toRgbaArray: (rgba: string) => number[];
651
+
652
+ export declare const toRGBAHex: (rgba: string) => string;
653
+
654
+ /**
655
+ * Set black pixels transparent and apply opacity to non-black pixels.
656
+ */
657
+ export declare const transparentBlackPixel: (imageData: ImageData, opacity: number) => ImageData;
658
+
659
+ export declare const useBrushStore: UseBoundStore<StoreApi<BrushState>>;
660
+
661
+ export declare const useCanvasObjectsStore: UseBoundStore<StoreApi<CanvasObjectsState>>;
662
+
663
+ /**
664
+ * Manages extension lifecycle — provides the ExtensionContext
665
+ * and hooks up ToolExtension canvas handlers.
666
+ */
667
+ export declare function useExtensions(options: UseExtensionsOptions): {
668
+ context: ExtensionContext;
669
+ toolExtensions: ToolExtension[];
670
+ sidePanelExtensions: LabelingExtension[];
671
+ toolbarExtensions: LabelingExtension[];
672
+ activeToolExtension: ToolExtension | undefined;
673
+ };
674
+
675
+ declare interface UseExtensionsOptions {
676
+ extensions: LabelingExtension[];
677
+ image: {
678
+ url: string;
679
+ width: number;
680
+ height: number;
681
+ };
682
+ annotations: Annotation[];
683
+ selectedIds: string[];
684
+ activeTool: string;
685
+ addAnnotations: (annotations: Annotation[]) => void;
686
+ updateAnnotation: (id: string, annotation: Partial<Annotation>) => void;
687
+ removeAnnotations: (ids: string[]) => void;
688
+ setTool: (tool: string) => void;
689
+ }
690
+
691
+ /**
692
+ * Level 3 headless hook — Direct canvas access.
693
+ *
694
+ * Provides low-level canvas operations: add/remove objects,
695
+ * export state, zoom control, etc.
696
+ */
697
+ export declare function useLabelingCanvas(): {
698
+ objects: LabeledFabricObject[];
699
+ zoom: number;
700
+ getAnnotations: (imageWidth: number, imageHeight: number) => Promise<Annotation[]>;
701
+ addAnnotation: (annotation: Annotation, imageWidth: number, imageHeight: number) => Promise<void>;
702
+ removeAnnotation: (annotationId: string) => void;
703
+ clearCanvas: () => void;
704
+ exportState: (imageWidth: number, imageHeight: number) => Promise<CanvasState_2>;
705
+ setZoomLevel: (level: number) => void;
706
+ };
707
+
708
+ export declare function useLabelingContext(): LabelingContextValue;
709
+
710
+ /**
711
+ * Level 3 headless hook — Canvas undo/redo history.
712
+ *
713
+ * Uses the tool store's undo/redo stacks (JSON snapshots).
714
+ */
715
+ export declare function useLabelingHistory(): {
716
+ canUndo: boolean;
717
+ canRedo: boolean;
718
+ undo: () => Promise<void>;
719
+ redo: () => Promise<void>;
720
+ pushSnapshot: () => void;
721
+ clear: () => void;
722
+ };
723
+
724
+ /**
725
+ * Level 3 headless hook — Tool selection and palette state.
726
+ *
727
+ * Returns current tool, setTool, and palette/brush/opacity state with setters.
728
+ */
729
+ export declare function useLabelingTools(): {
730
+ activeToolId: string | null;
731
+ currentTool: LabelingTool | null;
732
+ setTool: (toolType: ToolType) => void;
733
+ clearTool: () => void;
734
+ colorCode: string;
735
+ setColorCode: (colorCode: string) => void;
736
+ opacity: number;
737
+ setOpacity: (opacity: number) => void;
738
+ brush: {
739
+ id: number;
740
+ lineCap: string;
741
+ lineWidth: number;
742
+ };
743
+ setBrush: (brush: {
744
+ id: number;
745
+ lineCap: string;
746
+ lineWidth: number;
747
+ }) => void;
748
+ };
749
+
750
+ export declare const useLayerModeStore: UseBoundStore<StoreApi<LayerModeState>>;
751
+
752
+ export declare const useOpacityStore: UseBoundStore<StoreApi<OpacityState>>;
753
+
754
+ export declare const usePaletteStore: UseBoundStore<StoreApi<PaletteState>>;
755
+
756
+ export declare const useToolSelectionStore: UseBoundStore<StoreApi<ToolSelectionState>>;
757
+
758
+ export declare const useZoomStore: UseBoundStore<StoreApi<ZoomState>>;
759
+
760
+ export declare interface ValidateEvent {
761
+ annotationIds: string[];
762
+ result: boolean;
763
+ reason?: string;
764
+ }
765
+
766
+ export declare interface ValidationDeleteEvent {
767
+ ids: string[];
768
+ }
769
+
770
+ export declare interface ValidationResult {
771
+ id: string;
772
+ annotationId?: string;
773
+ result: boolean;
774
+ reason?: string;
775
+ validatedAt?: string;
776
+ }
777
+
778
+ export declare interface ValidationUpdateEvent {
779
+ id: string;
780
+ result?: boolean;
781
+ reason?: string;
782
+ }
783
+
784
+ export declare interface WorkspaceIndicator {
785
+ title: string;
786
+ subtitle?: string;
787
+ detail?: string;
788
+ progress?: {
789
+ current: number;
790
+ total: number;
791
+ };
792
+ }
793
+
794
+ export declare interface WorkspaceLayout {
795
+ navigation?: 'left' | 'bottom' | 'hidden';
796
+ toolbar?: 'top' | 'bottom';
797
+ }
798
+
799
+ export declare type WorkspaceMode = 'labeling' | 'validation' | 'readonly';
800
+
801
+ export declare interface WorkspaceRecord {
802
+ id: string;
803
+ title: string;
804
+ thumbnail?: string;
805
+ status?: RecordStatus;
806
+ children?: WorkspaceRecord[];
807
+ meta?: Record<string, unknown>;
808
+ }
809
+
810
+ declare interface ZoomPayload {
811
+ direction: 1 | 0 | -1;
812
+ level: number;
813
+ point?: {
814
+ x: number;
815
+ y: number;
816
+ };
817
+ onChange: (payload: {
818
+ level: number;
819
+ width: number;
820
+ height: number;
821
+ }) => void;
822
+ }
823
+
824
+ declare interface ZoomState {
825
+ level: number;
826
+ width: number;
827
+ height: number;
828
+ setZoom: (payload: {
829
+ level: number;
830
+ width: number;
831
+ height: number;
832
+ }) => void;
833
+ reset: () => void;
834
+ }
835
+
836
+ export { }