@flowscape-ui/core-sdk 1.0.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,1430 @@
1
+ import Konva from 'konva';
2
+ import * as konva_lib_types from 'konva/lib/types';
3
+
4
+ interface BaseNodeOptions {
5
+ id?: string;
6
+ x?: number;
7
+ y?: number;
8
+ width?: number;
9
+ height?: number;
10
+ }
11
+ declare abstract class BaseNode<T extends Konva.Node = Konva.Node> {
12
+ protected konvaNode: T;
13
+ readonly id: string;
14
+ constructor(node: T, options?: BaseNodeOptions);
15
+ getNode(): T;
16
+ setPosition({ x, y }: {
17
+ x: number;
18
+ y: number;
19
+ }): void;
20
+ getPosition(): konva_lib_types.Vector2d;
21
+ remove(): void;
22
+ }
23
+
24
+ interface ShapeNodeOptions extends BaseNodeOptions {
25
+ fill?: string;
26
+ stroke?: string;
27
+ strokeWidth?: number;
28
+ cornerRadius?: number | number[];
29
+ }
30
+ declare class ShapeNode extends BaseNode<Konva.Rect> {
31
+ constructor(options: ShapeNodeOptions);
32
+ setFill(color: string): this;
33
+ setStroke(color: string): this;
34
+ setStrokeWidth(width: number): this;
35
+ setCornerRadius(radius: number | number[]): this;
36
+ setSize({ width, height }: {
37
+ width: number;
38
+ height: number;
39
+ }): this;
40
+ getFill(): string | undefined;
41
+ getStroke(): string | undefined;
42
+ getStrokeWidth(): number;
43
+ getCornerRadius(): number;
44
+ }
45
+
46
+ type Listener<TArgs extends unknown[]> = (...args: TArgs) => void;
47
+ declare class EventBus<TEvents extends {
48
+ [K in keyof TEvents]: unknown[];
49
+ } = Record<string, unknown[]>> {
50
+ private _listeners;
51
+ constructor();
52
+ get listeners(): Map<string, Listener<TEvents[keyof TEvents & string]>[]>;
53
+ on<K extends keyof TEvents & string>(event: K, callback: Listener<TEvents[K]>): void;
54
+ off<K extends keyof TEvents & string>(event: K, callback: Listener<TEvents[K]>): void;
55
+ once<K extends keyof TEvents & string>(event: K, callback: Listener<TEvents[K]>): void;
56
+ emit<K extends keyof TEvents & string>(event: K, ...args: TEvents[K]): void;
57
+ }
58
+
59
+ /**
60
+ * Типизированные события CoreEngine
61
+ * Все события строго типизированы для лучшего DX
62
+ */
63
+ interface CoreEvents {
64
+ /** Нода была создана и добавлена в мир */
65
+ 'node:created': [node: BaseNode];
66
+ /** Нода была удалена из мира */
67
+ 'node:removed': [node: BaseNode];
68
+ /** Нода была выделена */
69
+ 'node:selected': [node: BaseNode];
70
+ /** Выделение ноды было снято */
71
+ 'node:deselected': [node: BaseNode];
72
+ /** Нода была изменена (position, size, rotation, etc.) */
73
+ 'node:transformed': [
74
+ node: BaseNode,
75
+ changes: {
76
+ x?: number;
77
+ y?: number;
78
+ width?: number;
79
+ height?: number;
80
+ rotation?: number;
81
+ scaleX?: number;
82
+ scaleY?: number;
83
+ }
84
+ ];
85
+ /** Z-index ноды был изменён */
86
+ 'node:zIndexChanged': [node: BaseNode, oldIndex: number, newIndex: number];
87
+ /** Группа была создана */
88
+ 'group:created': [group: BaseNode, nodes: BaseNode[]];
89
+ /** Группа была разгруппирована */
90
+ 'group:ungrouped': [group: BaseNode, nodes: BaseNode[]];
91
+ /** Множественное выделение создано */
92
+ 'selection:multi:created': [nodes: BaseNode[]];
93
+ /** Множественное выделение уничтожено */
94
+ 'selection:multi:destroyed': [];
95
+ /** Выделение полностью снято */
96
+ 'selection:cleared': [];
97
+ /** Ноды были скопированы в буфер обмена */
98
+ 'clipboard:copy': [nodes: BaseNode[]];
99
+ /** Ноды были вырезаны в буфер обмена */
100
+ 'clipboard:cut': [nodes: BaseNode[]];
101
+ /** Ноды были вставлены из буфера обмена */
102
+ 'clipboard:paste': [nodes: BaseNode[]];
103
+ /** Зум был изменён программно */
104
+ 'camera:setZoom': [{
105
+ scale: number;
106
+ }];
107
+ /** Зум был изменён пользователем (колесо мыши) */
108
+ 'camera:zoom': [{
109
+ scale: number;
110
+ position: {
111
+ x: number;
112
+ y: number;
113
+ };
114
+ }];
115
+ /** Камера была сброшена */
116
+ 'camera:reset': [];
117
+ /** Шаг зума был изменён */
118
+ 'camera:zoomStep': [{
119
+ zoomStep: number;
120
+ }];
121
+ /** Шаг панорамирования был изменён */
122
+ 'camera:panStep': [{
123
+ panStep: number;
124
+ }];
125
+ /** Камера была перемещена (панорамирование) */
126
+ 'camera:pan': [{
127
+ dx: number;
128
+ dy: number;
129
+ position: {
130
+ x: number;
131
+ y: number;
132
+ };
133
+ }];
134
+ /** Плагин был добавлен */
135
+ 'plugin:added': [pluginName: string];
136
+ /** Плагин был удалён */
137
+ 'plugin:removed': [pluginName: string];
138
+ /** Stage был изменён (resize) */
139
+ 'stage:resized': [{
140
+ width: number;
141
+ height: number;
142
+ }];
143
+ }
144
+
145
+ interface TextNodeOptions extends BaseNodeOptions {
146
+ text?: string;
147
+ fontSize?: number;
148
+ fontFamily?: string;
149
+ fontStyle?: string;
150
+ fill?: string;
151
+ align?: 'left' | 'center' | 'right';
152
+ padding?: number;
153
+ }
154
+ declare class TextNode extends BaseNode<Konva.Text> {
155
+ constructor(options?: TextNodeOptions);
156
+ getText(): string;
157
+ getFontSize(): number;
158
+ getFontFamily(): string;
159
+ getFontStyle(): string;
160
+ getFill(): string | undefined;
161
+ getAlign(): 'left' | 'center' | 'right';
162
+ getPadding(): number;
163
+ getSize(): {
164
+ width: number;
165
+ height: number;
166
+ };
167
+ setText(text: string): this;
168
+ setFontSize(size: number): this;
169
+ setFontFamily(family: string): this;
170
+ setFontStyle(style: string): this;
171
+ setFill(color: string): this;
172
+ setAlign(align: 'left' | 'center' | 'right'): this;
173
+ setPadding(padding: number): this;
174
+ setSize({ width, height }: {
175
+ width: number;
176
+ height: number;
177
+ }): this;
178
+ }
179
+
180
+ type ImageSource = HTMLImageElement;
181
+ interface ImageNodeOptions extends BaseNodeOptions {
182
+ image?: ImageSource;
183
+ src?: string;
184
+ width?: number;
185
+ height?: number;
186
+ }
187
+ declare class ImageNode extends BaseNode<Konva.Image> {
188
+ constructor(options?: ImageNodeOptions);
189
+ getSize(): {
190
+ width: number;
191
+ height: number;
192
+ };
193
+ /**
194
+ * Async loads image from URL and sets it to Konva.Image.
195
+ * Returns this for chaining.
196
+ */
197
+ setSrc(url: string, crossOrigin?: '' | 'anonymous' | 'use-credentials' | undefined): Promise<this>;
198
+ /**
199
+ * Set already loaded image source (HTMLImageElement)
200
+ */
201
+ setImage(image: ImageSource): this;
202
+ setSize({ width, height }: {
203
+ width: number;
204
+ height: number;
205
+ }): this;
206
+ private _loadHTMLImage;
207
+ }
208
+
209
+ interface CircleNodeOptions extends BaseNodeOptions {
210
+ radius?: number;
211
+ fill?: string;
212
+ stroke?: string;
213
+ strokeWidth?: number;
214
+ }
215
+ declare class CircleNode extends BaseNode<Konva.Circle> {
216
+ constructor(options?: CircleNodeOptions);
217
+ getRadius(): number;
218
+ getFill(): string | undefined;
219
+ getStroke(): string | undefined;
220
+ getStrokeWidth(): number;
221
+ setRadius(radius: number): this;
222
+ setFill(color: string): this;
223
+ setStroke(color: string): this;
224
+ setStrokeWidth(width: number): this;
225
+ }
226
+
227
+ interface EllipseNodeOptions extends BaseNodeOptions {
228
+ radiusX?: number;
229
+ radiusY?: number;
230
+ fill?: string;
231
+ stroke?: string;
232
+ strokeWidth?: number;
233
+ }
234
+ declare class EllipseNode extends BaseNode<Konva.Ellipse> {
235
+ constructor(options?: EllipseNodeOptions);
236
+ getRadiusX(): number;
237
+ getRadiusY(): number;
238
+ getFill(): string | undefined;
239
+ getStroke(): string | undefined;
240
+ getStrokeWidth(): number;
241
+ setRadiusX(value: number): this;
242
+ setRadiusY(value: number): this;
243
+ setFill(color: string): this;
244
+ setStroke(color: string): this;
245
+ setStrokeWidth(width: number): this;
246
+ }
247
+
248
+ interface ArcNodeOptions extends BaseNodeOptions {
249
+ innerRadius?: number;
250
+ outerRadius?: number;
251
+ angle?: number;
252
+ rotation?: number;
253
+ clockwise?: boolean;
254
+ fill?: string;
255
+ stroke?: string;
256
+ strokeWidth?: number;
257
+ }
258
+ declare class ArcNode extends BaseNode<Konva.Arc> {
259
+ constructor(options?: ArcNodeOptions);
260
+ getInnerRadius(): number;
261
+ getOuterRadius(): number;
262
+ getAngle(): number;
263
+ isClockwise(): boolean;
264
+ setInnerRadius(v: number): this;
265
+ setOuterRadius(v: number): this;
266
+ setAngle(v: number): this;
267
+ setRotationDeg(v: number): this;
268
+ setClockwise(v: boolean): this;
269
+ setFill(color: string): this;
270
+ setStroke(color: string): this;
271
+ setStrokeWidth(width: number): this;
272
+ }
273
+
274
+ interface ArrowNodeOptions extends BaseNodeOptions {
275
+ points?: number[];
276
+ tension?: number;
277
+ pointerLength?: number;
278
+ pointerWidth?: number;
279
+ pointerAtBeginning?: boolean;
280
+ pointerAtEnding?: boolean;
281
+ fill?: string;
282
+ stroke?: string;
283
+ strokeWidth?: number;
284
+ }
285
+ declare class ArrowNode extends BaseNode<Konva.Arrow> {
286
+ constructor(options?: ArrowNodeOptions);
287
+ getPoints(): number[];
288
+ getTension(): number;
289
+ getPointerLength(): number;
290
+ getPointerWidth(): number;
291
+ getPointerAtBeginning(): boolean;
292
+ getPointerAtEnding(): boolean;
293
+ setPoints(v: number[]): this;
294
+ setTension(v: number): this;
295
+ setPointerLength(v: number): this;
296
+ setPointerWidth(v: number): this;
297
+ setPointerAtBeginning(v: boolean): this;
298
+ setPointerAtEnding(v: boolean): this;
299
+ setFill(color: string): this;
300
+ setStroke(color: string): this;
301
+ setStrokeWidth(width: number): this;
302
+ }
303
+
304
+ interface RegularPolygonNodeOptions extends BaseNodeOptions {
305
+ sides?: number;
306
+ radius?: number;
307
+ fill?: string;
308
+ stroke?: string;
309
+ strokeWidth?: number;
310
+ }
311
+ declare class RegularPolygonNode extends BaseNode<Konva.RegularPolygon> {
312
+ constructor(options?: RegularPolygonNodeOptions);
313
+ getSides(): number;
314
+ getRadius(): number;
315
+ getFill(): string | undefined;
316
+ getStroke(): string | undefined;
317
+ getStrokeWidth(): number;
318
+ setSides(v: number): this;
319
+ setRadius(v: number): this;
320
+ setFill(color: string): this;
321
+ setStroke(color: string): this;
322
+ setStrokeWidth(width: number): this;
323
+ }
324
+
325
+ interface StarNodeOptions extends BaseNodeOptions {
326
+ numPoints?: number;
327
+ innerRadius?: number;
328
+ outerRadius?: number;
329
+ fill?: string;
330
+ stroke?: string;
331
+ strokeWidth?: number;
332
+ }
333
+ declare class StarNode extends BaseNode<Konva.Star> {
334
+ constructor(options?: StarNodeOptions);
335
+ getNumPoints(): number;
336
+ getInnerRadius(): number;
337
+ getOuterRadius(): number;
338
+ getFill(): string | undefined;
339
+ getStroke(): string | undefined;
340
+ getStrokeWidth(): number;
341
+ setNumPoints(v: number): this;
342
+ setInnerRadius(v: number): this;
343
+ setOuterRadius(v: number): this;
344
+ setFill(color: string): this;
345
+ setStroke(color: string): this;
346
+ setStrokeWidth(width: number): this;
347
+ }
348
+
349
+ interface RingNodeOptions extends BaseNodeOptions {
350
+ innerRadius?: number;
351
+ outerRadius?: number;
352
+ fill?: string;
353
+ stroke?: string;
354
+ strokeWidth?: number;
355
+ }
356
+ declare class RingNode extends BaseNode<Konva.Ring> {
357
+ constructor(options?: RingNodeOptions);
358
+ getInnerRadius(): number;
359
+ getOuterRadius(): number;
360
+ getFill(): string | undefined;
361
+ getStroke(): string | undefined;
362
+ getStrokeWidth(): number;
363
+ setInnerRadius(v: number): this;
364
+ setOuterRadius(v: number): this;
365
+ setFill(color: string): this;
366
+ setStroke(color: string): this;
367
+ setStrokeWidth(width: number): this;
368
+ }
369
+
370
+ interface GroupNodeOptions extends BaseNodeOptions {
371
+ draggable?: boolean;
372
+ listening?: boolean;
373
+ clip?: {
374
+ x: number;
375
+ y: number;
376
+ width: number;
377
+ height: number;
378
+ };
379
+ }
380
+ declare class GroupNode extends BaseNode<Konva.Group> {
381
+ constructor(options?: GroupNodeOptions);
382
+ addChild(child: Konva.Node | BaseNode): this;
383
+ removeChild(child: Konva.Node | BaseNode): this;
384
+ removeAllChildren(): this;
385
+ getChildren(): Konva.Node[];
386
+ findByName(name: string): Konva.Node[];
387
+ setDraggable(v: boolean): this;
388
+ isDraggable(): boolean;
389
+ setListening(v: boolean): this;
390
+ isListening(): boolean;
391
+ setClip(rect: {
392
+ x: number;
393
+ y: number;
394
+ width: number;
395
+ height: number;
396
+ }): this;
397
+ }
398
+
399
+ declare class NodeManager {
400
+ private _layer;
401
+ private _world;
402
+ private _nodes;
403
+ private _stage;
404
+ private _eventBus;
405
+ private _batchDrawScheduled;
406
+ private _listCache;
407
+ private _listCacheInvalidated;
408
+ constructor(stage: Konva.Stage, eventBus: EventBus<CoreEvents>);
409
+ get layer(): Konva.Layer;
410
+ get world(): Konva.Group;
411
+ get stage(): Konva.Stage;
412
+ get eventBus(): EventBus<CoreEvents>;
413
+ addShape(options: ShapeNodeOptions): ShapeNode;
414
+ addText(options: TextNodeOptions): TextNode;
415
+ addImage(options: ImageNodeOptions): ImageNode;
416
+ addCircle(options: CircleNodeOptions): CircleNode;
417
+ addEllipse(options: EllipseNodeOptions): EllipseNode;
418
+ addArc(options: ArcNodeOptions): ArcNode;
419
+ addStar(options: StarNodeOptions): StarNode;
420
+ addArrow(options: ArrowNodeOptions): ArrowNode;
421
+ addRing(options: RingNodeOptions): RingNode;
422
+ addRegularPolygon(options: RegularPolygonNodeOptions): RegularPolygonNode;
423
+ addGroup(options: GroupNodeOptions): GroupNode;
424
+ remove(node: BaseNode): void;
425
+ findById(id: string): BaseNode | undefined;
426
+ list(): BaseNode[];
427
+ /**
428
+ * Deferred redraw (throttling)
429
+ * CRITICAL OPTIMIZATION: group multiple node additions
430
+ */
431
+ private _scheduleBatchDraw;
432
+ }
433
+
434
+ interface CameraManagerOptions {
435
+ stage: Konva.Stage;
436
+ eventBus: EventBus<CoreEvents>;
437
+ target?: Konva.Node;
438
+ initialScale?: number;
439
+ minScale?: number;
440
+ maxScale?: number;
441
+ draggable?: boolean;
442
+ zoomStep?: number;
443
+ panStep?: number;
444
+ }
445
+ declare class CameraManager {
446
+ private _stage;
447
+ private _eventBus;
448
+ private _target;
449
+ private _scale;
450
+ private _minScale;
451
+ private _maxScale;
452
+ private _zoomStep;
453
+ private _panStep;
454
+ private _wheelScheduled;
455
+ private _pendingWheelEvent;
456
+ constructor(options: CameraManagerOptions);
457
+ private _initWheelZoom;
458
+ private _handleWheel;
459
+ get zoomStep(): number;
460
+ get panStep(): number;
461
+ setZoom(zoom: number): void;
462
+ zoomIn(step?: number): void;
463
+ zoomOut(step?: number): void;
464
+ reset(): void;
465
+ setDraggable(enabled: boolean): void;
466
+ setZoomStep(step: number): void;
467
+ setPanStep(step: number): void;
468
+ }
469
+
470
+ interface LODLevel {
471
+ minScale: number;
472
+ maxScale: number;
473
+ simplify: boolean;
474
+ disableStroke?: boolean;
475
+ disableShadow?: boolean;
476
+ disablePerfectDraw?: boolean;
477
+ }
478
+ interface LODOptions {
479
+ enabled?: boolean;
480
+ levels?: LODLevel[];
481
+ }
482
+ /**
483
+ * LODManager - manager for level of detail
484
+ *
485
+ * This is an ADDITIONAL optimization on top of Konva framework.
486
+ * Konva does not provide automatic LOD, so this implementation is necessary.
487
+ *
488
+ * When far away (small scale), it simplifies node rendering:
489
+ * - Disables stroke via strokeEnabled(false)
490
+ * - Disables shadow via shadowEnabled(false)
491
+ * - Disables perfect draw via perfectDrawEnabled(false)
492
+ *
493
+ * All methods use built-in Konva API, recommended in the official documentation:
494
+ * https://konvajs.org/docs/performance/All_Performance_Tips.html
495
+ *
496
+ * Performance boost: 20-30% when many nodes are rendered at small scales.
497
+ */
498
+ declare class LODManager {
499
+ private _enabled;
500
+ private _levels;
501
+ private _currentScale;
502
+ private _appliedNodes;
503
+ constructor(options?: LODOptions);
504
+ /**
505
+ * Level of detail for current scale
506
+ */
507
+ private _getLODLevel;
508
+ /**
509
+ * Apply LOD to node based on current scale
510
+ */
511
+ applyLOD(node: BaseNode, scale: number): void;
512
+ /**
513
+ * Restore original settings for node
514
+ */
515
+ private _restoreNode;
516
+ /**
517
+ * Apply LOD to all nodes
518
+ */
519
+ applyToAll(nodes: BaseNode[], scale: number): void;
520
+ /**
521
+ * Restore all nodes to full detail
522
+ */
523
+ restoreAll(nodes: BaseNode[]): void;
524
+ /**
525
+ * Enable LOD
526
+ */
527
+ enable(): void;
528
+ /**
529
+ * Disable LOD and restore all nodes
530
+ */
531
+ disable(nodes: BaseNode[]): void;
532
+ /**
533
+ * Check if LOD is enabled
534
+ */
535
+ get enabled(): boolean;
536
+ /**
537
+ * Get current scale
538
+ */
539
+ get currentScale(): number;
540
+ /**
541
+ * Get LOD stats
542
+ */
543
+ getStats(): {
544
+ enabled: boolean;
545
+ currentScale: number;
546
+ appliedNodes: number;
547
+ currentLevel: LODLevel | null;
548
+ };
549
+ /**
550
+ * Set custom LOD levels
551
+ */
552
+ setLevels(levels: LODLevel[]): void;
553
+ }
554
+
555
+ interface VirtualizationStats {
556
+ total: number;
557
+ visible: number;
558
+ hidden: number;
559
+ cullingRate: number;
560
+ }
561
+ interface VirtualizationOptions {
562
+ enabled?: boolean;
563
+ bufferZone?: number;
564
+ throttleMs?: number;
565
+ lod?: LODOptions;
566
+ }
567
+ /**
568
+ * VirtualizationManager - manages node visibility for performance optimization
569
+ *
570
+ * IMPORTANT: This is an ADDITIONAL optimization on top of Konva framework.
571
+ * Konva does not provide automatic viewport virtualization, so this implementation is necessary.
572
+ *
573
+ * Main idea: render only nodes that are within the viewport (visible area).
574
+ * This provides a significant performance boost when dealing with many nodes.
575
+ *
576
+ * Optimizations (uses built-in Konva APIs):
577
+ * 1. visible: false - node is not rendered (Konva recommendation)
578
+ * 2. listening: false - node does not handle events (Konva recommendation)
579
+ * 3. Buffer zone - render slightly more than viewport for smoothness
580
+ * 4. Throttling - limits update frequency
581
+ * 5. getClientRect() - Konva automatically caches results internally
582
+ *
583
+ * Konva documentation: https://konvajs.org/docs/performance/All_Performance_Tips.html
584
+ */
585
+ declare class VirtualizationManager {
586
+ private _stage;
587
+ private _world;
588
+ private _nodeManager;
589
+ private _enabled;
590
+ private _bufferZone;
591
+ private _throttle;
592
+ private _viewport;
593
+ private _visibleNodes;
594
+ private _hiddenNodes;
595
+ private _updateScheduled;
596
+ private _lod;
597
+ constructor(_stage: Konva.Stage, _world: Konva.Group, _nodeManager: NodeManager, options?: VirtualizationOptions);
598
+ /**
599
+ * Updates viewport based on current position and scale of world
600
+ */
601
+ private _updateViewport;
602
+ /**
603
+ * Gets node bounding box in world coordinates (relative to world)
604
+ *
605
+ * OPTIMIZATION: Konva automatically caches getClientRect() results internally,
606
+ * so additional TTL-cache is not needed. Konva invalidates its cache on transformations,
607
+ * which is more reliable than our TTL-approach.
608
+ */
609
+ private _getNodeBBox;
610
+ /**
611
+ * Checks if node is within viewport
612
+ */
613
+ private _isNodeVisible;
614
+ /**
615
+ * Updates visibility of all nodes
616
+ */
617
+ updateVisibility(): void;
618
+ /**
619
+ * Sets up event listeners
620
+ */
621
+ private _setupListeners;
622
+ /**
623
+ * Schedules update for the next frame
624
+ */
625
+ private _scheduleUpdate;
626
+ /**
627
+ * Enables virtualization
628
+ */
629
+ enable(): void;
630
+ /**
631
+ * Disables virtualization (shows all nodes)
632
+ */
633
+ disable(): void;
634
+ /**
635
+ * Returns virtualization statistics
636
+ */
637
+ getStats(): VirtualizationStats;
638
+ /**
639
+ * Sets buffer zone size
640
+ */
641
+ setBufferZone(pixels: number): void;
642
+ /**
643
+ * Sets throttle for updates
644
+ */
645
+ setThrottle(ms: number): void;
646
+ /**
647
+ * Checks if virtualization is enabled
648
+ */
649
+ get enabled(): boolean;
650
+ /**
651
+ * Returns current viewport
652
+ */
653
+ get viewport(): {
654
+ x: number;
655
+ y: number;
656
+ width: number;
657
+ height: number;
658
+ };
659
+ /**
660
+ * Forcefully updates visibility (ignores throttle)
661
+ */
662
+ forceUpdate(): void;
663
+ /**
664
+ * Returns LOD Manager (if enabled)
665
+ */
666
+ get lod(): LODManager | null;
667
+ /**
668
+ * Destroys manager and releases resources
669
+ */
670
+ destroy(): void;
671
+ }
672
+
673
+ declare abstract class Plugin {
674
+ protected abstract onAttach(core: CoreEngine): void;
675
+ protected abstract onDetach(core: CoreEngine): void;
676
+ attach(core: CoreEngine): void;
677
+ detach(core: CoreEngine): void;
678
+ }
679
+
680
+ declare class Plugins {
681
+ private _core;
682
+ private _items;
683
+ constructor(core: CoreEngine, initial?: Plugin[]);
684
+ addPlugins(plugins: Plugin[]): Plugin[];
685
+ removePlugins(plugins: Plugin[]): Plugin[];
686
+ removeAllPlugins(): Plugin[];
687
+ list(): Plugin[];
688
+ get(name: string): Plugin | undefined;
689
+ }
690
+
691
+ interface CoreEngineOptions {
692
+ container: HTMLDivElement;
693
+ width?: number;
694
+ height?: number;
695
+ autoResize?: boolean;
696
+ backgroundColor?: string;
697
+ draggable?: boolean;
698
+ plugins?: Plugin[];
699
+ minScale?: number;
700
+ maxScale?: number;
701
+ virtualization?: {
702
+ enabled?: boolean;
703
+ bufferZone?: number;
704
+ throttleMs?: number;
705
+ };
706
+ }
707
+ declare class CoreEngine {
708
+ private _stage;
709
+ private _eventBus;
710
+ private _initialWidth;
711
+ private _initialHeight;
712
+ private _autoResize;
713
+ private _backgroundColor;
714
+ private _draggable;
715
+ private _minScale;
716
+ private _maxScale;
717
+ private _gridLayer;
718
+ readonly container: HTMLDivElement;
719
+ readonly nodes: NodeManager;
720
+ readonly camera: CameraManager;
721
+ readonly virtualization: VirtualizationManager;
722
+ readonly plugins: Plugins;
723
+ constructor(options: CoreEngineOptions);
724
+ get eventBus(): EventBus<CoreEvents>;
725
+ get stage(): Konva.Stage;
726
+ get gridLayer(): Konva.Layer;
727
+ get draggable(): boolean;
728
+ get autoResize(): boolean;
729
+ get backgroundColor(): string;
730
+ get initialWidth(): number;
731
+ get initialHeight(): number;
732
+ get minScale(): number;
733
+ get maxScale(): number;
734
+ setSize({ width, height }: {
735
+ width: number;
736
+ height: number;
737
+ }): void;
738
+ setBackgroundColor(color: string): void;
739
+ setDraggable(draggable: boolean): void;
740
+ }
741
+
742
+ interface LogoOptions {
743
+ src: string;
744
+ width: number;
745
+ height: number;
746
+ opacity?: number;
747
+ }
748
+ declare class LogoPlugin extends Plugin {
749
+ private _core?;
750
+ private _layer?;
751
+ private _image?;
752
+ private _src;
753
+ private _width;
754
+ private _height;
755
+ private _opacity;
756
+ constructor(options: LogoOptions);
757
+ protected onAttach(core: CoreEngine): void;
758
+ protected onDetach(core: CoreEngine): void;
759
+ setOpacity(opacity: number): void;
760
+ setSize({ width, height }: {
761
+ width: number;
762
+ height: number;
763
+ }): void;
764
+ setSource(src: string): void;
765
+ private _setImage;
766
+ private _loadImageFromString;
767
+ private _layout;
768
+ }
769
+
770
+ interface CameraHotkeysOptions {
771
+ target?: Window | Document | HTMLElement | EventTarget;
772
+ zoomStep?: number;
773
+ panStep?: number;
774
+ ignoreEditableTargets?: boolean;
775
+ enableArrows?: boolean;
776
+ enablePanning?: boolean;
777
+ allowMiddleButtonPan?: boolean;
778
+ allowRightButtonPan?: boolean;
779
+ disableContextMenu?: boolean;
780
+ }
781
+ declare class CameraHotkeysPlugin extends Plugin {
782
+ private _core?;
783
+ private _options;
784
+ private _attached;
785
+ private _panning;
786
+ private _last;
787
+ private _prevCursor;
788
+ private _prevStageDraggable?;
789
+ constructor(options?: CameraHotkeysOptions);
790
+ setOptions(patch: Partial<CameraHotkeysOptions>): void;
791
+ protected onAttach(core: CoreEngine): void;
792
+ protected onDetach(core: CoreEngine): void;
793
+ private _onWheelDOM;
794
+ private _onMouseDownKonva;
795
+ private _onMouseMoveKonva;
796
+ private _onMouseUpKonva;
797
+ private _onMouseLeaveKonva;
798
+ private _onContextMenuDOM;
799
+ private _handleKeyDown;
800
+ private _isEditableTarget;
801
+ private _isTouchpadWheel;
802
+ private _pan;
803
+ }
804
+
805
+ interface MultiGroupControllerDeps {
806
+ ensureTempMulti: (nodes: BaseNode[]) => void;
807
+ destroyTempMulti: () => void;
808
+ commitTempMultiToGroup: () => void;
809
+ isActive: () => boolean;
810
+ forceUpdate: () => void;
811
+ onWorldChanged?: () => void;
812
+ isInsideTempByTarget?: (target: Konva.Node) => boolean;
813
+ }
814
+ /**
815
+ * MultiGroupController — thin controller encapsulating work with temporary multi-group.
816
+ * Actual logic lives in passed dependencies (SelectionPlugin),
817
+ * thanks to which we don't duplicate code for frames/overlays and behavior.
818
+ */
819
+ declare class MultiGroupController {
820
+ private deps;
821
+ constructor(deps: MultiGroupControllerDeps);
822
+ ensure(nodes: BaseNode[]): void;
823
+ destroy(): void;
824
+ commitToPermanentGroup(): void;
825
+ isActive(): boolean;
826
+ forceUpdateOverlays(): void;
827
+ onWorldChanged(): void;
828
+ isInsideTempByTarget(target: Konva.Node): boolean;
829
+ }
830
+
831
+ interface SelectionPluginOptions {
832
+ dragEnabled?: boolean;
833
+ enableTransformer?: boolean;
834
+ deselectOnEmptyClick?: boolean;
835
+ selectablePredicate?: (node: Konva.Node) => boolean;
836
+ autoPanEnabled?: boolean;
837
+ autoPanEdgePx?: number;
838
+ autoPanMaxSpeedPx?: number;
839
+ }
840
+ /**
841
+ * Universal selection and dragging plugin for nodes compatible with BaseNode.
842
+ *
843
+ * Default behavior:
844
+ * - Click on node in NodeManager layer selects the node
845
+ * - Selected node becomes draggable (dragEnabled)
846
+ * - Click on empty area deselects (deselectOnEmptyClick)
847
+ * - Optionally enable Konva.Transformer (enableTransformer)
848
+ */
849
+ declare class SelectionPlugin extends Plugin {
850
+ private _core?;
851
+ private _options;
852
+ private _selected;
853
+ private _prevDraggable;
854
+ private _transformer;
855
+ private _transformerWasVisibleBeforeDrag;
856
+ private _cornerHandlesWereVisibleBeforeDrag;
857
+ private _sizeLabelWasVisibleBeforeDrag;
858
+ private _rotateHandlesWereVisibleBeforeDrag;
859
+ private _cornerHandlesGroup;
860
+ private _cornerHandles;
861
+ private _cornerHandlesSuppressed;
862
+ private _transformOppositeCorner;
863
+ private _sizeLabel;
864
+ private _radiusLabel;
865
+ private _rotateHandlesGroup;
866
+ private _rotateHandles;
867
+ private _rotateDragState;
868
+ private _rotateCenterAbsStart;
869
+ private _prevStageDraggableBeforeRotate;
870
+ private _worldSyncRafId;
871
+ private _onCameraZoomEvent;
872
+ private _hoverTr;
873
+ private _isPointerDown;
874
+ private _autoPanRafId;
875
+ private _autoPanActive;
876
+ private _autoPanEdgePx;
877
+ private _autoPanMaxSpeedPx;
878
+ private _draggingNode;
879
+ private _ratioKeyPressed;
880
+ private _onGlobalKeyDown;
881
+ private _onGlobalKeyUp;
882
+ private _tempMultiSet;
883
+ private _tempMultiGroup;
884
+ private _tempMultiTr;
885
+ private _tempOverlay;
886
+ private _tempRotateHandlesGroup;
887
+ private _tempRotateHandles;
888
+ private _tempPlacement;
889
+ getMultiGroupController(): MultiGroupController;
890
+ private _tempMultiSizeLabel;
891
+ private _tempMultiHitRect;
892
+ private _multiCtrl;
893
+ private _startAutoPanLoop;
894
+ private _stopAutoPanLoop;
895
+ /**
896
+ * Deferred redraw (throttling)
897
+ * Groups multiple batchDraw calls into one
898
+ */
899
+ private _scheduleBatchDraw;
900
+ private _parentGroupDuringChildEdit;
901
+ private _parentGroupPrevDraggable;
902
+ private _dragMoveScheduled;
903
+ private _batchDrawScheduled;
904
+ private _hoverThrottle;
905
+ private _uiUpdateDebounce;
906
+ constructor(options?: SelectionPluginOptions);
907
+ setOptions(patch: Partial<SelectionPluginOptions>): void;
908
+ protected onAttach(core: CoreEngine): void;
909
+ protected onDetach(core: CoreEngine): void;
910
+ private _onMouseDown;
911
+ private _select;
912
+ private _clearSelection;
913
+ private _ensureTempMulti;
914
+ private _destroyTempMulti;
915
+ private _updateTempRotateHandlesPosition;
916
+ private _updateTempMultiSizeLabel;
917
+ private _updateTempMultiHitRect;
918
+ private _commitTempMultiToGroup;
919
+ private _tryUngroupSelectedGroup;
920
+ private _ensureHoverTr;
921
+ private _destroyHoverTr;
922
+ private _onHoverMoveThrottled;
923
+ private _onHoverMove;
924
+ private _onHoverDown;
925
+ private _onHoverUp;
926
+ private _onHoverLeave;
927
+ private _refreshTransformer;
928
+ private _restyleSideAnchors;
929
+ private _setupRotateHandles;
930
+ private _destroyRotateHandles;
931
+ private _getNodeCenterAbs;
932
+ private _updateRotateHandlesPosition;
933
+ private _setupSizeLabel;
934
+ private _scheduleUIUpdate;
935
+ private _updateSizeLabel;
936
+ private _destroySizeLabel;
937
+ private _isCornerRadiusSupported;
938
+ private _getCornerRadiusArray;
939
+ private _setCornerRadiusArray;
940
+ private _setupCornerRadiusHandles;
941
+ private _destroyCornerRadiusHandles;
942
+ private _bakeRectScale;
943
+ private _updateCornerRadiusHandlesPosition;
944
+ private _updateCornerRadiusHandlesVisibility;
945
+ private _ensureRadiusLabel;
946
+ private _updateRadiusLabelAt;
947
+ private _showRadiusLabelForCorner;
948
+ private _hideRadiusLabel;
949
+ private _destroyRadiusLabel;
950
+ private _findBaseNodeByTarget;
951
+ private _onNodeRemoved;
952
+ }
953
+
954
+ interface GridPluginOptions {
955
+ stepX?: number;
956
+ stepY?: number;
957
+ color?: string;
958
+ lineWidth?: number;
959
+ visible?: boolean;
960
+ minScaleToShow?: number | null;
961
+ enableSnap?: boolean;
962
+ }
963
+ /**
964
+ * GridPlugin — draws a grid and implements snap to grid on drag/resize.
965
+ * Architecture is identical to other plugins: onAttach/onDetach, own layer with Konva.Shape.
966
+ *
967
+ * Important points of the current architecture:
968
+ * - Panning/scale is performed by Stage transformations.
969
+ * - Nodes are placed on the NodeManager layer (core.nodes.layer), also Transformers are added to it.
970
+ */
971
+ declare class GridPlugin extends Plugin {
972
+ private _core?;
973
+ private _layer;
974
+ private _shape;
975
+ private _stepX;
976
+ private _stepY;
977
+ private _color;
978
+ private _lineWidth;
979
+ private _visible;
980
+ private _minScaleToShow;
981
+ private _enableSnap;
982
+ private _dragMoveHandler;
983
+ private _nodesAddHandler;
984
+ private _nodesRemoveHandler;
985
+ private _redrawScheduled;
986
+ private _transformersCache;
987
+ private _cacheInvalidated;
988
+ constructor(options?: GridPluginOptions);
989
+ protected onAttach(core: CoreEngine): void;
990
+ /**
991
+ * Deferred redraw (throttling)
992
+ */
993
+ private _scheduleRedraw;
994
+ protected onDetach(core: CoreEngine): void;
995
+ setVisible(visible: boolean): void;
996
+ get stepX(): number;
997
+ get stepY(): number;
998
+ get minScaleToShow(): number | null;
999
+ setStep(stepX: number, stepY: number): void;
1000
+ setMinScaleToShow(value: number | null): void;
1001
+ setSnap(enabled: boolean): void;
1002
+ }
1003
+
1004
+ interface RulerPluginOptions {
1005
+ thicknessPx?: number;
1006
+ fontFamily?: string;
1007
+ fontSizePx?: number;
1008
+ color?: string;
1009
+ bgColor?: string;
1010
+ borderColor?: string;
1011
+ enabled?: boolean;
1012
+ }
1013
+ declare class RulerPlugin extends Plugin {
1014
+ private _core?;
1015
+ private _options;
1016
+ private _layer;
1017
+ private _hGroup?;
1018
+ private _vGroup?;
1019
+ private _hBg?;
1020
+ private _vBg?;
1021
+ private _hTicksShape?;
1022
+ private _vTicksShape?;
1023
+ private _hBorder?;
1024
+ private _vBorder?;
1025
+ private _redrawScheduled;
1026
+ private _lastRedrawTime;
1027
+ private _redrawThrottleMs;
1028
+ private _panThrottleMs;
1029
+ private _cachedActiveGuide;
1030
+ private _cacheInvalidated;
1031
+ private _stepsCache;
1032
+ constructor(options?: RulerPluginOptions);
1033
+ /**
1034
+ * Calculate optimal step for ruler ticks
1035
+ * Uses nice numbers: 1, 2, 5, 10, 20, 50, 100 and so on
1036
+ */
1037
+ private _calculateNiceStep;
1038
+ /**
1039
+ * Format number for display on ruler
1040
+ * Always returns an integer without decimal places
1041
+ */
1042
+ private _formatNumber;
1043
+ /**
1044
+ * Calculate and cache parameters for ticks for current scale
1045
+ */
1046
+ private _getStepsConfig;
1047
+ protected onAttach(core: CoreEngine): void;
1048
+ protected onDetach(core: CoreEngine): void;
1049
+ /**
1050
+ * Get active guide from RulerGuidesPlugin (with caching)
1051
+ */
1052
+ private _getActiveGuideInfo;
1053
+ /**
1054
+ * Invalidate active guide cache
1055
+ */
1056
+ private _invalidateGuideCache;
1057
+ /**
1058
+ * Universal ruler drawing (horizontal or vertical)
1059
+ * @param ctx - canvas context
1060
+ * @param axis - ruler axis ('h' for horizontal, 'v' for vertical)
1061
+ * @param activeGuide - cached active guide info
1062
+ */
1063
+ private _drawRuler;
1064
+ /**
1065
+ * Draw horizontal ruler
1066
+ * @param activeGuide - cached active guide info
1067
+ */
1068
+ private _drawHorizontalRuler;
1069
+ /**
1070
+ * Draw vertical ruler
1071
+ * @param activeGuide - cached active guide info
1072
+ */
1073
+ private _drawVerticalRuler;
1074
+ /**
1075
+ * Full ruler redraw
1076
+ */
1077
+ private _redraw;
1078
+ /**
1079
+ * Deferred redraw with improved throttling
1080
+ * Groups fast zoom/pan events for optimization
1081
+ * @param isPanning - true for panning (more aggressive throttling)
1082
+ */
1083
+ private _scheduleRedraw;
1084
+ show(): void;
1085
+ hide(): void;
1086
+ /**
1087
+ * Toggle ruler visibility
1088
+ */
1089
+ toggle(): void;
1090
+ /**
1091
+ * Check if ruler is visible
1092
+ */
1093
+ isVisible(): boolean;
1094
+ }
1095
+
1096
+ interface RulerGuidesPluginOptions {
1097
+ guideColor?: string;
1098
+ activeColor?: string;
1099
+ rulerThicknessPx?: number;
1100
+ snapToGrid?: boolean;
1101
+ gridStep?: number;
1102
+ }
1103
+ declare class RulerGuidesPlugin extends Plugin {
1104
+ private _core?;
1105
+ private _options;
1106
+ private _guidesLayer;
1107
+ private _guides;
1108
+ private _activeGuide;
1109
+ private _draggingGuide;
1110
+ private _rulerLayerCache;
1111
+ private _updateScheduled;
1112
+ private _dragMoveScheduled;
1113
+ private _batchDrawScheduled;
1114
+ constructor(options?: RulerGuidesPluginOptions);
1115
+ protected onAttach(core: CoreEngine): void;
1116
+ protected onDetach(core: CoreEngine): void;
1117
+ /**
1118
+ * Schedules update of guide positions (without throttling for smoothness)
1119
+ */
1120
+ private _scheduleUpdate;
1121
+ /**
1122
+ * Updates positions of all guides when world transform changes
1123
+ */
1124
+ private _updateGuidesPositions;
1125
+ /**
1126
+ * Snaps coordinate to grid
1127
+ */
1128
+ private _snapToGrid;
1129
+ /**
1130
+ * Schedules batchDraw for grouping updates
1131
+ */
1132
+ private _scheduleBatchDraw;
1133
+ /**
1134
+ * Starts creating a guide line from ruler
1135
+ */
1136
+ private _startCreateGuide;
1137
+ private _setActiveGuide;
1138
+ /**
1139
+ * Get active guide
1140
+ */
1141
+ getActiveGuide(): Konva.Line | null;
1142
+ /**
1143
+ * Get active guide info
1144
+ * @returns { type: 'h' | 'v', coord: number } | null
1145
+ */
1146
+ getActiveGuideInfo(): {
1147
+ type: 'h' | 'v';
1148
+ coord: number;
1149
+ } | null;
1150
+ /**
1151
+ * Remove active guide
1152
+ */
1153
+ removeActiveGuide(): void;
1154
+ /**
1155
+ * Get all guides
1156
+ */
1157
+ getGuides(): Konva.Line[];
1158
+ /**
1159
+ * Remove all guides
1160
+ */
1161
+ clearGuides(): void;
1162
+ }
1163
+
1164
+ interface RulerHighlightPluginOptions {
1165
+ highlightColor?: string;
1166
+ highlightOpacity?: number;
1167
+ rulerThicknessPx?: number;
1168
+ }
1169
+ /**
1170
+ * RulerHighlightPlugin
1171
+ * Highlights the areas of the coordinate system that are occupied by selected objects
1172
+ * Works only if RulerPlugin and SelectionPlugin are present
1173
+ */
1174
+ declare class RulerHighlightPlugin extends Plugin {
1175
+ private _core?;
1176
+ private _options;
1177
+ private _highlightLayer;
1178
+ private _hGroup;
1179
+ private _vGroup;
1180
+ private _hHighlights;
1181
+ private _vHighlights;
1182
+ private _updateDebounce;
1183
+ private _transformersCache;
1184
+ private _cacheInvalidated;
1185
+ constructor(options?: RulerHighlightPluginOptions);
1186
+ protected onAttach(core: CoreEngine): void;
1187
+ protected onDetach(core: CoreEngine): void;
1188
+ /**
1189
+ * Schedules an update (debouncing)
1190
+ */
1191
+ private _scheduleUpdate;
1192
+ /**
1193
+ * Invalidates the cache of transformers
1194
+ */
1195
+ private _invalidateCache;
1196
+ /**
1197
+ * Updates highlights based on selected objects
1198
+ */
1199
+ private _updateHighlights;
1200
+ /**
1201
+ * Recursively collects all individual objects (unwraps groups)
1202
+ */
1203
+ private _collectNodes;
1204
+ /**
1205
+ * Merges overlapping and adjacent segments
1206
+ */
1207
+ private _mergeSegments;
1208
+ /**
1209
+ * Get list of selected Konva nodes (with group unwrapping)
1210
+ * Optimization: cache transformers
1211
+ */
1212
+ private _getSelectedKonvaNodes;
1213
+ /**
1214
+ * Public method to force update highlights
1215
+ * Useful to call when selection changes from outside
1216
+ */
1217
+ update(): void;
1218
+ }
1219
+
1220
+ interface RulerManagerPluginOptions {
1221
+ enabled?: boolean;
1222
+ }
1223
+ /**
1224
+ * RulerManagerPlugin
1225
+ * Manages visibility of ruler and guides on Shift+R
1226
+ */
1227
+ declare class RulerManagerPlugin extends Plugin {
1228
+ private _core?;
1229
+ private _options;
1230
+ private _visible;
1231
+ constructor(options?: RulerManagerPluginOptions);
1232
+ protected onAttach(core: CoreEngine): void;
1233
+ protected onDetach(_core: CoreEngine): void;
1234
+ /**
1235
+ * Bind keyboard events
1236
+ */
1237
+ private _bindKeyboardEvents;
1238
+ /**
1239
+ * Unbind keyboard events
1240
+ */
1241
+ private _unbindKeyboardEvents;
1242
+ /**
1243
+ * Keyboard event handler
1244
+ */
1245
+ private _handleKeyDown;
1246
+ /**
1247
+ * Toggle visibility of ruler and guides
1248
+ */
1249
+ toggle(): void;
1250
+ /**
1251
+ * Show ruler and guides
1252
+ */
1253
+ show(): void;
1254
+ /**
1255
+ * Hide ruler and guides
1256
+ */
1257
+ hide(): void;
1258
+ /**
1259
+ * Check if ruler is visible
1260
+ */
1261
+ isVisible(): boolean;
1262
+ /**
1263
+ * Remove active guide line
1264
+ * @returns true if guide was removed, false if no active guide
1265
+ */
1266
+ deleteActiveGuide(): boolean;
1267
+ }
1268
+
1269
+ interface AreaSelectionPluginOptions {
1270
+ rectStroke?: string;
1271
+ rectFill?: string;
1272
+ rectStrokeWidth?: number;
1273
+ rectOpacity?: number;
1274
+ enableKeyboardShortcuts?: boolean;
1275
+ }
1276
+ /**
1277
+ * AreaSelectionPlugin
1278
+ * - Drag LKM over empty space draws selection rectangle (marquee) in screen coordinates
1279
+ * - All nodes whose client rectangles intersect the rectangle are temporarily grouped
1280
+ * - Click outside — temporary group is removed, nodes return to their original positions
1281
+ * - Ctrl+G — lock in permanent group (GroupNode through NodeManager)
1282
+ * - Ctrl+Shift+G — unlock selected permanent group
1283
+ */
1284
+ declare class AreaSelectionPlugin extends Plugin {
1285
+ private _core?;
1286
+ private _layer;
1287
+ private _rect;
1288
+ private _start;
1289
+ private _transformer;
1290
+ private _selecting;
1291
+ private _options;
1292
+ constructor(options?: AreaSelectionPluginOptions);
1293
+ protected onAttach(core: CoreEngine): void;
1294
+ protected onDetach(core: CoreEngine): void;
1295
+ private _finalizeArea;
1296
+ private _clearSelection;
1297
+ private _getSelectionPlugin;
1298
+ private _rectsIntersect;
1299
+ private _findOwningGroupBaseNode;
1300
+ private _isAncestor;
1301
+ private _isPermanentGroupSelected;
1302
+ private _currentGroupNode;
1303
+ private _pointerInsidePermanentGroupBBox;
1304
+ }
1305
+
1306
+ interface NodeHotkeysOptions {
1307
+ target?: Window | Document | HTMLElement | EventTarget;
1308
+ ignoreEditableTargets?: boolean;
1309
+ }
1310
+ declare class NodeHotkeysPlugin extends Plugin {
1311
+ private _core?;
1312
+ private _options;
1313
+ private _clipboard;
1314
+ private _selectionPlugin?;
1315
+ constructor(options?: NodeHotkeysOptions);
1316
+ protected onAttach(core: CoreEngine): void;
1317
+ protected onDetach(_core: CoreEngine): void;
1318
+ private _onKeyDown;
1319
+ private _isEditableTarget;
1320
+ private _handleCopy;
1321
+ private _handleCut;
1322
+ private _handlePaste;
1323
+ private _handleDelete;
1324
+ private _getSelectedNodes;
1325
+ private _deleteNodes;
1326
+ private _serializeNode;
1327
+ private _serializeKonvaNode;
1328
+ private _getNodeTypeFromKonva;
1329
+ private _deserializeNode;
1330
+ private _getPastePosition;
1331
+ private _isPointerOnScreen;
1332
+ private _getScreenCenter;
1333
+ private _getClipboardCenter;
1334
+ private _computeSelectionWorldCenter;
1335
+ private _handleMoveUp;
1336
+ private _handleMoveDown;
1337
+ /**
1338
+ * Checks if the node is inside a real group (not the group itself)
1339
+ */
1340
+ private _isNodeInsidePermanentGroup;
1341
+ /**
1342
+ * Checks if the node is inside a real group
1343
+ * - For group itself — do nothing (moveUp/moveDown already applied to the group)
1344
+ * - For node inside group — FORBIDDEN to change z-index
1345
+ */
1346
+ private _syncGroupZIndex;
1347
+ }
1348
+
1349
+ /**
1350
+ * ThrottleHelper - utility for throttling (limiting the frequency of calls)
1351
+ *
1352
+ * Used to limit the frequency of operation execution to a certain number of times per second.
1353
+ * For example, to limit UI updates to 60 FPS (16ms) or 30 FPS (32ms).
1354
+ *
1355
+ * @example
1356
+ * ```typescript
1357
+ * private _throttle = new ThrottleHelper(16); // 60 FPS
1358
+ *
1359
+ * onMouseMove() {
1360
+ * if (!this._throttle.shouldExecute()) return;
1361
+ * // Execute expensive operation
1362
+ * }
1363
+ * ```
1364
+ */
1365
+ declare class ThrottleHelper {
1366
+ private _lastTime;
1367
+ private _throttle;
1368
+ /**
1369
+ * @param throttleMs - minimum interval between calls in milliseconds
1370
+ */
1371
+ constructor(throttleMs?: number);
1372
+ /**
1373
+ * Checks if the operation can be executed
1374
+ * @returns true if enough time has passed since the last call
1375
+ */
1376
+ shouldExecute(): boolean;
1377
+ /**
1378
+ * Resets the timer (the next call will be executed immediately)
1379
+ */
1380
+ reset(): void;
1381
+ /**
1382
+ * Changes the throttling interval
1383
+ */
1384
+ setThrottle(throttleMs: number): void;
1385
+ /**
1386
+ * Returns the current throttling interval
1387
+ */
1388
+ getThrottle(): number;
1389
+ }
1390
+
1391
+ /**
1392
+ * DebounceHelper - utility for debouncing (delayed execution)
1393
+ *
1394
+ * Used to group multiple calls into one through requestAnimationFrame.
1395
+ * Useful for optimizing UI updates - instead of updating on every event,
1396
+ * we update once in the next frame.
1397
+ *
1398
+ * @example
1399
+ * ```typescript
1400
+ * private _debounce = new DebounceHelper();
1401
+ *
1402
+ * onTransform() {
1403
+ * this._debounce.schedule(() => {
1404
+ * this._updateUI();
1405
+ * });
1406
+ * }
1407
+ * ```
1408
+ */
1409
+ declare class DebounceHelper {
1410
+ private _scheduled;
1411
+ /**
1412
+ * Schedules execution of callback in the next frame
1413
+ * If already scheduled - ignores repeated calls
1414
+ *
1415
+ * @param callback - function to execute
1416
+ */
1417
+ schedule(callback: () => void): void;
1418
+ /**
1419
+ * Checks if execution is scheduled
1420
+ */
1421
+ isScheduled(): boolean;
1422
+ /**
1423
+ * Cancels scheduled execution
1424
+ * Note: does not cancel already scheduled requestAnimationFrame,
1425
+ * but prevents callback execution
1426
+ */
1427
+ cancel(): void;
1428
+ }
1429
+
1430
+ export { ArcNode, AreaSelectionPlugin, ArrowNode, CameraHotkeysPlugin, CameraManager, CircleNode, CoreEngine, DebounceHelper, EllipseNode, EventBus, GridPlugin, GroupNode, ImageNode, LogoPlugin, NodeHotkeysPlugin, NodeManager, Plugins, RegularPolygonNode, RingNode, RulerGuidesPlugin, RulerHighlightPlugin, RulerManagerPlugin, RulerPlugin, SelectionPlugin, ShapeNode, StarNode, TextNode, ThrottleHelper };