goatdee-canvas 0.0.1

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.
Files changed (59) hide show
  1. package/README.md +536 -0
  2. package/dist/ZHCanvasCore.js +18 -0
  3. package/dist/ZHCanvasCore.wasm +0 -0
  4. package/dist/bind/binding.d.ts +2 -0
  5. package/dist/bind/constant.d.ts +1 -0
  6. package/dist/bind/core/bitmap-image.d.ts +5 -0
  7. package/dist/bind/core/matrix.d.ts +45 -0
  8. package/dist/bind/core/scaler-context.d.ts +29 -0
  9. package/dist/bind/core/web-mask.d.ts +26 -0
  10. package/dist/bind/tgfx-module.d.ts +4 -0
  11. package/dist/bind/tgfx.d.ts +15 -0
  12. package/dist/bind/types.d.ts +133 -0
  13. package/dist/bind/utils/canvas.d.ts +8 -0
  14. package/dist/bind/utils/decorators.d.ts +3 -0
  15. package/dist/bind/utils/font-family.d.ts +2 -0
  16. package/dist/bind/utils/measure-text.d.ts +10 -0
  17. package/dist/bind/utils/type-utils.d.ts +1 -0
  18. package/dist/bind/utils/ua.d.ts +7 -0
  19. package/dist/index.cjs +17631 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.d.ts +1250 -0
  22. package/dist/index.js +17585 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/src/CanvasOverlay.d.ts +8 -0
  25. package/dist/src/OverlayItem.d.ts +51 -0
  26. package/dist/src/canvas-overlay/index.d.ts +9 -0
  27. package/dist/src/canvas-overlay/utils.d.ts +50 -0
  28. package/dist/src/index.d.ts +3 -0
  29. package/dist/src/listener.d.ts +30 -0
  30. package/dist/src/manager.d.ts +108 -0
  31. package/dist/src/services/pasteService.d.ts +4 -0
  32. package/dist/src/static/cursor.icon.d.ts +6 -0
  33. package/dist/src/types.d.ts +72 -0
  34. package/dist/src/utils/clipboard/core.d.ts +31 -0
  35. package/dist/src/utils/clipboard/index.d.ts +3 -0
  36. package/dist/src/utils/clipboard/read.d.ts +17 -0
  37. package/dist/src/utils/clipboard/transform.d.ts +10 -0
  38. package/dist/src/utils/clipboard.d.ts +1 -0
  39. package/dist/src/utils/fabricConverter.d.ts +23 -0
  40. package/dist/src/utils/fontLoader.d.ts +50 -0
  41. package/dist/src/utils/html2json/converters.d.ts +47 -0
  42. package/dist/src/utils/html2json/element-helpers.d.ts +60 -0
  43. package/dist/src/utils/html2json/index.d.ts +16 -0
  44. package/dist/src/utils/html2json/parsers.d.ts +47 -0
  45. package/dist/src/utils/html2json/renderers.d.ts +95 -0
  46. package/dist/src/utils/html2json/types.d.ts +104 -0
  47. package/dist/src/utils/html2json/utils.d.ts +68 -0
  48. package/dist/src/utils/imageLoader.d.ts +10 -0
  49. package/dist/src/utils/imageLoader.example.d.ts +17 -0
  50. package/dist/src/utils/imageLoader.worker.d.ts +15 -0
  51. package/dist/src/utils/imageUpload.d.ts +1 -0
  52. package/dist/src/utils/index.d.ts +7 -0
  53. package/dist/src/utils/safariCompatibility.d.ts +71 -0
  54. package/dist/src/utils/safariDataCloneFix.d.ts +32 -0
  55. package/dist/src/utils/styles.d.ts +4 -0
  56. package/dist/src/utils/utils.d.ts +23 -0
  57. package/dist/src/utils/viewState.d.ts +9 -0
  58. package/dist/wasm/ZHCanvasCore.d.ts +2 -0
  59. package/package.json +58 -0
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ interface CanvasOverlayProps {
3
+ canvasRef: React.RefObject<any>;
4
+ canvasDomRef: React.RefObject<HTMLCanvasElement>;
5
+ renderOverlay?: () => React.ReactNode;
6
+ }
7
+ export declare function CanvasOverlay({ canvasRef, canvasDomRef, renderOverlay, }: CanvasOverlayProps): import("react/jsx-runtime").JSX.Element | null;
8
+ export {};
@@ -0,0 +1,51 @@
1
+ export interface OverlayItemInfo {
2
+ element: HTMLElement;
3
+ rectId: string | null;
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ export interface OverlayItemsManager {
10
+ items: Map<HTMLElement, OverlayItemInfo>;
11
+ isCanvasReady: boolean;
12
+ resizeObserver: ResizeObserver;
13
+ isReady: () => boolean;
14
+ }
15
+ /**
16
+ * 从 DOM 元素读取位置和尺寸信息
17
+ */
18
+ export declare function readElementBounds(element: HTMLElement): {
19
+ x: number;
20
+ y: number;
21
+ width: number;
22
+ height: number;
23
+ } | null;
24
+ /**
25
+ * 为 DOM 元素创建或更新占位矩形
26
+ */
27
+ export declare function syncOverlayItem(element: HTMLElement, info: OverlayItemInfo, isCanvasReady: boolean): Promise<void>;
28
+ /**
29
+ * 清理占位矩形
30
+ */
31
+ export declare function cleanupOverlayItem(info: OverlayItemInfo): void;
32
+ /**
33
+ * 扫描 overlay 下的一级子元素
34
+ */
35
+ export declare function scanElements(overlay: HTMLElement, manager: OverlayItemsManager): void;
36
+ /**
37
+ * 同步所有元素
38
+ */
39
+ export declare function syncAllElements(manager: OverlayItemsManager): void;
40
+ /**
41
+ * 检查 canvas 是否就绪
42
+ */
43
+ export declare function checkReady(manager: OverlayItemsManager): boolean;
44
+ /**
45
+ * 观察所有已存在元素
46
+ */
47
+ export declare function observeAllElements(manager: OverlayItemsManager): void;
48
+ /**
49
+ * 清理所有 overlay items
50
+ */
51
+ export declare function cleanupAllItems(manager: OverlayItemsManager, mutationObserver: MutationObserver): void;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface CanvasOverlayProps {
3
+ canvasRef: React.RefObject<any>;
4
+ canvasDomRef: React.RefObject<HTMLCanvasElement>;
5
+ renderOverlay?: () => React.ReactNode;
6
+ onRefreshReady?: (refresh: () => void) => void;
7
+ }
8
+ export declare function CanvasOverlay({ canvasRef, canvasDomRef, renderOverlay, onRefreshReady, }: CanvasOverlayProps): import("react/jsx-runtime").JSX.Element | null;
9
+ export {};
@@ -0,0 +1,50 @@
1
+ export interface OverlayItemInfo {
2
+ element: HTMLElement;
3
+ rectId: string | null;
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ export interface OverlayItemsManager {
10
+ items: Map<HTMLElement, OverlayItemInfo>;
11
+ isCanvasReady: boolean;
12
+ resizeObserver: ResizeObserver;
13
+ isReady: () => boolean;
14
+ }
15
+ /**
16
+ * 从 DOM 元素读取位置和尺寸信息
17
+ *
18
+ * 注意:如果元素使用了 transform 进行缩放,会读取到缩放后的实际视觉尺寸
19
+ * 同时会考虑 transform-origin 对位置的影响
20
+ */
21
+ export declare function readElementBounds(element: HTMLElement): {
22
+ x: number;
23
+ y: number;
24
+ width: number;
25
+ height: number;
26
+ } | null;
27
+ /**
28
+ * 为 DOM 元素创建或更新占位元素
29
+ */
30
+ export declare function syncOverlayItem(element: HTMLElement, info: OverlayItemInfo, isCanvasReady: boolean): Promise<void>;
31
+ /**
32
+ * 清理占位元素
33
+ */
34
+ export declare function cleanupOverlayItem(info: OverlayItemInfo): void;
35
+ /**
36
+ * 扫描 overlay 下的一级子元素
37
+ */
38
+ export declare function scanElements(overlay: HTMLElement, manager: OverlayItemsManager): void;
39
+ /**
40
+ * 同步所有元素
41
+ */
42
+ export declare function syncAllElements(manager: OverlayItemsManager): void;
43
+ /**
44
+ * 检查 canvas 是否就绪
45
+ */
46
+ export declare function checkReady(manager: OverlayItemsManager): boolean;
47
+ /**
48
+ * 清理所有 overlay items
49
+ */
50
+ export declare function cleanupAllItems(manager: OverlayItemsManager, mutationObserver: MutationObserver): void;
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import { CanvasRef, CanvasProps } from "./types";
3
+ export declare const InfiniteCanvas: React.ForwardRefExoticComponent<Omit<CanvasProps, "ref"> & React.RefAttributes<CanvasRef>>;
@@ -0,0 +1,30 @@
1
+ export declare class Listener {
2
+ private readonly canvasPtr;
3
+ private readonly canvas;
4
+ private readonly doc;
5
+ private readonly cppListener;
6
+ private isDestroyed;
7
+ private readonly MOUSE_MOVE_THROTTLE;
8
+ private readonly WHEEL_THROTTLE;
9
+ constructor(canvasPtr: any, canvas: HTMLCanvasElement);
10
+ private _addListener;
11
+ private _removeListener;
12
+ private _addOrRemove;
13
+ private _checkDestroyed;
14
+ private _onMouseDown;
15
+ private _onMouseMove;
16
+ private _onMouseUp;
17
+ private _onMouseWheel;
18
+ private _onContextMenu;
19
+ private _onClick;
20
+ private _onDocClick;
21
+ private _onDblClick;
22
+ private _onKeyDown;
23
+ private _onKeyUp;
24
+ private _onCursorChange;
25
+ /**
26
+ * 检查元素是否为输入元素
27
+ */
28
+ private _isInputElement;
29
+ destroy(): void;
30
+ }
@@ -0,0 +1,108 @@
1
+ declare class Manager {
2
+ private static instance_;
3
+ private canvasInstance_;
4
+ private module_;
5
+ private moduleFactory_;
6
+ private moduleInstance_;
7
+ private isInitialized_;
8
+ private registeredImages;
9
+ private imageRegistrationTasks;
10
+ private registeredFonts;
11
+ private uploadAction_;
12
+ private uploadHeader_;
13
+ private viewportWidth_;
14
+ private viewportHeight_;
15
+ private constructor();
16
+ static getInstance(): Manager;
17
+ registerModuleFactory(factory: () => Promise<any>): void;
18
+ getOrCreateModule(): Promise<any>;
19
+ registerCanvas(canvas: any, module: any): void;
20
+ setViewportSize(width: number, height: number): void;
21
+ getViewportSize(): {
22
+ width: number;
23
+ height: number;
24
+ };
25
+ setUploadConfig(action?: string, header?: Record<string, string>): void;
26
+ getUploadConfig(): {
27
+ uploadAction?: string;
28
+ uploadHeader?: Record<string, string>;
29
+ };
30
+ isReady(): boolean;
31
+ getCanvas(): any;
32
+ getModule(): any;
33
+ clear(): void;
34
+ registerImageIfNeeded(src: string): Promise<void>;
35
+ hasRegisteredFont(fontName: string): boolean;
36
+ addRegisteredFont(fontName: string): void;
37
+ }
38
+ export declare const manager: Manager;
39
+ export declare const pan: (deltaX: number, deltaY: number) => void;
40
+ export declare const scale: (scale: number, x: number, y: number) => void;
41
+ export declare const centerObjects: (ids: string[], duration?: number) => void;
42
+ export declare const fitToScreen: (screen?: {
43
+ x: number;
44
+ y: number;
45
+ width: number;
46
+ height: number;
47
+ }) => Promise<void>;
48
+ export declare const worldToCanvas: (x: number, y: number) => {
49
+ x: number;
50
+ y: number;
51
+ };
52
+ export declare const getScale: () => number;
53
+ export declare const getActiveObjects: () => any;
54
+ export declare const getBounds: () => {
55
+ left: number;
56
+ top: number;
57
+ width: number;
58
+ height: number;
59
+ } | null;
60
+ export declare const setObjectProperties: (id: string, properties: any) => Promise<void>;
61
+ export declare const registerFonts: (fonts: {
62
+ fontName: string;
63
+ url: string;
64
+ }[]) => Promise<void>;
65
+ export declare const switchToCreatingElement: (creating: boolean, type?: string, options?: any) => Promise<void>;
66
+ export declare const add: (type: string, properties: any) => Promise<string>;
67
+ export declare const remove: (id?: string) => void;
68
+ export declare const select: (ids: string[]) => void;
69
+ export declare const copy: () => Promise<void>;
70
+ export interface PasteResult {
71
+ count: number;
72
+ message?: string;
73
+ }
74
+ export declare const paste: (x: number, y: number, clipboardEvent?: ClipboardEvent) => Promise<PasteResult>;
75
+ export declare const cut: () => Promise<void>;
76
+ export declare const canUndo: () => boolean;
77
+ export declare const canRedo: () => boolean;
78
+ export declare const undo: () => void;
79
+ export declare const redo: () => void;
80
+ export declare const getParentLayer: (id: string) => string;
81
+ export declare const getIndex: (id: string) => number;
82
+ export declare const moveUp: (id: string) => void;
83
+ export declare const moveDown: (id: string) => void;
84
+ export declare const moveTo: (parentId: string, index: number) => void;
85
+ export declare const bringToFront: (id: string) => void;
86
+ export declare const sendToBack: (id: string) => void;
87
+ export declare const canGroup: (ids: string[]) => boolean;
88
+ export declare const group: (ids: string[]) => string;
89
+ export declare const ungroup: (id: string) => void;
90
+ export declare const align: (alignment: string) => void;
91
+ export declare const arrange: (arrangement: string) => void;
92
+ export declare const switchToPan: (isPan: boolean) => void;
93
+ export declare const loadFromJSON: (json: any) => Promise<void>;
94
+ export declare const addFabricJSON: (fabricJSON: any, x?: number, y?: number) => Promise<string>;
95
+ export declare const exportToJSON: () => any;
96
+ /**
97
+ * 导出图片。
98
+ * @param type MIME 类型,如 'image/png'
99
+ * @param multiple 导出时的倍率(如 devicePixelRatio),用于高清图
100
+ * @param quality 质量,0–1
101
+ * @returns 选中为单图/多图时返回 src 或 src[];否则返回画布导出的结果(如 base64/Blob URL)。失败返回空字符串。
102
+ */
103
+ export declare const exportImage: (type?: string, multiple?: number, quality?: number) => Promise<string | string[]>;
104
+ export declare const getTextLayerSelection: (id: string) => {
105
+ start: number;
106
+ end: number;
107
+ } | null;
108
+ export {};
@@ -0,0 +1,4 @@
1
+ import { SerializedClipboardData, ClipboardImagePayload } from "@/utils/clipboard";
2
+ export declare const handleSerializedPaste: (payload: SerializedClipboardData | null, x: number, y: number) => Promise<number>;
3
+ export declare const handleTextPaste: (text: string | null, x: number, y: number) => Promise<number>;
4
+ export declare const handleImagePaste: (payloads: ClipboardImagePayload[], x: number, y: number) => Promise<number>;
@@ -0,0 +1,6 @@
1
+ export declare const cursor = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjBfZF8yMTUzNl83Mjc1OTQpIj4KPHBhdGggZD0iTTEwLjI3NTcgMTcuMTkwN0MxMC41NTcgMTcuNzE4NSAxMS40MTQzIDE3LjUxNTggMTEuNTExMSAxNi45MjU3QzEyLjAyMTkgMTMuODE0MSAxMy43MjYzIDEyLjE2MzYgMTYuNzcyOSAxMS42NjY5QzE3LjM2MjggMTEuNTcwOCAxNy41NjU1IDEwLjcxNDggMTcuMDM4OCAxMC40MzIyQzEzLjE5NDMgOC4zNjkxMiA4Ljk1MTkgNi4zMTEwNiA1Ljc1MTEyIDUuMjM4OTdDNS40MjU0NSA1LjEyOTg5IDUuMTE4NzkgNS40Mjg1OCA1LjIxODg5IDUuNzU3MTNDNi4yNzAzOCA5LjIwODI3IDguMjM0NTggMTMuMzYwNiAxMC4yNzU3IDE3LjE5MDdaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNNS44MDQ2OSA0LjU3NjE3TDUuOTU5OTYgNC42MTYyMUw2LjU4MjAzIDQuODMzMDFDOS43NDkzOCA1Ljk2NzczIDEzLjczOTUgNy45MTYyMSAxNy4zNDk2IDkuODUzNTJMMTcuNDU0MSA5LjkxNjAyQzE3Ljk1MTEgMTAuMjQ1IDE4LjA2NCAxMC44MTk4IDE3Ljk2NDggMTEuMjYyN0MxNy44NjY4IDExLjcgMTcuNTM1OCAxMi4xNTQ4IDE2Ljk5MDIgMTIuMjkyTDE2Ljg3ODkgMTIuMzE0NUMxNS40NTAzIDEyLjU0NzQgMTQuNDAxNiAxMy4wMzkyIDEzLjY1MzMgMTMuNzgxMkMxMi45NTIyIDE0LjQ3NjYgMTIuNDYyNyAxNS40NDM2IDEyLjIwNyAxNi43NjM3TDEyLjE1OTIgMTcuMDMyMkMxMi4wNTg2IDE3LjY0NDMgMTEuNTcxOSAxOC4wMTM5IDExLjEwNTUgMTguMTE4MkMxMC42NjIzIDE4LjIxNzEgMTAuMDg3IDE4LjEwMzIgOS43NTg3OSAxNy42MDQ1TDkuNjk2MjkgMTcuNDk5QzcuNzc3ODQgMTMuODk5MSA1LjkxMDcgOS45ODUxOSA0LjgwMjczIDYuNjE1MjNMNC41OTA4MiA1Ljk0ODI0QzQuMzUxNjIgNS4xNjI1OCA1LjAzMjg2IDQuNDM0MTMgNS44MDQ2OSA0LjU3NjE3WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxLjMxMjUiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8L2c+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2RfMjE1MzZfNzI3NTk0IiB4PSIyLjEzNDc3IiB5PSIzLjkwMDM5IiB3aWR0aD0iMTguMjY3NiIgaGVpZ2h0PSIxOC40MDYyIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHk9IjEuNzUiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMC44NzUiLz4KPGZlQ29sb3JNYXRyaXggdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuNCAwIi8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0iZWZmZWN0MV9kcm9wU2hhZG93XzIxNTM2XzcyNzU5NCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9ImVmZmVjdDFfZHJvcFNoYWRvd18yMTUzNl83Mjc1OTQiIHJlc3VsdD0ic2hhcGUiLz4KPC9maWx0ZXI+CjwvZGVmcz4KPC9zdmc+Cg==";
2
+ export declare const crosshair = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjBfZF8yMjQyNl83NTI3NDApIj4KPHBhdGggZD0iTTUgMTEuNUgxOCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIzLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTEuNSAxOEwxMS41IDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMy41IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KPHBhdGggZD0iTTUgMTEuNUgxOCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTEuNSAxOEwxMS41IDUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMS4yIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz4KPC9nPgo8ZGVmcz4KPGZpbHRlciBpZD0iZmlsdGVyMF9kXzIyNDI2Xzc1Mjc0MCIgeD0iMS4yNSIgeT0iMi4yNSIgd2lkdGg9IjIwLjUiIGhlaWdodD0iMjAuNSIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVDb2xvck1hdHJpeCBpbj0iU291cmNlQWxwaGEiIHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAxMjcgMCIgcmVzdWx0PSJoYXJkQWxwaGEiLz4KPGZlT2Zmc2V0IGR5PSIxIi8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjEiLz4KPGZlQ29tcG9zaXRlIGluMj0iaGFyZEFscGhhIiBvcGVyYXRvcj0ib3V0Ii8+CjxmZUNvbG9yTWF0cml4IHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwLjMgMCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9ImVmZmVjdDFfZHJvcFNoYWRvd18yMjQyNl83NTI3NDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJlZmZlY3QxX2Ryb3BTaGFkb3dfMjI0MjZfNzUyNzQwIiByZXN1bHQ9InNoYXBlIi8+CjwvZmlsdGVyPgo8L2RlZnM+Cjwvc3ZnPgo=";
3
+ export declare const pencil = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjBfZF80MF85OSkiPgo8cGF0aCBkPSJNMTcuMDUxOSA3Ljk0MDk5TDIwLjQ4MTYgMTEuMzcwN0wyMi4zMzMyIDkuNTE5MTFMMTguOTAzNSA2LjA4OTQyTDE3LjA1MTkgNy45NDA5OVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik02LjU1OTc0IDE4LjQzMzJDNi40NDY1NyAxOC41NDY0IDYuMzc5MDkgMTguNjk4MiA2LjM3MDI5IDE4Ljg1OEw2LjIxNjk3IDIxLjY1MjlDNi4xOTUxIDIyLjA1MTIgNi41MzM4OSAyMi4zNzUxIDYuOTMwODMgMjIuMzM1NUw5LjU3MjQzIDIyLjA3MThDOS43MjE3NyAyMi4wNTcgOS44NjE3OCAyMS45OTE0IDkuOTY3OTQgMjEuODg1M0wxOS42NjgxIDEyLjE4NDFMMTYuMjM4NSA4Ljc1NDQ2TDYuNTU5NzQgMTguNDMzMloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTguMTg2NyA1LjE4OTAzQzE4LjYwMzMgNC44NDkzOCAxOS4yMDQ3IDQuODQ5MzEgMTkuNjIxMyA1LjE4OTAzTDE5LjcwNzIgNS4yNjcxNkwyMy4xNTY0IDguNzE1NEMyMy42MDAxIDkuMTU5MTUgMjMuNTk5OSA5Ljg3ODk2IDIzLjE1NjQgMTAuMzIyOEwxMC43ODE0IDIyLjY5NzhDMTAuNDg3NCAyMi45OTE4IDEwLjEwMDQgMjMuMTc1MSA5LjY4NjY5IDIzLjIxNjRMNy4wNDUwOSAyMy40OEM1Ljk0NTk2IDIzLjU4OTYgNS4wMDc3OSAyMi42OTIzIDUuMDY4NTMgMjEuNTg5NEw1LjIyMjgzIDE4Ljc5NDVDNS4yNDcyIDE4LjM1MiA1LjQzMzg3IDE3LjkzNDEgNS43NDcyNCAxNy42MjA3TDE4LjA5OTggNS4yNjcxNkwxOC4xODY3IDUuMTg5MDNaTTYuMzcwMjkgMTguODU4QzYuMzc5MDkgMTguNjk4MiA2LjQ0NjU3IDE4LjU0NjQgNi41NTk3NCAxOC40MzMyTDE2LjIzODUgOC43NTQ0NkwxOS42NjgxIDEyLjE4NDFMOS45Njc5NCAyMS44ODUzQzkuODYxNzggMjEuOTkxNCA5LjcyMTc3IDIyLjA1NyA5LjU3MjQzIDIyLjA3MThMNi45MzA4MyAyMi4zMzU1QzYuNTMzODkgMjIuMzc1MSA2LjE5NTEgMjIuMDUxMiA2LjIxNjk3IDIxLjY1MjlMNi4zNzAyOSAxOC44NThaTTIwLjQ4MTYgMTEuMzcwN0wxNy4wNTE5IDcuOTQwOTlMMTguOTAzNSA2LjA4OTQyTDIyLjMzMzIgOS41MTkxMUwyMC40ODE2IDExLjM3MDdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTcuMDUxOSA3Ljk0MDk5TDIwLjQ4MTYgMTEuMzcwN0wyMi4zMzMyIDkuNTE5MTFMMTguOTAzNSA2LjA4OTQyTDE3LjA1MTkgNy45NDA5OVoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8cGF0aCBkPSJNNi41NTk3NCAxOC40MzMyQzYuNDQ2NTcgMTguNTQ2NCA2LjM3OTA5IDE4LjY5ODIgNi4zNzAyOSAxOC44NThMNi4yMTY5NyAyMS42NTI5QzYuMTk1MSAyMi4wNTEyIDYuNTMzODkgMjIuMzc1MSA2LjkzMDgzIDIyLjMzNTVMOS41NzI0MyAyMi4wNzE4QzkuNzIxNzcgMjIuMDU3IDkuODYxNzggMjEuOTkxNCA5Ljk2Nzk0IDIxLjg4NTNMMTkuNjY4MSAxMi4xODQxTDE2LjIzODUgOC43NTQ0Nkw2LjU1OTc0IDE4LjQzMzJaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xOC4xODY3IDUuMTg5MDNDMTguNjAzMyA0Ljg0OTM4IDE5LjIwNDcgNC44NDkzMSAxOS42MjEzIDUuMTg5MDNMMTkuNzA3MiA1LjI2NzE2TDIzLjE1NjQgOC43MTU0QzIzLjYwMDEgOS4xNTkxNSAyMy41OTk5IDkuODc4OTYgMjMuMTU2NCAxMC4zMjI4TDEwLjc4MTQgMjIuNjk3OEMxMC40ODc0IDIyLjk5MTggMTAuMTAwNCAyMy4xNzUxIDkuNjg2NjkgMjMuMjE2NEw3LjA0NTA5IDIzLjQ4QzUuOTQ1OTYgMjMuNTg5NiA1LjAwNzc5IDIyLjY5MjMgNS4wNjg1MyAyMS41ODk0TDUuMjIyODMgMTguNzk0NUM1LjI0NzIgMTguMzUyIDUuNDMzODcgMTcuOTM0MSA1Ljc0NzI0IDE3LjYyMDdMMTguMDk5OCA1LjI2NzE2TDE4LjE4NjcgNS4xODkwM1pNNi4zNzAyOSAxOC44NThDNi4zNzkwOSAxOC42OTgyIDYuNDQ2NTcgMTguNTQ2NCA2LjU1OTc0IDE4LjQzMzJMMTYuMjM4NSA4Ljc1NDQ2TDE5LjY2ODEgMTIuMTg0MUw5Ljk2Nzk0IDIxLjg4NTNDOS44NjE3OCAyMS45OTE0IDkuNzIxNzcgMjIuMDU3IDkuNTcyNDMgMjIuMDcxOEw2LjkzMDgzIDIyLjMzNTVDNi41MzM4OSAyMi4zNzUxIDYuMTk1MSAyMi4wNTEyIDYuMjE2OTcgMjEuNjUyOUw2LjM3MDI5IDE4Ljg1OFpNMjAuNDgxNiAxMS4zNzA3TDE3LjA1MTkgNy45NDA5OUwxOC45MDM1IDYuMDg5NDJMMjIuMzMzMiA5LjUxOTExTDIwLjQ4MTYgMTEuMzcwN1oiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8cGF0aCBkPSJNMTguMTg2NyA1LjE4OTAzQzE4LjYwMzMgNC44NDkzOCAxOS4yMDQ3IDQuODQ5MzEgMTkuNjIxMyA1LjE4OTAzTDE5LjcwNzIgNS4yNjcxNkwyMy4xNTY0IDguNzE1NEMyMy42MDAxIDkuMTU5MTUgMjMuNTk5OSA5Ljg3ODk2IDIzLjE1NjQgMTAuMzIyOEwxMC43ODE0IDIyLjY5NzhDMTAuNDg3NCAyMi45OTE4IDEwLjEwMDQgMjMuMTc1MSA5LjY4NjY5IDIzLjIxNjRMNy4wNDUwOSAyMy40OEM1Ljk0NTk2IDIzLjU4OTYgNS4wMDc3OSAyMi42OTIzIDUuMDY4NTMgMjEuNTg5NEw1LjIyMjgzIDE4Ljc5NDVDNS4yNDcyIDE4LjM1MiA1LjQzMzg3IDE3LjkzNDEgNS43NDcyNCAxNy42MjA3TDE4LjA5OTggNS4yNjcxNkwxOC4xODY3IDUuMTg5MDNaTTYuNTU5NzQgMTguNDMzMkM2LjQ0NjU3IDE4LjU0NjQgNi4zNzkwOSAxOC42OTgyIDYuMzcwMjkgMTguODU4TDYuMjE2OTcgMjEuNjUyOUM2LjE5NTEgMjIuMDUxMiA2LjUzMzg5IDIyLjM3NTEgNi45MzA4MyAyMi4zMzU1TDkuNTcyNDMgMjIuMDcxOEM5LjcyMTc3IDIyLjA1NyA5Ljg2MTc4IDIxLjk5MTQgOS45Njc5NCAyMS44ODUzTDE5LjY2ODEgMTIuMTg0MUwxNi4yMzg1IDguNzU0NDZMNi41NTk3NCAxOC40MzMyWk0xNy4wNTE5IDcuOTQwOTlMMjAuNDgxNiAxMS4zNzA3TDIyLjMzMzIgOS41MTkxMUwxOC45MDM1IDYuMDg5NDJMMTcuMDUxOSA3Ljk0MDk5WiIgZmlsbD0iIzJGMzY0MCIvPgo8L2c+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2RfNDBfOTkiIHg9Ii0yIiB5PSIwIiB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQ29sb3JNYXRyaXggaW49IlNvdXJjZUFscGhhIiB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMTI3IDAiIHJlc3VsdD0iaGFyZEFscGhhIi8+CjxmZU9mZnNldCBkeT0iMiIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxIi8+CjxmZUNvbG9yTWF0cml4IHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwLjMgMCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9ImVmZmVjdDFfZHJvcFNoYWRvd180MF85OSIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9ImVmZmVjdDFfZHJvcFNoYWRvd180MF85OSIgcmVzdWx0PSJzaGFwZSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8L3N2Zz4K";
4
+ export declare const pen = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjBfZF8yMDg4MF8xNDA3MTIpIj4KPHBhdGggZD0iTTkuNTg0MTcgMTguNzAyM0w3LjQwNjI1IDkuNDQ4MUw4LjQ5NTM0IDguMzU5MzhIOS41ODQxN0wxMy4zOTQ2IDkuNDQ4MUwxNy4yMDQ5IDEwLjUzNjhMMTguMjkzNiAxMy4yNTg2TDE5LjkyNjggMTUuNDM2MUwyMS41NTk3IDE3LjA2OTJMMjIuNjQ4NCAxOC4xNTc5TDE3LjIwNSAyMy42MDE1TDE1LjAyNzUgMjEuNDI0MVYyMC4zMzUzTDkuNTg0MTcgMTguNzAyM1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0yNC4yNDkzIDE1LjYwNjRDMjUuMzQ2NSAxNi43MDQxIDI1LjM0NjcgMTguNDgzNSAyNC4yNDkzIDE5LjU4MTFMMTkuNTg3MSAyNC4yNDMyQzE4LjQ4OTUgMjUuMzQwOCAxNi43MDkzIDI1LjM0MDcgMTUuNjExNiAyNC4yNDMyTDE0LjE1MTYgMjIuNzgzMkMxMy43NTM0IDIyLjM4NSAxMy41NDYgMjEuODY5MiAxMy41MjQ2IDIxLjM0NzdMMTAuMjk5MSAyMC4yNzI1QzkuMDAxMjYgMTkuODM5NyA4LjAwMTkyIDE4Ljc5MSA3LjYzMzA1IDE3LjQ3MzZMNS4xNTc0NiA4LjYzMjgxTDQuOTIxMTMgNy43ODgwOUw3Ljc5MTI1IDQuOTE3OTdMOC42MzU5OCA1LjE1NDNMMTcuNDc2OCA3LjYyOTg4QzE4Ljc5NDMgNy45OTg3OCAxOS44NDM5IDguOTk3OTQgMjAuMjc2NiAxMC4yOTU5TDIxLjM1MDggMTMuNTE4NkMyMS44NzMyIDEzLjUzOTMgMjIuMzg5NCAxMy43NDY4IDIyLjc4ODMgMTQuMTQ1NUwyNC4yNDkzIDE1LjYwNjRaTTE3LjQyOTkgMTEuMjQ0MUMxNy4zMTIxIDEwLjg5MTEgMTcuMDI2NiAxMC42MTg5IDE2LjY2ODIgMTAuNTE4NkwxMC45NDE2IDguOTE1MDRMMTMuNDQxNiAxMS40MTZDMTMuNzcwOCAxMS40Nzg0IDE0LjA4NTMgMTEuNjM2OCAxNC4zNDAxIDExLjg5MTZDMTUuMDE0OCAxMi41NjY0IDE1LjAxNDggMTMuNjYwMiAxNC4zNDAxIDE0LjMzNUMxMy42NjUzIDE1LjAwOTYgMTIuNTcxNSAxNS4wMDk3IDExLjg5NjcgMTQuMzM1QzExLjY0MjMgMTQuMDgwNSAxMS40ODQ3IDEzLjc2NjIgMTEuNDIyMSAxMy40Mzc1TDguOTE4MiAxMC45MzM2TDEwLjUyMTcgMTYuNjY1QzEwLjYyMjEgMTcuMDIzNCAxMC44OTQzIDE3LjMwOSAxMS4yNDczIDE3LjQyNjhMMTUuMTU2NSAxOC43Mjk1TDE4LjczMjcgMTUuMTUzM0wxNy40Mjk5IDExLjI0NDFaTTIxLjI2NDkgMTYuODY0M0wxNi44NzA0IDIxLjI1ODhMMTcuNTk4OSAyMS45ODgzTDIxLjk5NDQgMTcuNTkzN0wyMS4yNjQ5IDE2Ljg2NDNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjMuNTQwMSAxNi4zMTY0QzI0LjI0NyAxNy4wMjM1IDI0LjI0NyAxOC4xNjk4IDIzLjU0MDEgMTguODc3TDE4Ljg3OCAyMy41MzkxQzE4LjE3MDkgMjQuMjQ2MiAxNy4wMjQ2IDI0LjI0NjEgMTYuMzE3NSAyMy41MzkxTDE0Ljg1NjUgMjIuMDc4MUMxNC40Nzc3IDIxLjY5ODkgMTQuNDE4NyAyMS4xMjI5IDE0LjY3NjggMjAuNjgwN0wxMC42MTM0IDE5LjMyNzFDOS42MzAzNyAxOC45OTk0IDguODczMiAxOC4yMDQ4IDguNTkzODIgMTcuMjA3TDYuMTE5MjEgOC4zNjUyM0w2LjA0MTA5IDguMDgzOThMOC4wODMwOCA2LjA0MTAxTDguMzY0MzMgNi4xMjEwOUwxNy4yMDYxIDguNTk1N0MxOC4yMDM4IDguODc1MTIgMTguOTk4NSA5LjYzMTQ1IDE5LjMyNjIgMTAuNjE0M0wyMC42ODA3IDE0LjY3NThDMjEuMTIzMyAxNC40MTY5IDIxLjcwMDYgMTQuNDc2IDIyLjA4MDEgMTQuODU1NUwyMy41NDAxIDE2LjMxNjRaTTE4LjM3NyAxMC45MzA3QzE4LjE1NDIgMTAuMjYyNyAxNy42MTM3IDkuNzQ4NDUgMTYuOTM1NiA5LjU1ODU5TDguMzc3MDIgNy4xNjIxMUw4LjEyMzEyIDcuNDE2MDFMMTIuMzAwOSAxMS41OTM3QzEyLjk1NDkgMTEuMjQyOSAxMy43ODcxIDExLjM0MjYgMTQuMzM4OSAxMS44OTQ1QzE1LjAxMzMgMTIuNTY5MyAxNS4wMTM1IDEzLjY2MzIgMTQuMzM4OSAxNC4zMzc5QzEzLjY2NDIgMTUuMDEyNyAxMi41Njk0IDE1LjAxMjcgMTEuODk0NiAxNC4zMzc5QzExLjM0MzEgMTMuNzg2MiAxMS4yNDM1IDEyLjk1NDYgMTEuNTkzOCAxMi4zMDA4TDcuNDE2MDkgOC4xMjMwNUw3LjE2MTIgOC4zNzc5M0w5LjU1NzY5IDE2LjkzNzVDOS43NDc2MiAxNy42MTU1IDEwLjI2MTggMTguMTU1MiAxMC45Mjk4IDE4LjM3NzlMMTUuNDI0OSAxOS44NzZMMTkuODc1MSAxNS40MjY4TDE4LjM3NyAxMC45MzA3Wk0yMi44MzMxIDE4LjE2OTlDMjMuMTQ5NSAxNy44NTMzIDIzLjE0OTUgMTcuMzQgMjIuODMzMSAxNy4wMjM0TDIxLjM3MzEgMTUuNTYyNUMyMS4zMTI1IDE1LjUwMTkgMjEuMjE0MSAxNS41MDIxIDIxLjE1MzQgMTUuNTYyNUwxNS41NjQ1IDIxLjE1MjNDMTUuNTAzOCAyMS4yMTMgMTUuNTAzOCAyMS4zMTA0IDE1LjU2NDUgMjEuMzcxMUwxNy4wMjQ1IDIyLjgzMkMxNy4zNDExIDIzLjE0ODUgMTcuODU0NCAyMy4xNDg2IDE4LjE3MSAyMi44MzJMMjIuODMzMSAxOC4xNjk5WiIgZmlsbD0iIzBFMTAxNCIvPgo8L2c+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2RfMjA4ODBfMTQwNzEyIiB4PSIyLjkyMTg4IiB5PSI0LjkxNzk3IiB3aWR0aD0iMjQuMTUwNCIgaGVpZ2h0PSIyNC4xNDg0IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHk9IjIiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMSIvPgo8ZmVDb2xvck1hdHJpeCB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4zIDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJlZmZlY3QxX2Ryb3BTaGFkb3dfMjA4ODBfMTQwNzEyIi8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iZWZmZWN0MV9kcm9wU2hhZG93XzIwODgwXzE0MDcxMiIgcmVzdWx0PSJzaGFwZSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8L3N2Zz4K";
5
+ export declare const mark = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAZCAYAAADaILXQAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAL/SURBVHgBtVVfSFNhFD9rd5uLNYduobRigxGsBTInyCDq7qmCyFEIvTkiiJ7S3oQijSD6hyMoyIf0RfRFttceaqKkT2MEPmjgRoTSWDg3tKXOTufc7U5j7t5p9IPD/f7+zu8753zfBdgDRBTJImRZLCFb7ovwLyCCIVTGEBwGMvFaAfHZR0TvS0Trg9KX+zx+GAea8pFjuV8AwXcA89+rF51tAYjeBGhskLoBjUYzBXXgCNldbryd25+YwePDc5VuL9QJJhe5MZGonjxp2W2P785fgDohkEkU39b+nnh8GeC2vzT+KQXwPFaZskCdYHKmtbBK2UGjvkjEAvT19YHFYoGenh6I33PIe3iVhgzVyDksU9y44ZWHfsNaLg+5nztSb2BgAJxOJwQCAYhGo5JyKoIkWUiNXL44UrmJr6kE7xexuXcZ37xfxlgshmWFFXM4HDg6OiqXZqrsRKPkICw7ePphB9sepfHKk8/SblEUqxwc2InsgJHP5zEej2Mmk8FwOLwveS0nhULBqRSiyNbWVnZpaQkXFhYwm80iJVXRgewkkUhgsVh8BaVc1oTWZDLZ/H7/RXK0TklVJGbnwWAQU6kUrq6uDrtcLoNSiMButxv1er17dnZ2jNXXIh0ZGZFOx1hZWZmn8r1ks9lMoJRkKN2Bls7Ozq7Nzc2NUChUFQZWmsvlfkxOTo653e47NN5Fgs7Q96gaOU8eI/POzMyMM9FeclZMic94PJ5bWq32Ko0FdDpdG4eTKkwANfh8Ph19TrW3t1/bq55VMwYHBx9S/5zBYHAR6XEOR3mPRpWc9musViur901PT0+weo4zO+FEC4Jw3mg0niBnDd3d3VpeDweEjggq6iORiBRrugMJUnya5htqKdXWQY5msxmTyaS2tbV1g96YZlL9tb+//8Xi4uKX7e3tdeAH6bDgBPHxKQwiJe86J5CS521qajKDyoVRl06x5Lon2KnUPBwOrgqqFL1SnOtOAJN0dHQI6XSaDiBwxRTp1dyh/6nqu/5f8Acp9xcUCT5+eAAAAABJRU5ErkJggg==";
6
+ export declare const arrow: (angle: number) => string;
@@ -0,0 +1,72 @@
1
+ export interface CanvasRef {
2
+ pan: (deltaX: number, deltaY: number) => void;
3
+ scale: (scale: number, x: number, y: number) => void;
4
+ centerObjects: (ids: string[], duration?: number) => void;
5
+ fitToScreen: (screen?: {
6
+ x: number;
7
+ y: number;
8
+ width: number;
9
+ height: number;
10
+ }) => Promise<void>;
11
+ worldToCanvas: (x: number, y: number) => {
12
+ x: number;
13
+ y: number;
14
+ };
15
+ getScale: () => number;
16
+ getActiveObjects: () => any;
17
+ getBounds: () => {
18
+ left: number;
19
+ top: number;
20
+ width: number;
21
+ height: number;
22
+ } | null;
23
+ setObjectProperties: (id: string, properties: any) => Promise<void>;
24
+ registerFonts: (fonts: {
25
+ fontName: string;
26
+ url: string;
27
+ }[]) => Promise<void>;
28
+ switchToCreatingElement: (creating: boolean, type?: string, options?: any) => Promise<void>;
29
+ add: (type: string, properties: any) => Promise<string>;
30
+ copy: () => Promise<void>;
31
+ paste: (x: number, y: number, clipboardEvent?: ClipboardEvent) => Promise<{
32
+ count: number;
33
+ message?: string;
34
+ }>;
35
+ cut: () => Promise<void>;
36
+ remove: (id?: string) => void;
37
+ select: (ids: string[]) => void;
38
+ canUndo: () => boolean;
39
+ canRedo: () => boolean;
40
+ undo: () => void;
41
+ redo: () => void;
42
+ getParentLayer: (id: string) => string;
43
+ getIndex: (id: string) => number;
44
+ moveUp: (id: string) => void;
45
+ moveDown: (id: string) => void;
46
+ moveTo: (parentId: string, index: number) => void;
47
+ bringToFront: (id: string) => void;
48
+ sendToBack: (id: string) => void;
49
+ canGroup: (ids: string[]) => boolean;
50
+ group: (ids: string[]) => string;
51
+ ungroup: (id: string) => void;
52
+ align: (alignment: string) => void;
53
+ arrange: (arrangement: string) => void;
54
+ switchToPan: (isPan: boolean) => void;
55
+ loadFromJSON: (json: any) => Promise<void>;
56
+ addFabricJSON: (fabricJSON: any, x?: number, y?: number) => Promise<string>;
57
+ exportToJSON: () => any;
58
+ exportImage: (type?: string, multiple?: number, quality?: number) => Promise<string | string[] | any>;
59
+ refreshOverlay?: () => void;
60
+ }
61
+ export interface CanvasProps {
62
+ onAction?: (action: string, data?: any) => void;
63
+ onLoad?: () => void;
64
+ uploadAction?: string;
65
+ uploadHeader?: Record<string, string>;
66
+ /**
67
+ * 覆盖在画布上的 DOM 插槽。
68
+ * 插槽中的元素会被放在一个跟随画布一起变换的 overlay 容器中。
69
+ */
70
+ renderOverlay?: () => any;
71
+ [key: string]: any;
72
+ }
@@ -0,0 +1,31 @@
1
+ export declare const INTERNAL_CLIPBOARD_ATTR = "data-infinite-canvas-selection";
2
+ export declare const INTERNAL_SESSION_ATTR = "data-infinite-canvas-session";
3
+ export interface SerializedClipboardPayload {
4
+ kind: SelectionClipboardContent["kind"];
5
+ types: string[];
6
+ serialized: string;
7
+ src?: string;
8
+ }
9
+ export interface SerializedClipboardData {
10
+ session: string;
11
+ payload: SerializedClipboardPayload;
12
+ }
13
+ export type SelectionClipboardContent = {
14
+ kind: "empty";
15
+ types: string[];
16
+ serialized: string;
17
+ } | {
18
+ kind: "singleImage";
19
+ data: Uint8Array;
20
+ src: string;
21
+ types: string[];
22
+ serialized: string;
23
+ } | {
24
+ kind: "types";
25
+ types: string[];
26
+ serialized: string;
27
+ };
28
+ export declare const getCurrentClipboardSessionId: () => string;
29
+ export declare const isSameClipboardSession: (session?: string | null) => boolean;
30
+ export declare const decodeBase64: (value: string) => string;
31
+ export declare const writeSelectionToClipboard: (canvas: any) => Promise<void>;
@@ -0,0 +1,3 @@
1
+ export * from "./core";
2
+ export * from "./read";
3
+ export * from "./transform";
@@ -0,0 +1,17 @@
1
+ import { SerializedClipboardData } from "./core";
2
+ export declare const extractInternalClipboardPayload: (html: string) => SerializedClipboardData | null;
3
+ export declare const extractTextFromHtml: (html: string) => string;
4
+ export interface ClipboardImagePayload {
5
+ blob: Blob;
6
+ type: string;
7
+ width: number;
8
+ height: number;
9
+ }
10
+ export declare const containsInternalPayloadInDataTransfer: (dataTransfer: DataTransfer) => boolean;
11
+ export declare const extractSerializedClipboardPayload: (dataTransfer: DataTransfer) => SerializedClipboardData | null;
12
+ export declare const extractTextFromDataTransfer: (dataTransfer: DataTransfer) => string | null;
13
+ export declare const extractUnsupportedFiles: (dataTransfer: DataTransfer) => {
14
+ types: string[];
15
+ names: string[];
16
+ } | null;
17
+ export declare const extractImageFromDataTransfer: (dataTransfer: DataTransfer) => Promise<ClipboardImagePayload[]>;
@@ -0,0 +1,10 @@
1
+ export interface ClipboardElementDescriptor {
2
+ type: string;
3
+ properties: Record<string, any>;
4
+ }
5
+ export declare const parseSerializedClipboardObjects: (serialized: string) => any[];
6
+ export declare const offsetClipboardElements: (objects: any[], targetX: number, targetY: number) => ClipboardElementDescriptor[];
7
+ export declare const collectImageSources: (elements: ClipboardElementDescriptor[]) => string[];
8
+ export declare const registerClipboardImages: (sources: string[], registerImage: (src: string) => Promise<void>) => Promise<void>;
9
+ export declare const buildElementsFromSerialized: (serialized: string, targetX: number, targetY: number) => ClipboardElementDescriptor[];
10
+ export declare const registerImagesForElements: (elements: ClipboardElementDescriptor[], registerImage: (src: string) => Promise<void>) => Promise<void>;
@@ -0,0 +1 @@
1
+ export * from "./clipboard";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Fabric.js JSON 转换工具
3
+ * 将 Fabric.js 的 JSON 格式转换为项目需要的数据结构
4
+ */
5
+ export interface FabricObject {
6
+ type: string;
7
+ version?: string;
8
+ objects?: FabricObject[];
9
+ [key: string]: any;
10
+ }
11
+ export interface ConvertedObject {
12
+ type: string;
13
+ id?: string;
14
+ [key: string]: any;
15
+ }
16
+ /**
17
+ * 转换整个 Fabric.js JSON 数据
18
+ * @param fabricJSON - Fabric.js 格式的 JSON 数据
19
+ * @param offsetX - X 坐标偏移量(可选,用于调整 frame 位置)
20
+ * @param offsetY - Y 坐标偏移量(可选,用于调整 frame 位置)
21
+ * @returns 转换后的项目格式数据
22
+ */
23
+ export declare function convertFabricJSON(fabricJSON: any, offsetX?: number, offsetY?: number): any;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 字体加载工具模块
3
+ */
4
+ export interface FontData {
5
+ name: string;
6
+ buffer: ArrayBuffer;
7
+ array: Uint8Array;
8
+ }
9
+ /**
10
+ * 检测字体格式类型
11
+ * @param buffer ArrayBuffer 或 Uint8Array
12
+ * @returns 字体格式类型
13
+ */
14
+ export declare function detectFontFormat(buffer: ArrayBuffer | Uint8Array): 'woff2' | 'woff' | 'otf' | 'ttf' | 'unknown';
15
+ /**
16
+ * 检测字体格式是否为 WOFF2(保持向后兼容)
17
+ */
18
+ export declare function isWOFF2(buffer: ArrayBuffer | Uint8Array): boolean;
19
+ /**
20
+ * 将 WOFF2 解码为 TTF
21
+ * 使用 wawoff2 解码 WOFF2 格式
22
+ */
23
+ export declare function decompressWOFF2(buffer: ArrayBuffer): Promise<ArrayBuffer>;
24
+ /**
25
+ * 获取默认字体数据(仅 SourceHan,emoji 依赖系统字体,不发起网络请求)
26
+ */
27
+ export declare const getFontBuffers: () => Promise<{
28
+ sourceHan: FontData;
29
+ }>;
30
+ /**
31
+ * 注册单个字体到浏览器
32
+ * @param fontData 字体数据
33
+ * @returns 是否成功注册
34
+ */
35
+ export declare const registerFontToBrowser: (fontData: {
36
+ name: string;
37
+ buffer: ArrayBuffer | Uint8Array;
38
+ }) => Promise<boolean>;
39
+ /**
40
+ * 将默认字体注册到浏览器(document.fonts),供 textarea 等使用。
41
+ */
42
+ export declare const registerDefaultFonts: (fontData: {
43
+ sourceHan: FontData;
44
+ }) => Promise<void>;
45
+ /**
46
+ * 完整的字体初始化流程
47
+ */
48
+ export declare const initializeFonts: () => Promise<{
49
+ sourceHan: FontData;
50
+ }>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * HTML to EditorJSON Converter - Element Converters
3
+ * 包含各种元素的转换函数
4
+ */
5
+ import type { Layer, TextLayer, ImageLayer, RectangleLayer, CircleLayer, ElementContext } from "./types";
6
+ /**
7
+ * 处理 body 元素的背景(作为最底层)
8
+ * @param bodyElement - body 元素
9
+ * @param containerWidth - 容器宽度
10
+ * @param tempHeight - 临时高度(稍后会根据实际内容更新)
11
+ * @returns 背景图层数组(可能为空)
12
+ */
13
+ export declare function convertBodyBackground(bodyElement: HTMLElement, containerWidth: number, tempHeight: number): Promise<Layer[]>;
14
+ /**
15
+ * 转换文本元素
16
+ */
17
+ export declare function convertTextElement(element: Element, context: ElementContext): Promise<TextLayer | ImageLayer | null>;
18
+ /**
19
+ * 转换图片元素
20
+ */
21
+ export declare function convertImageElement(element: HTMLImageElement, context: ElementContext): ImageLayer | null;
22
+ /**
23
+ * 转换 Canvas 元素
24
+ * 将 <canvas> 导出为 2 倍分辨率 PNG,ImageLayer 的 scale 设为 0.5,以提升清晰度
25
+ */
26
+ export declare function convertCanvasElement(element: HTMLCanvasElement, context: ElementContext): ImageLayer | null;
27
+ /**
28
+ * 转换 SVG 元素
29
+ * 将 SVG 通过 encodeURIComponent 转换为 data URL 图片
30
+ */
31
+ export declare function convertSVGElement(element: SVGElement, context: ElementContext): Promise<ImageLayer | null>;
32
+ /**
33
+ * 转换 ::before 和 ::after 伪元素(统一渲染为图片)
34
+ */
35
+ export declare function convertPseudoElements(element: Element, context: ElementContext): Promise<Layer[]>;
36
+ /**
37
+ * 转换背景元素
38
+ */
39
+ export declare function convertBackgroundElement(element: Element, context: ElementContext): Promise<RectangleLayer | CircleLayer | ImageLayer | null>;
40
+ /**
41
+ * 转换单边边框
42
+ */
43
+ export declare function convertSingleBorders(element: Element, context: ElementContext): RectangleLayer[];
44
+ /**
45
+ * 递归遍历 DOM 树并转换元素
46
+ */
47
+ export declare function traverseAndConvert(element: Element, context: ElementContext, layers: Layer[]): Promise<void>;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * HTML to EditorJSON Converter - Element Helper Functions
3
+ * 包含元素相关的辅助函数(旋转、透明度、圆角、浮动等)
4
+ */
5
+ /**
6
+ * 获取元素所在容器的 padding(向上遍历父元素,找到第一个有 padding 的容器)
7
+ * @param element 元素
8
+ * @param containerRect 容器边界框
9
+ * @returns { paddingLeft: 容器左padding, paddingRight: 容器右padding }
10
+ */
11
+ export declare function getContainerPadding(element: Element, containerRect: DOMRect): {
12
+ paddingLeft: number;
13
+ paddingRight: number;
14
+ };
15
+ /**
16
+ * 通过创建临时元素来获取伪元素的准确位置
17
+ */
18
+ export declare function getPseudoElementRect(element: Element, pseudoStyles: CSSStyleDeclaration, pseudoType?: "::before" | "::after"): DOMRect | null;
19
+ /**
20
+ * 获取图片元素的圆角值(考虑父元素的 overflow 和 border-radius)
21
+ * @param element 图片元素
22
+ * @param styles 图片元素的样式
23
+ * @param cssVariables CSS 变量映射
24
+ * @returns 圆角半径(像素值)
25
+ */
26
+ export declare function getImageBorderRadius(element: HTMLElement, styles: CSSStyleDeclaration | null, cssVariables: Map<string, string>): number;
27
+ /**
28
+ * 计算浮动元素占用的空间(用于调整文本位置和宽度)
29
+ * @param element 当前文本元素
30
+ * @param containerRect 容器边界框
31
+ * @returns { leftOffset: 左浮动偏移, rightOffset: 右浮动占用的宽度 }
32
+ */
33
+ export declare function calculateFloatOffsets(element: Element, containerRect: DOMRect): {
34
+ leftOffset: number;
35
+ rightOffset: number;
36
+ };
37
+ /**
38
+ * 获取元素的旋转角度(考虑父元素链的 transform: rotate 累积)
39
+ * @param element 元素
40
+ * @param styles 元素的样式
41
+ * @returns 旋转角度(度数),累积所有父元素的旋转
42
+ */
43
+ export declare function getElementRotation(element: Element, styles: CSSStyleDeclaration | null): number | undefined;
44
+ /**
45
+ * 获取元素的透明度(考虑父元素链的透明度累积)
46
+ * @param element 元素
47
+ * @param styles 元素的样式
48
+ * @returns 透明度值(0-1)
49
+ */
50
+ export declare function getElementOpacity(element: Element, styles: CSSStyleDeclaration | null): number;
51
+ /**
52
+ * 按照 CSS 堆叠上下文规则排序子元素
53
+ * @param children 要排序的子元素数组
54
+ * @returns 排序后的子元素数组
55
+ */
56
+ export declare function sortChildrenByStackingOrder(children: Element[]): Element[];
57
+ /**
58
+ * 判断元素是否需要处理为背景层
59
+ */
60
+ export declare function shouldConvertAsBackground(element: Element, styles: CSSStyleDeclaration | null, cssVariables: Map<string, string>): boolean;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * HTML to EditorJSON Converter - Main Entry Point
3
+ */
4
+ export type { ColorStop, LinearGradient, Shadow, CommonLayerFields, TextLayer, ImageLayer, RectangleLayer, CircleLayer, FrameLayer, GroupLayer, Layer, EditorJSON, ElementContext, } from "./types";
5
+ export { uuid, extractTitle, extractCSSVariables, resolveVariable, getTextContent, waitForImage, waitForAllImages, } from "./utils";
6
+ export { parseColor, parseGradient, parseShadow, parseFontSize, parseLength, parseTransformAngle, parseFontWeight, parseBorderRadius, parseLineHeight, } from "./parsers";
7
+ export { isComplexBackground, renderElementWithFilterToBase64, renderBackgroundToBase64, renderEmojiToBase64, isEmojiText, } from "./renderers";
8
+ import type { FrameLayer } from "./types";
9
+ /**
10
+ * 将 HTML 字符串转换为 FrameLayer(仅支持浏览器环境)
11
+ * 在隐藏 iframe 中加载并执行 HTML(含脚本与动态样式),再解析为 JSON。
12
+ * @param html - HTML 字符串
13
+ * @returns FrameLayer 对象
14
+ */
15
+ export declare function html2json(html: string): Promise<FrameLayer>;
16
+ export default html2json;