@orangecatai/adgen-canvas 0.0.39 → 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.
Files changed (95) hide show
  1. package/dist/dev/chunk-2K6ZAAHB.js +1535 -0
  2. package/dist/dev/chunk-2K6ZAAHB.js.map +7 -0
  3. package/dist/dev/{chunk-E7VZGEUJ.js → chunk-2Q5Z4UTF.js} +2 -2
  4. package/dist/dev/{chunk-E7VZGEUJ.js.map → chunk-2Q5Z4UTF.js.map} +1 -1
  5. package/dist/dev/{chunk-LIELFD5T.js → chunk-3WIRZ6S7.js} +6 -1
  6. package/dist/dev/chunk-3WIRZ6S7.js.map +7 -0
  7. package/dist/dev/{chunk-5XP2WJAQ.js → chunk-7XZBXIDZ.js} +1300 -1252
  8. package/dist/dev/chunk-7XZBXIDZ.js.map +7 -0
  9. package/dist/dev/chunk-AKA4GZ3R.js +62 -0
  10. package/dist/dev/chunk-AKA4GZ3R.js.map +7 -0
  11. package/dist/dev/chunk-LWUV2KR2.js +27 -0
  12. package/dist/dev/chunk-LWUV2KR2.js.map +7 -0
  13. package/dist/dev/chunk-T57LHRZV.js +2167 -0
  14. package/dist/dev/chunk-T57LHRZV.js.map +7 -0
  15. package/dist/dev/components/auto-resize/nativeResizeAgent-5XWJJ74W.js +1074 -0
  16. package/dist/dev/components/auto-resize/nativeResizeAgent-5XWJJ74W.js.map +7 -0
  17. package/dist/dev/data/{image-PUPXCX7M.js → image-MTDE3WXB.js} +4 -3
  18. package/dist/dev/index.css +618 -27
  19. package/dist/dev/index.css.map +3 -3
  20. package/dist/dev/index.js +6769 -8217
  21. package/dist/dev/index.js.map +4 -4
  22. package/dist/dev/locales/{en-VCZQBJ2N.js → en-3S2H3QGO.js} +2 -2
  23. package/dist/dev/model-capabilities.js +47 -0
  24. package/dist/dev/model-capabilities.js.map +7 -0
  25. package/dist/dev/subset-shared.chunk.js +1 -1
  26. package/dist/dev/subset-worker.chunk.js +1 -1
  27. package/dist/prod/chunk-6YYSQB5E.js +1 -0
  28. package/dist/prod/{chunk-CLQPYXMS.js → chunk-PIM2DC2L.js} +3 -3
  29. package/dist/prod/chunk-POCDVKZK.js +142 -0
  30. package/dist/prod/chunk-PWBUVPCU.js +1 -0
  31. package/dist/prod/{chunk-WBFDC4WN.js → chunk-R4DNAEVN.js} +1 -1
  32. package/dist/prod/chunk-U2I2OXQ7.js +4 -0
  33. package/dist/prod/chunk-UR7GPHHO.js +1 -0
  34. package/dist/prod/components/auto-resize/nativeResizeAgent-45UNA3LO.js +5 -0
  35. package/dist/prod/data/image-U4RMOYQQ.js +1 -0
  36. package/dist/prod/index.css +1 -1
  37. package/dist/prod/index.js +67 -298
  38. package/dist/prod/locales/{en-ZZURI326.js → en-Z3CKUL4S.js} +1 -1
  39. package/dist/prod/model-capabilities.js +1 -0
  40. package/dist/prod/subset-shared.chunk.js +1 -1
  41. package/dist/prod/subset-worker.chunk.js +1 -1
  42. package/dist/types/common/src/utils.d.ts +4 -1
  43. package/dist/types/element/src/index.d.ts +3 -0
  44. package/dist/types/element/src/newElement.d.ts +2 -1
  45. package/dist/types/element/src/textHtml.d.ts +14 -0
  46. package/dist/types/element/src/textLayout.d.ts +97 -0
  47. package/dist/types/element/src/textStyleRanges.d.ts +62 -0
  48. package/dist/types/element/src/textWrapping.d.ts +27 -0
  49. package/dist/types/element/src/types.d.ts +35 -0
  50. package/dist/types/excalidraw/actions/actionFrame.d.ts +1 -0
  51. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +1 -0
  52. package/dist/types/excalidraw/actions/actionProperties.d.ts +50 -0
  53. package/dist/types/excalidraw/actions/index.d.ts +1 -1
  54. package/dist/types/excalidraw/actions/types.d.ts +1 -1
  55. package/dist/types/excalidraw/components/AIChatPanel.d.ts +18 -2
  56. package/dist/types/excalidraw/components/App.d.ts +6 -0
  57. package/dist/types/excalidraw/components/FontSizeInput.d.ts +19 -0
  58. package/dist/types/excalidraw/components/ImageGeneratorPanel.d.ts +946 -45
  59. package/dist/types/excalidraw/components/VideoGeneratorPanel.d.ts +67 -53
  60. package/dist/types/excalidraw/components/ai-chat/ActivityTimeline.d.ts +18 -0
  61. package/dist/types/excalidraw/components/ai-chat/activitySteps.d.ts +106 -0
  62. package/dist/types/excalidraw/components/ai-chat/agentLoop.d.ts +66 -3
  63. package/dist/types/excalidraw/components/ai-chat/canvasTools.d.ts +23 -8
  64. package/dist/types/excalidraw/components/ai-chat/htmlToExcalidraw.d.ts +3 -0
  65. package/dist/types/excalidraw/components/ai-chat/openRouterStream.d.ts +13 -0
  66. package/dist/types/excalidraw/components/auto-resize/ResizeActivityCard.d.ts +7 -0
  67. package/dist/types/excalidraw/components/auto-resize/autoResizeEngine.d.ts +5 -2
  68. package/dist/types/excalidraw/components/auto-resize/autoResizeStore.d.ts +23 -0
  69. package/dist/types/excalidraw/components/auto-resize/imageBounds.d.ts +11 -0
  70. package/dist/types/excalidraw/components/auto-resize/nativeResizeAgent.d.ts +5 -0
  71. package/dist/types/excalidraw/components/auto-resize/resizeFitting.d.ts +7 -0
  72. package/dist/types/excalidraw/components/auto-resize/resizeLayout.d.ts +33 -0
  73. package/dist/types/excalidraw/components/icons.d.ts +6 -0
  74. package/dist/types/excalidraw/components/template-builder/TemplateBuilderTray.d.ts +1 -0
  75. package/dist/types/excalidraw/index.d.ts +9 -0
  76. package/dist/types/excalidraw/modelCapabilities/index.d.ts +17 -0
  77. package/dist/types/excalidraw/modelCapabilities/registry.image.d.ts +2 -0
  78. package/dist/types/excalidraw/modelCapabilities/registry.video.d.ts +2 -0
  79. package/dist/types/excalidraw/modelCapabilities/shared.d.ts +24 -0
  80. package/dist/types/excalidraw/modelCapabilities/types.d.ts +276 -0
  81. package/dist/types/excalidraw/modelCapabilities/validate.d.ts +48 -0
  82. package/dist/types/excalidraw/types.d.ts +4 -4
  83. package/dist/types/excalidraw/utils/imageApi.d.ts +3 -0
  84. package/dist/types/excalidraw/utils/referenceBudget.d.ts +12 -23
  85. package/dist/types/excalidraw/utils/videoApi.d.ts +21 -1
  86. package/dist/types/excalidraw/wysiwyg/richTextEditable.d.ts +36 -0
  87. package/dist/types/excalidraw/wysiwyg/textSelectionStyles.d.ts +32 -0
  88. package/dist/types/excalidraw/wysiwyg/textWysiwyg.d.ts +6 -2
  89. package/package.json +10 -4
  90. package/dist/dev/chunk-5XP2WJAQ.js.map +0 -7
  91. package/dist/dev/chunk-LIELFD5T.js.map +0 -7
  92. package/dist/prod/chunk-T3ZLBHX4.js +0 -4
  93. package/dist/prod/data/image-AG3CTRSJ.js +0 -1
  94. /package/dist/dev/data/{image-PUPXCX7M.js.map → image-MTDE3WXB.js.map} +0 -0
  95. /package/dist/dev/locales/{en-VCZQBJ2N.js.map → en-3S2H3QGO.js.map} +0 -0
@@ -1,283 +1,92 @@
1
1
  import {
2
2
  define_import_meta_env_default
3
- } from "./chunk-E7VZGEUJ.js";
3
+ } from "./chunk-2Q5Z4UTF.js";
4
4
  import {
5
5
  __publicField
6
6
  } from "./chunk-XDFCUUT6.js";
7
7
 
8
- // data/image.ts
9
- import tEXt from "png-chunk-text";
10
- import encodePng from "png-chunks-encode";
11
- import decodePng from "png-chunks-extract";
12
- import { EXPORT_DATA_TYPES as EXPORT_DATA_TYPES3, MIME_TYPES as MIME_TYPES7 } from "@orangecatai/common";
13
-
14
- // data/blob.ts
15
- import { nanoid } from "nanoid";
8
+ // fonts/Fonts.ts
16
9
  import {
17
- IMAGE_MIME_TYPES,
18
- VIDEO_MIME_TYPES,
19
- MIME_TYPES as MIME_TYPES6,
20
- bytesToHexString,
21
- isPromiseLike
10
+ FONT_FAMILY,
11
+ FONT_FAMILY_FALLBACKS,
12
+ CJK_HAND_DRAWN_FALLBACK_FONT,
13
+ WINDOWS_EMOJI_FALLBACK_FONT,
14
+ getFontFamilyFallbacks,
15
+ FONT_SIZES
22
16
  } from "@orangecatai/common";
23
-
24
- // appState.ts
17
+ import { getContainerElement } from "@orangecatai/element";
18
+ import { charWidth } from "@orangecatai/element";
19
+ import { containsCJK } from "@orangecatai/element";
25
20
  import {
26
- COLOR_PALETTE,
27
- ARROW_TYPE,
28
- DEFAULT_ELEMENT_PROPS,
29
- DEFAULT_FONT_FAMILY,
30
- DEFAULT_FONT_SIZE,
31
- DEFAULT_TEXT_ALIGN,
32
- DEFAULT_GRID_SIZE,
33
- EXPORT_SCALES,
34
- STATS_PANELS,
35
- THEME,
36
- DEFAULT_GRID_STEP
21
+ FONT_METADATA,
22
+ getFontString,
23
+ PromisePool,
24
+ promiseTry as promiseTry3
37
25
  } from "@orangecatai/common";
38
- var defaultExportScale = EXPORT_SCALES.includes(devicePixelRatio) ? devicePixelRatio : 1;
39
- var getDefaultAppState = () => {
40
- return {
41
- showWelcomeScreen: false,
42
- theme: THEME.LIGHT,
43
- collaborators: /* @__PURE__ */ new Map(),
44
- currentChartType: "bar",
45
- currentItemBackgroundColor: COLOR_PALETTE.blue[1],
46
- currentItemEndArrowhead: "arrow",
47
- currentItemFillStyle: DEFAULT_ELEMENT_PROPS.fillStyle,
48
- currentItemFontFamily: DEFAULT_FONT_FAMILY,
49
- currentItemFontSize: DEFAULT_FONT_SIZE,
50
- currentItemOpacity: DEFAULT_ELEMENT_PROPS.opacity,
51
- currentItemRoughness: DEFAULT_ELEMENT_PROPS.roughness,
52
- currentItemStartArrowhead: null,
53
- currentItemStrokeColor: DEFAULT_ELEMENT_PROPS.strokeColor,
54
- currentItemRoundness: "sharp",
55
- currentItemArrowType: ARROW_TYPE.round,
56
- currentItemStrokeStyle: DEFAULT_ELEMENT_PROPS.strokeStyle,
57
- currentItemStrokeWidth: DEFAULT_ELEMENT_PROPS.strokeWidth,
58
- currentItemTextAlign: DEFAULT_TEXT_ALIGN,
59
- currentHoveredFontFamily: null,
60
- cursorButton: "up",
61
- activeEmbeddable: null,
62
- newElement: null,
63
- editingTextElement: null,
64
- editingGroupId: null,
65
- activeTool: {
66
- type: "selection",
67
- customType: null,
68
- locked: DEFAULT_ELEMENT_PROPS.locked,
69
- fromSelection: false,
70
- lastActiveTool: null
71
- },
72
- preferredSelectionTool: {
73
- type: "selection",
74
- initialized: false
75
- },
76
- penMode: false,
77
- penDetected: false,
78
- errorMessage: null,
79
- exportBackground: true,
80
- exportScale: defaultExportScale,
81
- exportEmbedScene: false,
82
- exportWithDarkMode: false,
83
- fileHandle: null,
84
- gridSize: DEFAULT_GRID_SIZE,
85
- gridStep: DEFAULT_GRID_STEP,
86
- gridModeEnabled: false,
87
- isBindingEnabled: true,
88
- defaultSidebarDockedPreference: false,
89
- isLoading: false,
90
- isResizing: false,
91
- isRotating: false,
92
- lastPointerDownWith: "mouse",
93
- multiElement: null,
94
- name: null,
95
- contextMenu: null,
96
- openMenu: null,
97
- openPopup: null,
98
- openSidebar: null,
99
- openDialog: null,
100
- pasteDialog: { shown: false, data: null },
101
- previousSelectedElementIds: {},
102
- resizingElement: null,
103
- scrolledOutside: false,
104
- scrollX: 0,
105
- scrollY: 0,
106
- selectedElementIds: {},
107
- hoveredElementIds: {},
108
- selectedGroupIds: {},
109
- selectedElementsAreBeingDragged: false,
110
- selectionElement: null,
111
- shouldCacheIgnoreZoom: false,
112
- stats: {
113
- open: false,
114
- panels: STATS_PANELS.generalStats | STATS_PANELS.elementProperties
115
- },
116
- startBoundElement: null,
117
- suggestedBinding: null,
118
- frameRendering: { enabled: true, clip: true, name: true, outline: true },
119
- frameToHighlight: null,
120
- editingFrame: null,
121
- elementsToHighlight: null,
122
- toast: null,
123
- viewBackgroundColor: COLOR_PALETTE.white,
124
- zenModeEnabled: false,
125
- zoom: {
126
- value: 1
127
- },
128
- viewModeEnabled: false,
129
- showHyperlinkPopup: false,
130
- selectedLinearElement: null,
131
- snapLines: [],
132
- originSnapOffset: {
133
- x: 0,
134
- y: 0
135
- },
136
- objectsSnapModeEnabled: false,
137
- userToFollow: null,
138
- followedBy: /* @__PURE__ */ new Set(),
139
- isCropping: false,
140
- croppingElementId: null,
141
- searchMatches: null,
142
- lockedMultiSelections: {},
143
- activeLockedId: null,
144
- bindMode: "orbit"
145
- };
146
- };
147
- var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
148
- showWelcomeScreen: { browser: true, export: false, server: false },
149
- theme: { browser: true, export: false, server: false },
150
- collaborators: { browser: false, export: false, server: false },
151
- currentChartType: { browser: true, export: false, server: false },
152
- currentItemBackgroundColor: { browser: true, export: false, server: false },
153
- currentItemEndArrowhead: { browser: true, export: false, server: false },
154
- currentItemFillStyle: { browser: true, export: false, server: false },
155
- currentItemFontFamily: { browser: true, export: false, server: false },
156
- currentItemFontSize: { browser: true, export: false, server: false },
157
- currentItemRoundness: {
158
- browser: true,
159
- export: false,
160
- server: false
26
+ import { ShapeCache } from "@orangecatai/element";
27
+ import { isTextElement } from "@orangecatai/element";
28
+
29
+ // fonts/Cascadia/CascadiaCode-Regular.woff2
30
+ var CascadiaCode_Regular_default = "./fonts/Cascadia/CascadiaCode-Regular.woff2";
31
+
32
+ // fonts/Cascadia/index.ts
33
+ var CascadiaFontFaces = [
34
+ {
35
+ uri: CascadiaCode_Regular_default
36
+ }
37
+ ];
38
+
39
+ // fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2
40
+ var ComicShanns_Regular_279a7b317d12eb88de06167bd672b4b4_default = "./fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2";
41
+
42
+ // fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2
43
+ var ComicShanns_Regular_6e066e8de2ac57ea9283adb9c24d7f0c_default = "./fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2";
44
+
45
+ // fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2
46
+ var ComicShanns_Regular_dc6a8806fa96795d7b3be5026f989a17_default = "./fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2";
47
+
48
+ // fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2
49
+ var ComicShanns_Regular_fcb0fc02dcbee4c9846b3e2508668039_default = "./fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2";
50
+
51
+ // fonts/ComicShanns/index.ts
52
+ var ComicShannsFontFaces = [
53
+ {
54
+ uri: ComicShanns_Regular_279a7b317d12eb88de06167bd672b4b4_default,
55
+ descriptors: {
56
+ unicodeRange: "U+20-7e,U+a1-a6,U+a8,U+ab-ac,U+af-b1,U+b4,U+b8,U+bb-bc,U+bf-cf,U+d1-d7,U+d9-de,U+e0-ef,U+f1-f7,U+f9-ff,U+131,U+152-153,U+2c6,U+2da,U+2dc,U+2013-2014,U+2018-201a,U+201c-201d,U+2020-2022,U+2026,U+2039-203a,U+2044,U+20ac,U+2191,U+2193,U+2212"
57
+ }
161
58
  },
162
- currentItemArrowType: {
163
- browser: true,
164
- export: false,
165
- server: false
59
+ {
60
+ uri: ComicShanns_Regular_fcb0fc02dcbee4c9846b3e2508668039_default,
61
+ descriptors: {
62
+ unicodeRange: "U+100-10f,U+112-125,U+128-130,U+134-137,U+139-13c,U+141-148,U+14c-151,U+154-161,U+164-165,U+168-17f,U+1bf,U+1f7,U+218-21b,U+237,U+1e80-1e85,U+1ef2-1ef3,U+a75b"
63
+ }
166
64
  },
167
- currentItemOpacity: { browser: true, export: false, server: false },
168
- currentItemRoughness: { browser: true, export: false, server: false },
169
- currentItemStartArrowhead: { browser: true, export: false, server: false },
170
- currentItemStrokeColor: { browser: true, export: false, server: false },
171
- currentItemStrokeStyle: { browser: true, export: false, server: false },
172
- currentItemStrokeWidth: { browser: true, export: false, server: false },
173
- currentItemTextAlign: { browser: true, export: false, server: false },
174
- currentHoveredFontFamily: { browser: false, export: false, server: false },
175
- cursorButton: { browser: true, export: false, server: false },
176
- activeEmbeddable: { browser: false, export: false, server: false },
177
- newElement: { browser: false, export: false, server: false },
178
- editingTextElement: { browser: false, export: false, server: false },
179
- editingGroupId: { browser: true, export: false, server: false },
180
- activeTool: { browser: true, export: false, server: false },
181
- preferredSelectionTool: { browser: true, export: false, server: false },
182
- penMode: { browser: true, export: false, server: false },
183
- penDetected: { browser: true, export: false, server: false },
184
- errorMessage: { browser: false, export: false, server: false },
185
- exportBackground: { browser: true, export: false, server: false },
186
- exportEmbedScene: { browser: true, export: false, server: false },
187
- exportScale: { browser: true, export: false, server: false },
188
- exportWithDarkMode: { browser: true, export: false, server: false },
189
- fileHandle: { browser: false, export: false, server: false },
190
- gridSize: { browser: true, export: true, server: true },
191
- gridStep: { browser: true, export: true, server: true },
192
- gridModeEnabled: { browser: true, export: true, server: true },
193
- height: { browser: false, export: false, server: false },
194
- isBindingEnabled: { browser: false, export: false, server: false },
195
- defaultSidebarDockedPreference: {
196
- browser: true,
197
- export: false,
198
- server: false
65
+ {
66
+ uri: ComicShanns_Regular_dc6a8806fa96795d7b3be5026f989a17_default,
67
+ descriptors: {
68
+ unicodeRange: "U+2c7,U+2d8-2d9,U+2db,U+2dd,U+315,U+2190,U+2192,U+2200,U+2203-2204,U+2264-2265,U+f6c3"
69
+ }
199
70
  },
200
- isLoading: { browser: false, export: false, server: false },
201
- isResizing: { browser: false, export: false, server: false },
202
- isRotating: { browser: false, export: false, server: false },
203
- lastPointerDownWith: { browser: true, export: false, server: false },
204
- multiElement: { browser: false, export: false, server: false },
205
- name: { browser: true, export: false, server: false },
206
- offsetLeft: { browser: false, export: false, server: false },
207
- offsetTop: { browser: false, export: false, server: false },
208
- contextMenu: { browser: false, export: false, server: false },
209
- openMenu: { browser: true, export: false, server: false },
210
- openPopup: { browser: false, export: false, server: false },
211
- openSidebar: { browser: true, export: false, server: false },
212
- openDialog: { browser: false, export: false, server: false },
213
- pasteDialog: { browser: false, export: false, server: false },
214
- previousSelectedElementIds: { browser: true, export: false, server: false },
215
- resizingElement: { browser: false, export: false, server: false },
216
- scrolledOutside: { browser: true, export: false, server: false },
217
- scrollX: { browser: true, export: false, server: false },
218
- scrollY: { browser: true, export: false, server: false },
219
- selectedElementIds: { browser: true, export: false, server: false },
220
- hoveredElementIds: { browser: false, export: false, server: false },
221
- selectedGroupIds: { browser: true, export: false, server: false },
222
- selectedElementsAreBeingDragged: {
223
- browser: false,
224
- export: false,
225
- server: false
226
- },
227
- selectionElement: { browser: false, export: false, server: false },
228
- shouldCacheIgnoreZoom: { browser: true, export: false, server: false },
229
- stats: { browser: true, export: false, server: false },
230
- startBoundElement: { browser: false, export: false, server: false },
231
- suggestedBinding: { browser: false, export: false, server: false },
232
- frameRendering: { browser: false, export: false, server: false },
233
- frameToHighlight: { browser: false, export: false, server: false },
234
- editingFrame: { browser: false, export: false, server: false },
235
- elementsToHighlight: { browser: false, export: false, server: false },
236
- toast: { browser: false, export: false, server: false },
237
- viewBackgroundColor: { browser: true, export: true, server: true },
238
- width: { browser: false, export: false, server: false },
239
- zenModeEnabled: { browser: true, export: false, server: false },
240
- zoom: { browser: true, export: false, server: false },
241
- viewModeEnabled: { browser: false, export: false, server: false },
242
- showHyperlinkPopup: { browser: false, export: false, server: false },
243
- selectedLinearElement: { browser: true, export: false, server: false },
244
- snapLines: { browser: false, export: false, server: false },
245
- originSnapOffset: { browser: false, export: false, server: false },
246
- objectsSnapModeEnabled: { browser: true, export: false, server: false },
247
- userToFollow: { browser: false, export: false, server: false },
248
- followedBy: { browser: false, export: false, server: false },
249
- isCropping: { browser: false, export: false, server: false },
250
- croppingElementId: { browser: false, export: false, server: false },
251
- searchMatches: { browser: false, export: false, server: false },
252
- lockedMultiSelections: { browser: true, export: true, server: true },
253
- activeLockedId: { browser: false, export: false, server: false },
254
- bindMode: { browser: true, export: false, server: false }
255
- });
256
- var _clearAppStateForStorage = (appState, exportType) => {
257
- const stateForExport = {};
258
- for (const key of Object.keys(appState)) {
259
- const propConfig = APP_STATE_STORAGE_CONF[key];
260
- if (propConfig?.[exportType]) {
261
- const nextValue = appState[key];
262
- stateForExport[key] = nextValue;
263
- }
71
+ {
72
+ uri: ComicShanns_Regular_6e066e8de2ac57ea9283adb9c24d7f0c_default,
73
+ descriptors: { unicodeRange: "U+3bb" }
264
74
  }
265
- return stateForExport;
266
- };
267
- var cleanAppStateForExport = (appState) => {
268
- return _clearAppStateForStorage(appState, "export");
269
- };
270
- var clearAppStateForDatabase = (appState) => {
271
- return _clearAppStateForStorage(appState, "server");
272
- };
273
- var isEraserActive = ({
274
- activeTool
275
- }) => activeTool.type === "eraser";
276
- var isHandToolActive = ({
277
- activeTool
278
- }) => {
279
- return activeTool.type === "hand";
280
- };
75
+ ];
76
+
77
+ // fonts/Emoji/index.ts
78
+ import { LOCAL_FONT_PROTOCOL } from "@orangecatai/common";
79
+ var EmojiFontFaces = [
80
+ {
81
+ uri: LOCAL_FONT_PROTOCOL
82
+ }
83
+ ];
84
+
85
+ // fonts/ExcalidrawFontFace.ts
86
+ import { promiseTry as promiseTry2, LOCAL_FONT_PROTOCOL as LOCAL_FONT_PROTOCOL2 } from "@orangecatai/common";
87
+
88
+ // subset/subset-main.ts
89
+ import { isServerEnv, promiseTry } from "@orangecatai/common";
281
90
 
282
91
  // errors.ts
283
92
  var CanvasError = class extends Error {
@@ -341,954 +150,524 @@ var RequestError = class extends Error {
341
150
  }
342
151
  };
343
152
 
344
- // scene/index.ts
345
- import {
346
- isSomeElementSelected,
347
- getElementsWithinSelection,
348
- getSelectedElements,
349
- getTargetElements
350
- } from "@orangecatai/element";
351
-
352
- // scene/scroll.ts
353
- import { getVisibleElements } from "@orangecatai/element";
354
- import {
355
- sceneCoordsToViewportCoords,
356
- viewportCoordsToSceneCoords
357
- } from "@orangecatai/common";
358
- import { getClosestElementBounds } from "@orangecatai/element";
359
- import { getCommonBounds } from "@orangecatai/element";
360
- var isOutsideViewPort = (appState, cords) => {
361
- const [x1, y1, x2, y2] = cords;
362
- const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(
363
- { sceneX: x1, sceneY: y1 },
364
- appState
365
- );
366
- const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(
367
- { sceneX: x2, sceneY: y2 },
368
- appState
369
- );
370
- return viewportX2 - viewportX1 > appState.width || viewportY2 - viewportY1 > appState.height;
371
- };
372
- var centerScrollOn = ({
373
- scenePoint,
374
- viewportDimensions,
375
- zoom,
376
- offsets
377
- }) => {
378
- let scrollX = (viewportDimensions.width - (offsets?.right ?? 0)) / 2 / zoom.value - scenePoint.x;
379
- scrollX += (offsets?.left ?? 0) / 2 / zoom.value;
380
- let scrollY = (viewportDimensions.height - (offsets?.bottom ?? 0)) / 2 / zoom.value - scenePoint.y;
381
- scrollY += (offsets?.top ?? 0) / 2 / zoom.value;
382
- return {
383
- scrollX,
384
- scrollY
385
- };
153
+ // workers.ts
154
+ import { debounce } from "@orangecatai/common";
155
+ var IdleWorker = class {
156
+ constructor(workerUrl) {
157
+ __publicField(this, "instance");
158
+ /**
159
+ * Use to prolong the worker's life by `workerTTL` or terminate it with a flush immediately.
160
+ */
161
+ __publicField(this, "debounceTerminate");
162
+ this.instance = new Worker(workerUrl, { type: "module" });
163
+ }
386
164
  };
387
- var calculateScrollCenter = (elements, appState) => {
388
- elements = getVisibleElements(elements);
389
- if (!elements.length) {
390
- return {
391
- scrollX: 0,
392
- scrollY: 0
165
+ var WorkerPool = class _WorkerPool {
166
+ constructor(workerUrl, options) {
167
+ __publicField(this, "idleWorkers", /* @__PURE__ */ new Set());
168
+ __publicField(this, "workerUrl");
169
+ __publicField(this, "workerTTL");
170
+ this.workerUrl = workerUrl;
171
+ this.workerTTL = options.ttl || 1e3;
172
+ }
173
+ /**
174
+ * Create a new worker pool.
175
+ *
176
+ * @param workerUrl - The URL of the worker file.
177
+ * @param options - The options for the worker pool.
178
+ * @throws If the worker is bundled into the main chunk.
179
+ * @returns A new worker pool instance.
180
+ */
181
+ static create(workerUrl, options = {}) {
182
+ if (!workerUrl) {
183
+ throw new WorkerUrlNotDefinedError();
184
+ }
185
+ if (!import.meta.url || workerUrl.toString() === import.meta.url) {
186
+ throw new WorkerInTheMainChunkError();
187
+ }
188
+ return new _WorkerPool(workerUrl, options);
189
+ }
190
+ /**
191
+ * Take idle worker from the pool or create a new one and post a message to it.
192
+ */
193
+ async postMessage(data, options) {
194
+ let worker;
195
+ const idleWorker = Array.from(this.idleWorkers).shift();
196
+ if (idleWorker) {
197
+ this.idleWorkers.delete(idleWorker);
198
+ worker = idleWorker;
199
+ } else {
200
+ worker = await this.createWorker();
201
+ }
202
+ return new Promise((resolve, reject) => {
203
+ worker.instance.onmessage = this.onMessageHandler(worker, resolve);
204
+ worker.instance.onerror = this.onErrorHandler(worker, reject);
205
+ worker.instance.postMessage(data, options);
206
+ worker.debounceTerminate(
207
+ () => reject(
208
+ new Error(`Active worker did not respond for ${this.workerTTL}ms!`)
209
+ )
210
+ );
211
+ });
212
+ }
213
+ /**
214
+ * Terminate the idle workers in the pool.
215
+ */
216
+ async clear() {
217
+ for (const worker of this.idleWorkers) {
218
+ worker.debounceTerminate.cancel();
219
+ worker.instance.terminate();
220
+ }
221
+ this.idleWorkers.clear();
222
+ }
223
+ /**
224
+ * Used to get a worker from the pool or create a new one if there is no idle available.
225
+ */
226
+ async createWorker() {
227
+ const worker = new IdleWorker(this.workerUrl);
228
+ worker.debounceTerminate = debounce((reject) => {
229
+ worker.instance.terminate();
230
+ if (this.idleWorkers.has(worker)) {
231
+ this.idleWorkers.delete(worker);
232
+ console.debug(
233
+ "Job finished! Idle worker has been released from the pool."
234
+ );
235
+ } else if (reject) {
236
+ reject();
237
+ } else {
238
+ console.error("Worker has been terminated!");
239
+ }
240
+ }, this.workerTTL);
241
+ return worker;
242
+ }
243
+ onMessageHandler(worker, resolve) {
244
+ return (e) => {
245
+ worker.debounceTerminate();
246
+ this.idleWorkers.add(worker);
247
+ resolve(e.data);
393
248
  };
394
249
  }
395
- let [x1, y1, x2, y2] = getCommonBounds(elements);
396
- if (isOutsideViewPort(appState, [x1, y1, x2, y2])) {
397
- [x1, y1, x2, y2] = getClosestElementBounds(
398
- elements,
399
- viewportCoordsToSceneCoords(
400
- { clientX: appState.scrollX, clientY: appState.scrollY },
401
- appState
402
- )
403
- );
250
+ onErrorHandler(worker, reject) {
251
+ return (e) => {
252
+ worker.debounceTerminate(() => reject(e));
253
+ worker.debounceTerminate.flush();
254
+ this.clear();
255
+ };
404
256
  }
405
- const centerX = (x1 + x2) / 2;
406
- const centerY = (y1 + y2) / 2;
407
- return centerScrollOn({
408
- scenePoint: { x: centerX, y: centerY },
409
- viewportDimensions: { width: appState.width, height: appState.height },
410
- zoom: appState.zoom
411
- });
412
257
  };
413
258
 
414
- // scene/index.ts
415
- import {
416
- hasBackground,
417
- hasStrokeWidth,
418
- hasStrokeStyle,
419
- canHaveArrowheads,
420
- canChangeRoundness
421
- } from "@orangecatai/element";
422
-
423
- // scene/normalize.ts
424
- import { MAX_ZOOM, MIN_ZOOM } from "@orangecatai/common";
425
- import { clamp, round } from "@orangecatai/math";
426
- var getNormalizedZoom = (zoom) => {
427
- return clamp(round(zoom, 6), MIN_ZOOM, MAX_ZOOM);
428
- };
429
- var getNormalizedGridSize = (gridStep) => {
430
- return clamp(Math.round(gridStep), 1, 100);
431
- };
432
- var getNormalizedGridStep = (gridStep) => {
433
- return clamp(Math.round(gridStep), 1, 100);
434
- };
435
-
436
- // scene/export.ts
437
- import rough from "roughjs/bin/rough";
438
- import {
439
- DEFAULT_EXPORT_PADDING,
440
- FRAME_STYLE as FRAME_STYLE3,
441
- FONT_FAMILY as FONT_FAMILY2,
442
- SVG_NS as SVG_NS2,
443
- THEME as THEME5,
444
- MIME_TYPES as MIME_TYPES5,
445
- EXPORT_DATA_TYPES as EXPORT_DATA_TYPES2,
446
- arrayToMap,
447
- distance,
448
- getFontString as getFontString2,
449
- toBrandedType,
450
- applyDarkModeFilter as applyDarkModeFilter4
451
- } from "@orangecatai/common";
452
- import {
453
- getCommonBounds as getCommonBounds2,
454
- getElementAbsoluteCoords as getElementAbsoluteCoords4
455
- } from "@orangecatai/element";
456
- import {
457
- getInitializedImageElements,
458
- updateImageCache
459
- } from "@orangecatai/element";
460
- import { newElementWith } from "@orangecatai/element";
461
- import { isFrameLikeElement } from "@orangecatai/element";
462
- import {
463
- getElementsOverlappingFrame,
464
- getFrameLikeElements,
465
- getFrameLikeTitle,
466
- getRootElements
467
- } from "@orangecatai/element";
468
- import { syncInvalidIndices } from "@orangecatai/element";
469
- import { newTextElement } from "@orangecatai/element";
470
-
471
- // data/encode.ts
472
- import { deflate, inflate } from "pako";
473
-
474
- // data/encryption.ts
475
- import { ENCRYPTION_KEY_BITS } from "@orangecatai/common";
476
-
477
- // data/encode.ts
478
- var toByteString = (data) => {
479
- const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data);
480
- let bstring = "";
481
- for (const byte of bytes) {
482
- bstring += String.fromCharCode(byte);
483
- }
484
- return bstring;
485
- };
486
- var byteStringToArrayBuffer = (byteString) => {
487
- const buffer = new ArrayBuffer(byteString.length);
488
- const bufferView = new Uint8Array(buffer);
489
- for (let i = 0, len = byteString.length; i < len; i++) {
490
- bufferView[i] = byteString.charCodeAt(i);
259
+ // subset/subset-main.ts
260
+ var shouldUseWorkers = typeof Worker !== "undefined";
261
+ var subsetWoff2GlyphsByCodepoints = async (arrayBuffer, codePoints) => {
262
+ const { Commands, subsetToBase64, toBase64 } = await lazyLoadSharedSubsetChunk();
263
+ if (!shouldUseWorkers) {
264
+ return subsetToBase64(arrayBuffer, codePoints);
491
265
  }
492
- return buffer;
493
- };
494
- var byteStringToString = (byteString) => {
495
- return new TextDecoder("utf-8").decode(byteStringToArrayBuffer(byteString));
496
- };
497
- var stringToBase64 = (str, isByteString = false) => {
498
- return isByteString ? window.btoa(str) : window.btoa(toByteString(str));
499
- };
500
- var base64ToString = (base64, isByteString = false) => {
501
- return isByteString ? window.atob(base64) : byteStringToString(window.atob(base64));
502
- };
503
- var encode = ({
504
- text,
505
- compress
506
- }) => {
507
- let deflated;
508
- if (compress !== false) {
266
+ return promiseTry(async () => {
509
267
  try {
510
- deflated = toByteString(deflate(text));
511
- } catch (error) {
512
- console.error("encode: cannot deflate", error);
268
+ const workerPool2 = await getOrCreateWorkerPool();
269
+ const arrayBufferCopy = arrayBuffer.slice(0);
270
+ const result = await workerPool2.postMessage(
271
+ {
272
+ command: Commands.Subset,
273
+ arrayBuffer: arrayBufferCopy,
274
+ codePoints
275
+ },
276
+ { transfer: [arrayBufferCopy] }
277
+ );
278
+ return toBase64(result);
279
+ } catch (e) {
280
+ shouldUseWorkers = false;
281
+ if (
282
+ // don't log the expected errors server-side
283
+ !(isServerEnv() && (e instanceof WorkerUrlNotDefinedError || e instanceof WorkerInTheMainChunkError))
284
+ ) {
285
+ console.error(
286
+ "Failed to use workers for subsetting, falling back to the main thread.",
287
+ e
288
+ );
289
+ }
290
+ return subsetToBase64(arrayBuffer, codePoints);
513
291
  }
292
+ });
293
+ };
294
+ var subsetWorker = null;
295
+ var subsetShared = null;
296
+ var lazyLoadWorkerSubsetChunk = async () => {
297
+ if (!subsetWorker) {
298
+ subsetWorker = import("./subset-worker.chunk.js");
514
299
  }
515
- return {
516
- version: "1",
517
- encoding: "bstring",
518
- compressed: !!deflated,
519
- encoded: deflated || toByteString(text)
520
- };
300
+ return subsetWorker;
521
301
  };
522
- var decode = (data) => {
523
- let decoded;
524
- switch (data.encoding) {
525
- case "bstring":
526
- decoded = data.compressed ? data.encoded : byteStringToString(data.encoded);
527
- break;
528
- default:
529
- throw new Error(`decode: unknown encoding "${data.encoding}"`);
302
+ var lazyLoadSharedSubsetChunk = async () => {
303
+ if (!subsetShared) {
304
+ subsetShared = import("./subset-shared.chunk.js");
530
305
  }
531
- if (data.compressed) {
532
- return inflate(new Uint8Array(byteStringToArrayBuffer(decoded)), {
533
- to: "string"
306
+ return subsetShared;
307
+ };
308
+ var workerPool = null;
309
+ var getOrCreateWorkerPool = () => {
310
+ if (!workerPool) {
311
+ workerPool = promiseTry(async () => {
312
+ const { WorkerUrl } = await lazyLoadWorkerSubsetChunk();
313
+ const pool = WorkerPool.create(WorkerUrl);
314
+ return pool;
534
315
  });
535
316
  }
536
- return decoded;
317
+ return workerPool;
537
318
  };
538
319
 
539
- // data/json.ts
540
- import {
541
- DEFAULT_FILENAME,
542
- EXPORT_DATA_TYPES,
543
- getExportSource,
544
- MIME_TYPES as MIME_TYPES2,
545
- VERSIONS
546
- } from "@orangecatai/common";
547
-
548
- // data/filesystem.ts
549
- import {
550
- fileOpen as _fileOpen,
551
- fileSave as _fileSave,
552
- supported as nativeFileSystemSupported
553
- } from "browser-fs-access";
554
- import { EVENT, MIME_TYPES, debounce } from "@orangecatai/common";
555
- var INPUT_CHANGE_INTERVAL_MS = 5e3;
556
- var fileOpen = async (opts) => {
557
- const mimeTypes = opts.extensions?.reduce((mimeTypes2, type) => {
558
- mimeTypes2.push(MIME_TYPES[type]);
559
- return mimeTypes2;
560
- }, []);
561
- const extensions = opts.extensions?.reduce((acc, ext) => {
562
- if (ext === "jpg") {
563
- return acc.concat(".jpg", ".jpeg");
564
- }
565
- return acc.concat(`.${ext}`);
566
- }, []);
567
- const files = await _fileOpen({
568
- description: opts.description,
569
- extensions,
570
- mimeTypes,
571
- multiple: opts.multiple ?? false,
572
- legacySetup: (resolve, reject, input) => {
573
- const scheduleRejection = debounce(reject, INPUT_CHANGE_INTERVAL_MS);
574
- const focusHandler = () => {
575
- checkForFile();
576
- document.addEventListener(EVENT.KEYUP, scheduleRejection);
577
- document.addEventListener(EVENT.POINTER_UP, scheduleRejection);
578
- scheduleRejection();
579
- };
580
- const checkForFile = () => {
581
- if (input.files?.length) {
582
- const ret = opts.multiple ? [...input.files] : input.files[0];
583
- resolve(ret);
584
- }
585
- };
586
- requestAnimationFrame(() => {
587
- window.addEventListener(EVENT.FOCUS, focusHandler);
588
- });
589
- const interval = window.setInterval(() => {
590
- checkForFile();
591
- }, INPUT_CHANGE_INTERVAL_MS);
592
- return (rejectPromise) => {
593
- clearInterval(interval);
594
- scheduleRejection.cancel();
595
- window.removeEventListener(EVENT.FOCUS, focusHandler);
596
- document.removeEventListener(EVENT.KEYUP, scheduleRejection);
597
- document.removeEventListener(EVENT.POINTER_UP, scheduleRejection);
598
- if (rejectPromise) {
599
- console.warn("Opening the file was canceled (legacy-fs).");
600
- rejectPromise(new AbortError());
601
- }
602
- };
320
+ // fonts/ExcalidrawFontFace.ts
321
+ var _ExcalidrawFontFace = class _ExcalidrawFontFace {
322
+ constructor(family, uri, descriptors) {
323
+ __publicField(this, "urls");
324
+ __publicField(this, "fontFace");
325
+ this.urls = _ExcalidrawFontFace.createUrls(uri);
326
+ const sources = this.urls.map((url) => `url(${url}) ${_ExcalidrawFontFace.getFormat(url)}`).join(", ");
327
+ this.fontFace = new FontFace(family, sources, {
328
+ display: "swap",
329
+ style: "normal",
330
+ weight: "400",
331
+ ...descriptors
332
+ });
333
+ }
334
+ /**
335
+ * Generates CSS `@font-face` definition with the (subsetted) font source as a data url for the characters within the unicode range.
336
+ *
337
+ * Retrieves `undefined` otherwise.
338
+ */
339
+ toCSS(characters) {
340
+ if (!this.getUnicodeRangeRegex().test(characters)) {
341
+ return;
603
342
  }
604
- });
605
- if (Array.isArray(files)) {
606
- return await Promise.all(
607
- files.map((file) => normalizeFile(file))
343
+ const codepoints = Array.from(characters).map(
344
+ (char) => char.codePointAt(0)
345
+ );
346
+ return this.getContent(codepoints).then(
347
+ (content) => `@font-face { font-family: ${this.fontFace.family}; src: url(${content}); }`
608
348
  );
609
349
  }
610
- return await normalizeFile(files);
611
- };
612
- var fileSave = (blob, opts) => {
613
- return _fileSave(
614
- blob,
615
- {
616
- fileName: `${opts.name}.${opts.extension}`,
617
- description: opts.description,
618
- extensions: [`.${opts.extension}`],
619
- mimeTypes: opts.mimeTypes
620
- },
621
- opts.fileHandle
622
- );
623
- };
624
-
625
- // data/json.ts
626
- var filterOutDeletedFiles = (elements, files) => {
627
- const nextFiles = {};
628
- for (const element of elements) {
629
- if (!element.isDeleted && "fileId" in element && element.fileId && files[element.fileId]) {
630
- nextFiles[element.fileId] = files[element.fileId];
350
+ /**
351
+ * Tries to fetch woff2 content, based on the registered urls (from first to last, treated as fallbacks).
352
+ *
353
+ * @returns base64 with subsetted glyphs based on the passed codepoint, last defined url otherwise
354
+ */
355
+ async getContent(codePoints) {
356
+ let i = 0;
357
+ const errorMessages = [];
358
+ while (i < this.urls.length) {
359
+ const url = this.urls[i];
360
+ try {
361
+ const arrayBuffer = await this.fetchFont(url);
362
+ const base64 = await subsetWoff2GlyphsByCodepoints(
363
+ arrayBuffer,
364
+ codePoints
365
+ );
366
+ return base64;
367
+ } catch (e) {
368
+ errorMessages.push(`"${url.toString()}" returned error "${e}"`);
369
+ }
370
+ i++;
631
371
  }
372
+ console.error(
373
+ `Failed to fetch font family "${this.fontFace.family}"`,
374
+ JSON.stringify(errorMessages, void 0, 2)
375
+ );
376
+ return this.urls.length ? this.urls[this.urls.length - 1].toString() : "";
632
377
  }
633
- return nextFiles;
634
- };
635
- var serializeAsJSON = (elements, appState, files, type) => {
636
- const data = {
637
- type: EXPORT_DATA_TYPES.excalidraw,
638
- version: VERSIONS.excalidraw,
639
- source: getExportSource(),
640
- elements,
641
- appState: type === "local" ? cleanAppStateForExport(appState) : clearAppStateForDatabase(appState),
642
- files: type === "local" ? filterOutDeletedFiles(elements, files) : (
643
- // will be stripped from JSON
644
- void 0
645
- )
646
- };
647
- return JSON.stringify(data, null, 2);
648
- };
649
- var saveAsJSON = async (elements, appState, files, name = appState.name || DEFAULT_FILENAME) => {
650
- const serialized = serializeAsJSON(elements, appState, files, "local");
651
- const blob = new Blob([serialized], {
652
- type: MIME_TYPES2.excalidraw
653
- });
654
- const fileHandle = await fileSave(blob, {
655
- name,
656
- extension: "excalidraw",
657
- description: "Excalidraw file",
658
- fileHandle: isImageFileHandle(appState.fileHandle) ? null : appState.fileHandle
659
- });
660
- return { fileHandle };
661
- };
662
- var isValidExcalidrawData = (data) => {
663
- return data?.type === EXPORT_DATA_TYPES.excalidraw && (!data.elements || Array.isArray(data.elements) && (!data.appState || typeof data.appState === "object"));
664
- };
665
- var isValidLibrary = (json) => {
666
- return typeof json === "object" && json && json.type === EXPORT_DATA_TYPES.excalidrawLibrary && (json.version === 1 || json.version === 2);
667
- };
668
- var serializeLibraryAsJSON = (libraryItems) => {
669
- const data = {
670
- type: EXPORT_DATA_TYPES.excalidrawLibrary,
671
- version: VERSIONS.excalidrawLibrary,
672
- source: getExportSource(),
673
- libraryItems
674
- };
675
- return JSON.stringify(data, null, 2);
676
- };
677
- var saveLibraryAsJSON = async (libraryItems) => {
678
- const serialized = serializeLibraryAsJSON(libraryItems);
679
- await fileSave(
680
- new Blob([serialized], {
681
- type: MIME_TYPES2.excalidrawlib
682
- }),
683
- {
684
- name: "library",
685
- extension: "excalidrawlib",
686
- description: "Excalidraw library file"
378
+ fetchFont(url) {
379
+ return promiseTry2(async () => {
380
+ const response = await fetch(url, {
381
+ // always prefer cache (even stale), otherwise it always triggers an unnecessary validation request
382
+ // which we don't need as we are controlling freshness of the fonts with the stable hash suffix in the url
383
+ // https://developer.mozilla.org/en-US/docs/Web/API/Request/cache
384
+ cache: "force-cache",
385
+ headers: {
386
+ Accept: "font/woff2"
387
+ }
388
+ });
389
+ if (!response.ok) {
390
+ const urlString = url instanceof URL ? url.toString() : "dataurl";
391
+ throw new Error(
392
+ `Failed to fetch "${urlString}": ${response.statusText}`
393
+ );
394
+ }
395
+ const arrayBuffer = await response.arrayBuffer();
396
+ return arrayBuffer;
397
+ });
398
+ }
399
+ getUnicodeRangeRegex() {
400
+ const unicodeRangeRegex = this.fontFace.unicodeRange.split(/,\s*/).map((range) => {
401
+ const [start, end] = range.replace("U+", "").split("-");
402
+ if (end) {
403
+ return `\\u{${start}}-\\u{${end}}`;
404
+ }
405
+ return `\\u{${start}}`;
406
+ }).join("");
407
+ return new RegExp(`[${unicodeRangeRegex}]`, "u");
408
+ }
409
+ static createUrls(uri) {
410
+ if (uri.startsWith("data")) {
411
+ return [uri];
687
412
  }
688
- );
413
+ if (uri.startsWith(LOCAL_FONT_PROTOCOL2)) {
414
+ return [];
415
+ }
416
+ if (uri.startsWith("http")) {
417
+ return [new URL(uri)];
418
+ }
419
+ const assetUrl = uri.replace(/^\/+/, "");
420
+ const urls = [];
421
+ if (typeof window.EXCALIDRAW_ASSET_PATH === "string") {
422
+ const normalizedBaseUrl = this.normalizeBaseUrl(
423
+ window.EXCALIDRAW_ASSET_PATH
424
+ );
425
+ urls.push(new URL(assetUrl, normalizedBaseUrl));
426
+ } else if (Array.isArray(window.EXCALIDRAW_ASSET_PATH)) {
427
+ window.EXCALIDRAW_ASSET_PATH.forEach((path) => {
428
+ const normalizedBaseUrl = this.normalizeBaseUrl(path);
429
+ urls.push(new URL(assetUrl, normalizedBaseUrl));
430
+ });
431
+ }
432
+ urls.push(new URL(assetUrl, _ExcalidrawFontFace.ASSETS_FALLBACK_URL));
433
+ return urls;
434
+ }
435
+ static getFormat(url) {
436
+ if (!(url instanceof URL)) {
437
+ return "";
438
+ }
439
+ try {
440
+ const parts = new URL(url).pathname.split(".");
441
+ if (parts.length === 1) {
442
+ return "";
443
+ }
444
+ return `format('${parts.pop()}')`;
445
+ } catch (error) {
446
+ return "";
447
+ }
448
+ }
449
+ static normalizeBaseUrl(baseUrl) {
450
+ let result = baseUrl;
451
+ if (/^\.?\//.test(result)) {
452
+ result = new URL(
453
+ result.replace(/^\.?\/+/, ""),
454
+ window?.location?.origin
455
+ ).toString();
456
+ }
457
+ result = `${result.replace(/\/+$/, "")}/`;
458
+ return result;
459
+ }
689
460
  };
461
+ __publicField(_ExcalidrawFontFace, "ASSETS_FALLBACK_URL", `https://esm.sh/${define_import_meta_env_default.PKG_NAME ? `${define_import_meta_env_default.PKG_NAME}@${define_import_meta_env_default.PKG_VERSION}` : "@orangecatai/adgen-canvas"}/dist/prod/`);
462
+ var ExcalidrawFontFace = _ExcalidrawFontFace;
690
463
 
691
- // fonts/Fonts.ts
692
- import {
693
- FONT_FAMILY,
694
- FONT_FAMILY_FALLBACKS,
695
- CJK_HAND_DRAWN_FALLBACK_FONT,
696
- WINDOWS_EMOJI_FALLBACK_FONT,
697
- getFontFamilyFallbacks,
698
- FONT_SIZES
699
- } from "@orangecatai/common";
700
- import { getContainerElement } from "@orangecatai/element";
701
- import { charWidth } from "@orangecatai/element";
702
- import { containsCJK } from "@orangecatai/element";
703
- import {
704
- FONT_METADATA,
705
- getFontString,
706
- PromisePool,
707
- promiseTry as promiseTry3
708
- } from "@orangecatai/common";
709
- import { ShapeCache } from "@orangecatai/element";
710
- import { isTextElement } from "@orangecatai/element";
464
+ // fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2
465
+ var Excalifont_Regular_349fac6ca4700ffec595a7150a0d1e1d_default = "./fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2";
711
466
 
712
- // fonts/Cascadia/CascadiaCode-Regular.woff2
713
- var CascadiaCode_Regular_default = "./fonts/Cascadia/CascadiaCode-Regular.woff2";
467
+ // fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2
468
+ var Excalifont_Regular_3f2c5db56cc93c5a6873b1361d730c16_default = "./fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2";
714
469
 
715
- // fonts/Cascadia/index.ts
716
- var CascadiaFontFaces = [
717
- {
718
- uri: CascadiaCode_Regular_default
719
- }
720
- ];
470
+ // fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2
471
+ var Excalifont_Regular_41b173a47b57366892116a575a43e2b6_default = "./fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2";
721
472
 
722
- // fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2
723
- var ComicShanns_Regular_279a7b317d12eb88de06167bd672b4b4_default = "./fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2";
473
+ // fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2
474
+ var Excalifont_Regular_623ccf21b21ef6b3a0d87738f77eb071_default = "./fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2";
724
475
 
725
- // fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2
726
- var ComicShanns_Regular_6e066e8de2ac57ea9283adb9c24d7f0c_default = "./fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2";
476
+ // fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2
477
+ var Excalifont_Regular_a88b72a24fb54c9f94e3b5fdaa7481c9_default = "./fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2";
727
478
 
728
- // fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2
729
- var ComicShanns_Regular_dc6a8806fa96795d7b3be5026f989a17_default = "./fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2";
479
+ // fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2
480
+ var Excalifont_Regular_b9dcf9d2e50a1eaf42fc664b50a3fd0d_default = "./fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2";
730
481
 
731
- // fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2
732
- var ComicShanns_Regular_fcb0fc02dcbee4c9846b3e2508668039_default = "./fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2";
482
+ // fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2
483
+ var Excalifont_Regular_be310b9bcd4f1a43f571c46df7809174_default = "./fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2";
733
484
 
734
- // fonts/ComicShanns/index.ts
735
- var ComicShannsFontFaces = [
485
+ // fonts/Excalifont/index.ts
486
+ var ExcalifontFontFaces = [
736
487
  {
737
- uri: ComicShanns_Regular_279a7b317d12eb88de06167bd672b4b4_default,
488
+ uri: Excalifont_Regular_a88b72a24fb54c9f94e3b5fdaa7481c9_default,
738
489
  descriptors: {
739
- unicodeRange: "U+20-7e,U+a1-a6,U+a8,U+ab-ac,U+af-b1,U+b4,U+b8,U+bb-bc,U+bf-cf,U+d1-d7,U+d9-de,U+e0-ef,U+f1-f7,U+f9-ff,U+131,U+152-153,U+2c6,U+2da,U+2dc,U+2013-2014,U+2018-201a,U+201c-201d,U+2020-2022,U+2026,U+2039-203a,U+2044,U+20ac,U+2191,U+2193,U+2212"
490
+ unicodeRange: "U+20-7e,U+a0-a3,U+a5-a6,U+a8-ab,U+ad-b1,U+b4,U+b6-b8,U+ba-ff,U+131,U+152-153,U+2bc,U+2c6,U+2da,U+2dc,U+304,U+308,U+2013-2014,U+2018-201a,U+201c-201e,U+2020,U+2022,U+2024-2026,U+2030,U+2039-203a,U+20ac,U+2122,U+2212"
740
491
  }
741
492
  },
742
493
  {
743
- uri: ComicShanns_Regular_fcb0fc02dcbee4c9846b3e2508668039_default,
494
+ uri: Excalifont_Regular_be310b9bcd4f1a43f571c46df7809174_default,
744
495
  descriptors: {
745
- unicodeRange: "U+100-10f,U+112-125,U+128-130,U+134-137,U+139-13c,U+141-148,U+14c-151,U+154-161,U+164-165,U+168-17f,U+1bf,U+1f7,U+218-21b,U+237,U+1e80-1e85,U+1ef2-1ef3,U+a75b"
496
+ unicodeRange: "U+100-130,U+132-137,U+139-149,U+14c-151,U+154-17e,U+192,U+1fc-1ff,U+218-21b,U+237,U+1e80-1e85,U+1ef2-1ef3,U+2113"
746
497
  }
747
498
  },
499
+ { uri: Excalifont_Regular_b9dcf9d2e50a1eaf42fc664b50a3fd0d_default, descriptors: { unicodeRange: "U+400-45f,U+490-491,U+2116" } },
748
500
  {
749
- uri: ComicShanns_Regular_dc6a8806fa96795d7b3be5026f989a17_default,
501
+ uri: Excalifont_Regular_41b173a47b57366892116a575a43e2b6_default,
750
502
  descriptors: {
751
- unicodeRange: "U+2c7,U+2d8-2d9,U+2db,U+2dd,U+315,U+2190,U+2192,U+2200,U+2203-2204,U+2264-2265,U+f6c3"
503
+ unicodeRange: "U+37e,U+384-38a,U+38c,U+38e-393,U+395-3a1,U+3a3-3a8,U+3aa-3cf,U+3d7"
752
504
  }
753
505
  },
754
506
  {
755
- uri: ComicShanns_Regular_6e066e8de2ac57ea9283adb9c24d7f0c_default,
756
- descriptors: { unicodeRange: "U+3bb" }
757
- }
507
+ uri: Excalifont_Regular_3f2c5db56cc93c5a6873b1361d730c16_default,
508
+ descriptors: {
509
+ unicodeRange: "U+2c7,U+2d8-2d9,U+2db,U+2dd,U+302,U+306-307,U+30a-30c,U+326-328,U+212e,U+2211,U+fb01-fb02"
510
+ }
511
+ },
512
+ {
513
+ uri: Excalifont_Regular_349fac6ca4700ffec595a7150a0d1e1d_default,
514
+ descriptors: {
515
+ unicodeRange: "U+462-463,U+472-475,U+4d8-4d9,U+4e2-4e3,U+4e6-4e9,U+4ee-4ef"
516
+ }
517
+ },
518
+ { uri: Excalifont_Regular_623ccf21b21ef6b3a0d87738f77eb071_default, descriptors: { unicodeRange: "U+300-301,U+303" } }
758
519
  ];
759
520
 
760
- // fonts/Emoji/index.ts
761
- import { LOCAL_FONT_PROTOCOL } from "@orangecatai/common";
762
- var EmojiFontFaces = [
521
+ // fonts/Helvetica/index.ts
522
+ import { LOCAL_FONT_PROTOCOL as LOCAL_FONT_PROTOCOL3 } from "@orangecatai/common";
523
+ var HelveticaFontFaces = [
763
524
  {
764
- uri: LOCAL_FONT_PROTOCOL
525
+ uri: LOCAL_FONT_PROTOCOL3
765
526
  }
766
527
  ];
767
528
 
768
- // fonts/ExcalidrawFontFace.ts
769
- import { promiseTry as promiseTry2, LOCAL_FONT_PROTOCOL as LOCAL_FONT_PROTOCOL2 } from "@orangecatai/common";
770
-
771
- // subset/subset-main.ts
772
- import { isServerEnv, promiseTry } from "@orangecatai/common";
529
+ // fonts/Liberation/LiberationSans-Regular.woff2
530
+ var LiberationSans_Regular_default = "./fonts/Liberation/LiberationSans-Regular.woff2";
773
531
 
774
- // workers.ts
775
- import { debounce as debounce2 } from "@orangecatai/common";
776
- var IdleWorker = class {
777
- constructor(workerUrl) {
778
- __publicField(this, "instance");
779
- /**
780
- * Use to prolong the worker's life by `workerTTL` or terminate it with a flush immediately.
781
- */
782
- __publicField(this, "debounceTerminate");
783
- this.instance = new Worker(workerUrl, { type: "module" });
784
- }
785
- };
786
- var WorkerPool = class _WorkerPool {
787
- constructor(workerUrl, options) {
788
- __publicField(this, "idleWorkers", /* @__PURE__ */ new Set());
789
- __publicField(this, "workerUrl");
790
- __publicField(this, "workerTTL");
791
- this.workerUrl = workerUrl;
792
- this.workerTTL = options.ttl || 1e3;
532
+ // fonts/Liberation/index.ts
533
+ var LiberationFontFaces = [
534
+ {
535
+ uri: LiberationSans_Regular_default
793
536
  }
794
- /**
795
- * Create a new worker pool.
796
- *
797
- * @param workerUrl - The URL of the worker file.
798
- * @param options - The options for the worker pool.
799
- * @throws If the worker is bundled into the main chunk.
800
- * @returns A new worker pool instance.
801
- */
802
- static create(workerUrl, options = {}) {
803
- if (!workerUrl) {
804
- throw new WorkerUrlNotDefinedError();
805
- }
806
- if (!import.meta.url || workerUrl.toString() === import.meta.url) {
807
- throw new WorkerInTheMainChunkError();
808
- }
809
- return new _WorkerPool(workerUrl, options);
537
+ ];
538
+
539
+ // fonts/Lilita/index.ts
540
+ import { GOOGLE_FONTS_RANGES } from "@orangecatai/common";
541
+
542
+ // fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2
543
+ var Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYE98RXi4EwSsbg_default = "./fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2";
544
+
545
+ // fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2
546
+ var Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYEF8RXi4EwQ_default = "./fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2";
547
+
548
+ // fonts/Lilita/index.ts
549
+ var LilitaFontFaces = [
550
+ {
551
+ uri: Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYE98RXi4EwSsbg_default,
552
+ descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN_EXT }
553
+ },
554
+ {
555
+ uri: Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYEF8RXi4EwQ_default,
556
+ descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN }
810
557
  }
811
- /**
812
- * Take idle worker from the pool or create a new one and post a message to it.
813
- */
814
- async postMessage(data, options) {
815
- let worker;
816
- const idleWorker = Array.from(this.idleWorkers).shift();
817
- if (idleWorker) {
818
- this.idleWorkers.delete(idleWorker);
819
- worker = idleWorker;
820
- } else {
821
- worker = await this.createWorker();
558
+ ];
559
+
560
+ // fonts/Nunito/index.ts
561
+ import { GOOGLE_FONTS_RANGES as GOOGLE_FONTS_RANGES2 } from "@orangecatai/common";
562
+
563
+ // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2
564
+ var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2";
565
+
566
+ // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2
567
+ var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2";
568
+
569
+ // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2
570
+ var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2";
571
+
572
+ // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2
573
+ var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2";
574
+
575
+ // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2
576
+ var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2";
577
+
578
+ // fonts/Nunito/index.ts
579
+ var NunitoFontFaces = [
580
+ {
581
+ uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5_default,
582
+ descriptors: {
583
+ unicodeRange: GOOGLE_FONTS_RANGES2.CYRILIC_EXT,
584
+ weight: "500"
822
585
  }
823
- return new Promise((resolve, reject) => {
824
- worker.instance.onmessage = this.onMessageHandler(worker, resolve);
825
- worker.instance.onerror = this.onErrorHandler(worker, reject);
826
- worker.instance.postMessage(data, options);
827
- worker.debounceTerminate(
828
- () => reject(
829
- new Error(`Active worker did not respond for ${this.workerTTL}ms!`)
830
- )
831
- );
832
- });
833
- }
834
- /**
835
- * Terminate the idle workers in the pool.
836
- */
837
- async clear() {
838
- for (const worker of this.idleWorkers) {
839
- worker.debounceTerminate.cancel();
840
- worker.instance.terminate();
586
+ },
587
+ {
588
+ uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5_default,
589
+ descriptors: { unicodeRange: GOOGLE_FONTS_RANGES2.CYRILIC, weight: "500" }
590
+ },
591
+ {
592
+ uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5_default,
593
+ descriptors: {
594
+ unicodeRange: GOOGLE_FONTS_RANGES2.VIETNAMESE,
595
+ weight: "500"
841
596
  }
842
- this.idleWorkers.clear();
843
- }
844
- /**
845
- * Used to get a worker from the pool or create a new one if there is no idle available.
846
- */
847
- async createWorker() {
848
- const worker = new IdleWorker(this.workerUrl);
849
- worker.debounceTerminate = debounce2((reject) => {
850
- worker.instance.terminate();
851
- if (this.idleWorkers.has(worker)) {
852
- this.idleWorkers.delete(worker);
853
- console.debug(
854
- "Job finished! Idle worker has been released from the pool."
855
- );
856
- } else if (reject) {
857
- reject();
858
- } else {
859
- console.error("Worker has been terminated!");
860
- }
861
- }, this.workerTTL);
862
- return worker;
863
- }
864
- onMessageHandler(worker, resolve) {
865
- return (e) => {
866
- worker.debounceTerminate();
867
- this.idleWorkers.add(worker);
868
- resolve(e.data);
869
- };
870
- }
871
- onErrorHandler(worker, reject) {
872
- return (e) => {
873
- worker.debounceTerminate(() => reject(e));
874
- worker.debounceTerminate.flush();
875
- this.clear();
876
- };
597
+ },
598
+ {
599
+ uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5_default,
600
+ descriptors: { unicodeRange: GOOGLE_FONTS_RANGES2.LATIN_EXT, weight: "500" }
601
+ },
602
+ {
603
+ uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg_default,
604
+ descriptors: { unicodeRange: GOOGLE_FONTS_RANGES2.LATIN, weight: "500" }
877
605
  }
878
- };
606
+ ];
879
607
 
880
- // subset/subset-main.ts
881
- var shouldUseWorkers = typeof Worker !== "undefined";
882
- var subsetWoff2GlyphsByCodepoints = async (arrayBuffer, codePoints) => {
883
- const { Commands, subsetToBase64, toBase64 } = await lazyLoadSharedSubsetChunk();
884
- if (!shouldUseWorkers) {
885
- return subsetToBase64(arrayBuffer, codePoints);
886
- }
887
- return promiseTry(async () => {
888
- try {
889
- const workerPool2 = await getOrCreateWorkerPool();
890
- const arrayBufferCopy = arrayBuffer.slice(0);
891
- const result = await workerPool2.postMessage(
892
- {
893
- command: Commands.Subset,
894
- arrayBuffer: arrayBufferCopy,
895
- codePoints
896
- },
897
- { transfer: [arrayBufferCopy] }
898
- );
899
- return toBase64(result);
900
- } catch (e) {
901
- shouldUseWorkers = false;
902
- if (
903
- // don't log the expected errors server-side
904
- !(isServerEnv() && (e instanceof WorkerUrlNotDefinedError || e instanceof WorkerInTheMainChunkError))
905
- ) {
906
- console.error(
907
- "Failed to use workers for subsetting, falling back to the main thread.",
908
- e
909
- );
910
- }
911
- return subsetToBase64(arrayBuffer, codePoints);
912
- }
913
- });
914
- };
915
- var subsetWorker = null;
916
- var subsetShared = null;
917
- var lazyLoadWorkerSubsetChunk = async () => {
918
- if (!subsetWorker) {
919
- subsetWorker = import("./subset-worker.chunk.js");
920
- }
921
- return subsetWorker;
922
- };
923
- var lazyLoadSharedSubsetChunk = async () => {
924
- if (!subsetShared) {
925
- subsetShared = import("./subset-shared.chunk.js");
926
- }
927
- return subsetShared;
928
- };
929
- var workerPool = null;
930
- var getOrCreateWorkerPool = () => {
931
- if (!workerPool) {
932
- workerPool = promiseTry(async () => {
933
- const { WorkerUrl } = await lazyLoadWorkerSubsetChunk();
934
- const pool = WorkerPool.create(WorkerUrl);
935
- return pool;
936
- });
608
+ // fonts/Virgil/Virgil-Regular.woff2
609
+ var Virgil_Regular_default = "./fonts/Virgil/Virgil-Regular.woff2";
610
+
611
+ // fonts/Virgil/index.ts
612
+ var VirgilFontFaces = [
613
+ {
614
+ uri: Virgil_Regular_default
937
615
  }
938
- return workerPool;
939
- };
616
+ ];
940
617
 
941
- // fonts/ExcalidrawFontFace.ts
942
- var _ExcalidrawFontFace = class _ExcalidrawFontFace {
943
- constructor(family, uri, descriptors) {
944
- __publicField(this, "urls");
945
- __publicField(this, "fontFace");
946
- this.urls = _ExcalidrawFontFace.createUrls(uri);
947
- const sources = this.urls.map((url) => `url(${url}) ${_ExcalidrawFontFace.getFormat(url)}`).join(", ");
948
- this.fontFace = new FontFace(family, sources, {
949
- display: "swap",
950
- style: "normal",
951
- weight: "400",
952
- ...descriptors
953
- });
954
- }
955
- /**
956
- * Generates CSS `@font-face` definition with the (subsetted) font source as a data url for the characters within the unicode range.
957
- *
958
- * Retrieves `undefined` otherwise.
959
- */
960
- toCSS(characters) {
961
- if (!this.getUnicodeRangeRegex().test(characters)) {
962
- return;
963
- }
964
- const codepoints = Array.from(characters).map(
965
- (char) => char.codePointAt(0)
966
- );
967
- return this.getContent(codepoints).then(
968
- (content) => `@font-face { font-family: ${this.fontFace.family}; src: url(${content}); }`
969
- );
970
- }
971
- /**
972
- * Tries to fetch woff2 content, based on the registered urls (from first to last, treated as fallbacks).
973
- *
974
- * @returns base64 with subsetted glyphs based on the passed codepoint, last defined url otherwise
975
- */
976
- async getContent(codePoints) {
977
- let i = 0;
978
- const errorMessages = [];
979
- while (i < this.urls.length) {
980
- const url = this.urls[i];
981
- try {
982
- const arrayBuffer = await this.fetchFont(url);
983
- const base64 = await subsetWoff2GlyphsByCodepoints(
984
- arrayBuffer,
985
- codePoints
986
- );
987
- return base64;
988
- } catch (e) {
989
- errorMessages.push(`"${url.toString()}" returned error "${e}"`);
990
- }
991
- i++;
992
- }
993
- console.error(
994
- `Failed to fetch font family "${this.fontFace.family}"`,
995
- JSON.stringify(errorMessages, void 0, 2)
996
- );
997
- return this.urls.length ? this.urls[this.urls.length - 1].toString() : "";
998
- }
999
- fetchFont(url) {
1000
- return promiseTry2(async () => {
1001
- const response = await fetch(url, {
1002
- // always prefer cache (even stale), otherwise it always triggers an unnecessary validation request
1003
- // which we don't need as we are controlling freshness of the fonts with the stable hash suffix in the url
1004
- // https://developer.mozilla.org/en-US/docs/Web/API/Request/cache
1005
- cache: "force-cache",
1006
- headers: {
1007
- Accept: "font/woff2"
1008
- }
1009
- });
1010
- if (!response.ok) {
1011
- const urlString = url instanceof URL ? url.toString() : "dataurl";
1012
- throw new Error(
1013
- `Failed to fetch "${urlString}": ${response.statusText}`
1014
- );
1015
- }
1016
- const arrayBuffer = await response.arrayBuffer();
1017
- return arrayBuffer;
1018
- });
1019
- }
1020
- getUnicodeRangeRegex() {
1021
- const unicodeRangeRegex = this.fontFace.unicodeRange.split(/,\s*/).map((range) => {
1022
- const [start, end] = range.replace("U+", "").split("-");
1023
- if (end) {
1024
- return `\\u{${start}}-\\u{${end}}`;
1025
- }
1026
- return `\\u{${start}}`;
1027
- }).join("");
1028
- return new RegExp(`[${unicodeRangeRegex}]`, "u");
1029
- }
1030
- static createUrls(uri) {
1031
- if (uri.startsWith("data")) {
1032
- return [uri];
1033
- }
1034
- if (uri.startsWith(LOCAL_FONT_PROTOCOL2)) {
1035
- return [];
1036
- }
1037
- if (uri.startsWith("http")) {
1038
- return [new URL(uri)];
1039
- }
1040
- const assetUrl = uri.replace(/^\/+/, "");
1041
- const urls = [];
1042
- if (typeof window.EXCALIDRAW_ASSET_PATH === "string") {
1043
- const normalizedBaseUrl = this.normalizeBaseUrl(
1044
- window.EXCALIDRAW_ASSET_PATH
1045
- );
1046
- urls.push(new URL(assetUrl, normalizedBaseUrl));
1047
- } else if (Array.isArray(window.EXCALIDRAW_ASSET_PATH)) {
1048
- window.EXCALIDRAW_ASSET_PATH.forEach((path) => {
1049
- const normalizedBaseUrl = this.normalizeBaseUrl(path);
1050
- urls.push(new URL(assetUrl, normalizedBaseUrl));
1051
- });
1052
- }
1053
- urls.push(new URL(assetUrl, _ExcalidrawFontFace.ASSETS_FALLBACK_URL));
1054
- return urls;
1055
- }
1056
- static getFormat(url) {
1057
- if (!(url instanceof URL)) {
1058
- return "";
1059
- }
1060
- try {
1061
- const parts = new URL(url).pathname.split(".");
1062
- if (parts.length === 1) {
1063
- return "";
1064
- }
1065
- return `format('${parts.pop()}')`;
1066
- } catch (error) {
1067
- return "";
1068
- }
1069
- }
1070
- static normalizeBaseUrl(baseUrl) {
1071
- let result = baseUrl;
1072
- if (/^\.?\//.test(result)) {
1073
- result = new URL(
1074
- result.replace(/^\.?\/+/, ""),
1075
- window?.location?.origin
1076
- ).toString();
1077
- }
1078
- result = `${result.replace(/\/+$/, "")}/`;
1079
- return result;
1080
- }
1081
- };
1082
- __publicField(_ExcalidrawFontFace, "ASSETS_FALLBACK_URL", `https://esm.sh/${define_import_meta_env_default.PKG_NAME ? `${define_import_meta_env_default.PKG_NAME}@${define_import_meta_env_default.PKG_VERSION}` : "@orangecatai/adgen-canvas"}/dist/prod/`);
1083
- var ExcalidrawFontFace = _ExcalidrawFontFace;
618
+ // fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2
619
+ var Xiaolai_Regular_019d66dcad46dc156b162d267f981c20_default = "./fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2";
1084
620
 
1085
- // fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2
1086
- var Excalifont_Regular_349fac6ca4700ffec595a7150a0d1e1d_default = "./fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2";
621
+ // fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2
622
+ var Xiaolai_Regular_04b718e5623574919c8b0dea5f301444_default = "./fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2";
1087
623
 
1088
- // fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2
1089
- var Excalifont_Regular_3f2c5db56cc93c5a6873b1361d730c16_default = "./fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2";
624
+ // fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2
625
+ var Xiaolai_Regular_069e77aac84590e2e991d0a0176d34f2_default = "./fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2";
1090
626
 
1091
- // fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2
1092
- var Excalifont_Regular_41b173a47b57366892116a575a43e2b6_default = "./fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2";
627
+ // fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2
628
+ var Xiaolai_Regular_06c77b8c66e51ed6c63ccb502dd8b8af_default = "./fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2";
1093
629
 
1094
- // fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2
1095
- var Excalifont_Regular_623ccf21b21ef6b3a0d87738f77eb071_default = "./fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2";
630
+ // fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2
631
+ var Xiaolai_Regular_08e0dc436ad0ad61ba5558db0674d762_default = "./fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2";
1096
632
 
1097
- // fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2
1098
- var Excalifont_Regular_a88b72a24fb54c9f94e3b5fdaa7481c9_default = "./fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2";
633
+ // fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2
634
+ var Xiaolai_Regular_093b9ef39a46ceae95a1df18a0a3a326_default = "./fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2";
1099
635
 
1100
- // fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2
1101
- var Excalifont_Regular_b9dcf9d2e50a1eaf42fc664b50a3fd0d_default = "./fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2";
636
+ // fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2
637
+ var Xiaolai_Regular_095c169f3314805276f603a362766abd_default = "./fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2";
1102
638
 
1103
- // fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2
1104
- var Excalifont_Regular_be310b9bcd4f1a43f571c46df7809174_default = "./fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2";
639
+ // fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2
640
+ var Xiaolai_Regular_09850c4077f3fffe707905872e0e2460_default = "./fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2";
1105
641
 
1106
- // fonts/Excalifont/index.ts
1107
- var ExcalifontFontFaces = [
1108
- {
1109
- uri: Excalifont_Regular_a88b72a24fb54c9f94e3b5fdaa7481c9_default,
1110
- descriptors: {
1111
- unicodeRange: "U+20-7e,U+a0-a3,U+a5-a6,U+a8-ab,U+ad-b1,U+b4,U+b6-b8,U+ba-ff,U+131,U+152-153,U+2bc,U+2c6,U+2da,U+2dc,U+304,U+308,U+2013-2014,U+2018-201a,U+201c-201e,U+2020,U+2022,U+2024-2026,U+2030,U+2039-203a,U+20ac,U+2122,U+2212"
1112
- }
1113
- },
1114
- {
1115
- uri: Excalifont_Regular_be310b9bcd4f1a43f571c46df7809174_default,
1116
- descriptors: {
1117
- unicodeRange: "U+100-130,U+132-137,U+139-149,U+14c-151,U+154-17e,U+192,U+1fc-1ff,U+218-21b,U+237,U+1e80-1e85,U+1ef2-1ef3,U+2113"
1118
- }
1119
- },
1120
- { uri: Excalifont_Regular_b9dcf9d2e50a1eaf42fc664b50a3fd0d_default, descriptors: { unicodeRange: "U+400-45f,U+490-491,U+2116" } },
1121
- {
1122
- uri: Excalifont_Regular_41b173a47b57366892116a575a43e2b6_default,
1123
- descriptors: {
1124
- unicodeRange: "U+37e,U+384-38a,U+38c,U+38e-393,U+395-3a1,U+3a3-3a8,U+3aa-3cf,U+3d7"
1125
- }
1126
- },
1127
- {
1128
- uri: Excalifont_Regular_3f2c5db56cc93c5a6873b1361d730c16_default,
1129
- descriptors: {
1130
- unicodeRange: "U+2c7,U+2d8-2d9,U+2db,U+2dd,U+302,U+306-307,U+30a-30c,U+326-328,U+212e,U+2211,U+fb01-fb02"
1131
- }
1132
- },
1133
- {
1134
- uri: Excalifont_Regular_349fac6ca4700ffec595a7150a0d1e1d_default,
1135
- descriptors: {
1136
- unicodeRange: "U+462-463,U+472-475,U+4d8-4d9,U+4e2-4e3,U+4e6-4e9,U+4ee-4ef"
1137
- }
1138
- },
1139
- { uri: Excalifont_Regular_623ccf21b21ef6b3a0d87738f77eb071_default, descriptors: { unicodeRange: "U+300-301,U+303" } }
1140
- ];
642
+ // fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2
643
+ var Xiaolai_Regular_41521fade99856108931b4768b1b2648_default = "./fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2";
1141
644
 
1142
- // fonts/Helvetica/index.ts
1143
- import { LOCAL_FONT_PROTOCOL as LOCAL_FONT_PROTOCOL3 } from "@orangecatai/common";
1144
- var HelveticaFontFaces = [
1145
- {
1146
- uri: LOCAL_FONT_PROTOCOL3
1147
- }
1148
- ];
645
+ // fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2
646
+ var Xiaolai_Regular_544fc28abe2c5c30e62383fd4dac255f_default = "./fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2";
1149
647
 
1150
- // fonts/Liberation/LiberationSans-Regular.woff2
1151
- var LiberationSans_Regular_default = "./fonts/Liberation/LiberationSans-Regular.woff2";
648
+ // fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2
649
+ var Xiaolai_Regular_60a3089806700d379f11827ee9843b6b_default = "./fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2";
1152
650
 
1153
- // fonts/Liberation/index.ts
1154
- var LiberationFontFaces = [
1155
- {
1156
- uri: LiberationSans_Regular_default
1157
- }
1158
- ];
651
+ // fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2
652
+ var Xiaolai_Regular_7eb9fffd1aa890d07d0f88cc82e6cfe4_default = "./fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2";
1159
653
 
1160
- // fonts/Lilita/index.ts
1161
- import { GOOGLE_FONTS_RANGES } from "@orangecatai/common";
654
+ // fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2
655
+ var Xiaolai_Regular_6fe5c5973cc06f74b2387a631ea36b88_default = "./fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2";
1162
656
 
1163
- // fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2
1164
- var Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYE98RXi4EwSsbg_default = "./fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2";
657
+ // fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2
658
+ var Xiaolai_Regular_a4c34be6d42152e64b0df90bc4607f64_default = "./fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2";
1165
659
 
1166
- // fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2
1167
- var Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYEF8RXi4EwQ_default = "./fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2";
660
+ // fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2
661
+ var Xiaolai_Regular_b96d9226ce77ec94ceca043d712182e6_default = "./fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2";
1168
662
 
1169
- // fonts/Lilita/index.ts
1170
- var LilitaFontFaces = [
1171
- {
1172
- uri: Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYE98RXi4EwSsbg_default,
1173
- descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN_EXT }
1174
- },
1175
- {
1176
- uri: Lilita_Regular_i7dPIFZ9Zz_WBtRtedDbYEF8RXi4EwQ_default,
1177
- descriptors: { unicodeRange: GOOGLE_FONTS_RANGES.LATIN }
1178
- }
1179
- ];
663
+ // fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2
664
+ var Xiaolai_Regular_6ae5b42180ad70b971c91e7eefb8eba2_default = "./fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2";
1180
665
 
1181
- // fonts/Nunito/index.ts
1182
- import { GOOGLE_FONTS_RANGES as GOOGLE_FONTS_RANGES2 } from "@orangecatai/common";
666
+ // fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2
667
+ var Xiaolai_Regular_c69f61a4ab18d0488c8d1fc12e7028e8_default = "./fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2";
1183
668
 
1184
- // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2
1185
- var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2";
1186
-
1187
- // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2
1188
- var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2";
1189
-
1190
- // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2
1191
- var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2";
1192
-
1193
- // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2
1194
- var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2";
1195
-
1196
- // fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2
1197
- var Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5_default = "./fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2";
1198
-
1199
- // fonts/Nunito/index.ts
1200
- var NunitoFontFaces = [
1201
- {
1202
- uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5_default,
1203
- descriptors: {
1204
- unicodeRange: GOOGLE_FONTS_RANGES2.CYRILIC_EXT,
1205
- weight: "500"
1206
- }
1207
- },
1208
- {
1209
- uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5_default,
1210
- descriptors: { unicodeRange: GOOGLE_FONTS_RANGES2.CYRILIC, weight: "500" }
1211
- },
1212
- {
1213
- uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5_default,
1214
- descriptors: {
1215
- unicodeRange: GOOGLE_FONTS_RANGES2.VIETNAMESE,
1216
- weight: "500"
1217
- }
1218
- },
1219
- {
1220
- uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5_default,
1221
- descriptors: { unicodeRange: GOOGLE_FONTS_RANGES2.LATIN_EXT, weight: "500" }
1222
- },
1223
- {
1224
- uri: Nunito_Regular_XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg_default,
1225
- descriptors: { unicodeRange: GOOGLE_FONTS_RANGES2.LATIN, weight: "500" }
1226
- }
1227
- ];
1228
-
1229
- // fonts/Virgil/Virgil-Regular.woff2
1230
- var Virgil_Regular_default = "./fonts/Virgil/Virgil-Regular.woff2";
1231
-
1232
- // fonts/Virgil/index.ts
1233
- var VirgilFontFaces = [
1234
- {
1235
- uri: Virgil_Regular_default
1236
- }
1237
- ];
1238
-
1239
- // fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2
1240
- var Xiaolai_Regular_019d66dcad46dc156b162d267f981c20_default = "./fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2";
1241
-
1242
- // fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2
1243
- var Xiaolai_Regular_04b718e5623574919c8b0dea5f301444_default = "./fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2";
1244
-
1245
- // fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2
1246
- var Xiaolai_Regular_069e77aac84590e2e991d0a0176d34f2_default = "./fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2";
1247
-
1248
- // fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2
1249
- var Xiaolai_Regular_06c77b8c66e51ed6c63ccb502dd8b8af_default = "./fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2";
1250
-
1251
- // fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2
1252
- var Xiaolai_Regular_08e0dc436ad0ad61ba5558db0674d762_default = "./fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2";
1253
-
1254
- // fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2
1255
- var Xiaolai_Regular_093b9ef39a46ceae95a1df18a0a3a326_default = "./fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2";
1256
-
1257
- // fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2
1258
- var Xiaolai_Regular_095c169f3314805276f603a362766abd_default = "./fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2";
1259
-
1260
- // fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2
1261
- var Xiaolai_Regular_09850c4077f3fffe707905872e0e2460_default = "./fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2";
1262
-
1263
- // fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2
1264
- var Xiaolai_Regular_41521fade99856108931b4768b1b2648_default = "./fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2";
1265
-
1266
- // fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2
1267
- var Xiaolai_Regular_544fc28abe2c5c30e62383fd4dac255f_default = "./fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2";
1268
-
1269
- // fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2
1270
- var Xiaolai_Regular_60a3089806700d379f11827ee9843b6b_default = "./fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2";
1271
-
1272
- // fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2
1273
- var Xiaolai_Regular_7eb9fffd1aa890d07d0f88cc82e6cfe4_default = "./fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2";
1274
-
1275
- // fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2
1276
- var Xiaolai_Regular_6fe5c5973cc06f74b2387a631ea36b88_default = "./fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2";
1277
-
1278
- // fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2
1279
- var Xiaolai_Regular_a4c34be6d42152e64b0df90bc4607f64_default = "./fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2";
1280
-
1281
- // fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2
1282
- var Xiaolai_Regular_b96d9226ce77ec94ceca043d712182e6_default = "./fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2";
1283
-
1284
- // fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2
1285
- var Xiaolai_Regular_6ae5b42180ad70b971c91e7eefb8eba2_default = "./fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2";
1286
-
1287
- // fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2
1288
- var Xiaolai_Regular_c69f61a4ab18d0488c8d1fc12e7028e8_default = "./fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2";
1289
-
1290
- // fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2
1291
- var Xiaolai_Regular_cb17fc3db95f6d139afc9d31a8e93293_default = "./fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2";
669
+ // fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2
670
+ var Xiaolai_Regular_cb17fc3db95f6d139afc9d31a8e93293_default = "./fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2";
1292
671
 
1293
672
  // fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2
1294
673
  var Xiaolai_Regular_e3fcf5180fd466c8915c4e8069491054_default = "./fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2";
@@ -3066,64 +2445,617 @@ var _Fonts = class _Fonts {
3066
2445
  if (isTextElement(element)) {
3067
2446
  families.add(element.fontFamily);
3068
2447
  }
3069
- return families;
3070
- }, /* @__PURE__ */ new Set())
3071
- );
3072
- }
3073
- /**
3074
- * Get all the unique characters per font family for the given scene.
3075
- */
3076
- static getCharsPerFamily(elements) {
3077
- const charsPerFamily = {};
3078
- for (const element of elements) {
3079
- if (!isTextElement(element)) {
3080
- continue;
3081
- }
3082
- for (const char of element.originalText) {
3083
- if (!charsPerFamily[element.fontFamily]) {
3084
- charsPerFamily[element.fontFamily] = /* @__PURE__ */ new Set();
2448
+ return families;
2449
+ }, /* @__PURE__ */ new Set())
2450
+ );
2451
+ }
2452
+ /**
2453
+ * Get all the unique characters per font family for the given scene.
2454
+ */
2455
+ static getCharsPerFamily(elements) {
2456
+ const charsPerFamily = {};
2457
+ for (const element of elements) {
2458
+ if (!isTextElement(element)) {
2459
+ continue;
2460
+ }
2461
+ for (const char of element.originalText) {
2462
+ if (!charsPerFamily[element.fontFamily]) {
2463
+ charsPerFamily[element.fontFamily] = /* @__PURE__ */ new Set();
2464
+ }
2465
+ charsPerFamily[element.fontFamily].add(char);
2466
+ }
2467
+ }
2468
+ return charsPerFamily;
2469
+ }
2470
+ /**
2471
+ * Get characters for a given family.
2472
+ */
2473
+ static getCharacters(charsPerFamily, family) {
2474
+ return charsPerFamily[family] ? Array.from(charsPerFamily[family]).join("") : "";
2475
+ }
2476
+ /**
2477
+ * Get all registered font families.
2478
+ */
2479
+ static getAllFamilies() {
2480
+ return Array.from(_Fonts.registered.keys());
2481
+ }
2482
+ };
2483
+ // it's ok to track fonts across multiple instances only once, so let's use
2484
+ // a static member to reduce memory footprint
2485
+ __publicField(_Fonts, "loadedFontsCache", /* @__PURE__ */ new Set());
2486
+ __publicField(_Fonts, "_registered");
2487
+ __publicField(_Fonts, "_initialized", false);
2488
+ // Subscribers notified when a new custom font is registered so that
2489
+ // components (FontPickerList) can re-render via useSyncExternalStore.
2490
+ __publicField(_Fonts, "_customFontVersion", 0);
2491
+ __publicField(_Fonts, "_subscribers", /* @__PURE__ */ new Set());
2492
+ __publicField(_Fonts, "subscribeToCustomFonts", (callback) => {
2493
+ _Fonts._subscribers.add(callback);
2494
+ return () => _Fonts._subscribers.delete(callback);
2495
+ });
2496
+ __publicField(_Fonts, "getCustomFontVersion", () => _Fonts._customFontVersion);
2497
+ /**
2498
+ * Load font faces for passed elements - use when the scene is unavailable (i.e. export).
2499
+ */
2500
+ __publicField(_Fonts, "loadElementsFonts", async (elements) => {
2501
+ const fontFamilies = _Fonts.getUniqueFamilies(elements);
2502
+ const charsPerFamily = _Fonts.getCharsPerFamily(elements);
2503
+ return _Fonts.loadFontFaces(fontFamilies, charsPerFamily);
2504
+ });
2505
+ var Fonts = _Fonts;
2506
+
2507
+ // data/encode.ts
2508
+ import { deflate, inflate } from "pako";
2509
+
2510
+ // data/encryption.ts
2511
+ import { ENCRYPTION_KEY_BITS } from "@orangecatai/common";
2512
+
2513
+ // data/blob.ts
2514
+ import { nanoid } from "nanoid";
2515
+ import {
2516
+ IMAGE_MIME_TYPES,
2517
+ VIDEO_MIME_TYPES,
2518
+ MIME_TYPES as MIME_TYPES6,
2519
+ bytesToHexString,
2520
+ isPromiseLike
2521
+ } from "@orangecatai/common";
2522
+
2523
+ // appState.ts
2524
+ import {
2525
+ COLOR_PALETTE,
2526
+ ARROW_TYPE,
2527
+ DEFAULT_ELEMENT_PROPS,
2528
+ DEFAULT_FONT_FAMILY,
2529
+ DEFAULT_FONT_SIZE,
2530
+ DEFAULT_TEXT_ALIGN,
2531
+ DEFAULT_GRID_SIZE,
2532
+ EXPORT_SCALES,
2533
+ STATS_PANELS,
2534
+ THEME,
2535
+ DEFAULT_GRID_STEP
2536
+ } from "@orangecatai/common";
2537
+ var defaultExportScale = EXPORT_SCALES.includes(devicePixelRatio) ? devicePixelRatio : 1;
2538
+ var getDefaultAppState = () => {
2539
+ return {
2540
+ showWelcomeScreen: false,
2541
+ theme: THEME.LIGHT,
2542
+ collaborators: /* @__PURE__ */ new Map(),
2543
+ currentChartType: "bar",
2544
+ currentItemBackgroundColor: COLOR_PALETTE.blue[1],
2545
+ currentItemEndArrowhead: "arrow",
2546
+ currentItemFillStyle: DEFAULT_ELEMENT_PROPS.fillStyle,
2547
+ currentItemFontFamily: DEFAULT_FONT_FAMILY,
2548
+ currentItemFontSize: DEFAULT_FONT_SIZE,
2549
+ currentItemOpacity: DEFAULT_ELEMENT_PROPS.opacity,
2550
+ currentItemRoughness: DEFAULT_ELEMENT_PROPS.roughness,
2551
+ currentItemStartArrowhead: null,
2552
+ currentItemStrokeColor: DEFAULT_ELEMENT_PROPS.strokeColor,
2553
+ currentItemRoundness: "sharp",
2554
+ currentItemArrowType: ARROW_TYPE.round,
2555
+ currentItemStrokeStyle: DEFAULT_ELEMENT_PROPS.strokeStyle,
2556
+ currentItemStrokeWidth: DEFAULT_ELEMENT_PROPS.strokeWidth,
2557
+ currentItemTextAlign: DEFAULT_TEXT_ALIGN,
2558
+ currentHoveredFontFamily: null,
2559
+ cursorButton: "up",
2560
+ activeEmbeddable: null,
2561
+ newElement: null,
2562
+ editingTextElement: null,
2563
+ editingGroupId: null,
2564
+ activeTool: {
2565
+ type: "selection",
2566
+ customType: null,
2567
+ locked: DEFAULT_ELEMENT_PROPS.locked,
2568
+ fromSelection: false,
2569
+ lastActiveTool: null
2570
+ },
2571
+ preferredSelectionTool: {
2572
+ type: "selection",
2573
+ initialized: false
2574
+ },
2575
+ penMode: false,
2576
+ penDetected: false,
2577
+ errorMessage: null,
2578
+ exportBackground: true,
2579
+ exportScale: defaultExportScale,
2580
+ exportEmbedScene: false,
2581
+ exportWithDarkMode: false,
2582
+ fileHandle: null,
2583
+ gridSize: DEFAULT_GRID_SIZE,
2584
+ gridStep: DEFAULT_GRID_STEP,
2585
+ gridModeEnabled: false,
2586
+ isBindingEnabled: true,
2587
+ defaultSidebarDockedPreference: false,
2588
+ isLoading: false,
2589
+ isResizing: false,
2590
+ isRotating: false,
2591
+ lastPointerDownWith: "mouse",
2592
+ multiElement: null,
2593
+ name: null,
2594
+ contextMenu: null,
2595
+ openMenu: null,
2596
+ openPopup: null,
2597
+ openSidebar: null,
2598
+ openDialog: null,
2599
+ pasteDialog: { shown: false, data: null },
2600
+ previousSelectedElementIds: {},
2601
+ resizingElement: null,
2602
+ scrolledOutside: false,
2603
+ scrollX: 0,
2604
+ scrollY: 0,
2605
+ selectedElementIds: {},
2606
+ hoveredElementIds: {},
2607
+ selectedGroupIds: {},
2608
+ selectedElementsAreBeingDragged: false,
2609
+ selectionElement: null,
2610
+ shouldCacheIgnoreZoom: false,
2611
+ stats: {
2612
+ open: false,
2613
+ panels: STATS_PANELS.generalStats | STATS_PANELS.elementProperties
2614
+ },
2615
+ startBoundElement: null,
2616
+ suggestedBinding: null,
2617
+ frameRendering: { enabled: true, clip: true, name: true, outline: true },
2618
+ frameToHighlight: null,
2619
+ editingFrame: null,
2620
+ elementsToHighlight: null,
2621
+ toast: null,
2622
+ viewBackgroundColor: COLOR_PALETTE.white,
2623
+ zenModeEnabled: false,
2624
+ zoom: {
2625
+ value: 1
2626
+ },
2627
+ viewModeEnabled: false,
2628
+ showHyperlinkPopup: false,
2629
+ selectedLinearElement: null,
2630
+ snapLines: [],
2631
+ originSnapOffset: {
2632
+ x: 0,
2633
+ y: 0
2634
+ },
2635
+ objectsSnapModeEnabled: false,
2636
+ userToFollow: null,
2637
+ followedBy: /* @__PURE__ */ new Set(),
2638
+ isCropping: false,
2639
+ croppingElementId: null,
2640
+ searchMatches: null,
2641
+ lockedMultiSelections: {},
2642
+ activeLockedId: null,
2643
+ bindMode: "orbit"
2644
+ };
2645
+ };
2646
+ var APP_STATE_STORAGE_CONF = /* @__PURE__ */ ((config) => config)({
2647
+ showWelcomeScreen: { browser: true, export: false, server: false },
2648
+ theme: { browser: true, export: false, server: false },
2649
+ collaborators: { browser: false, export: false, server: false },
2650
+ currentChartType: { browser: true, export: false, server: false },
2651
+ currentItemBackgroundColor: { browser: true, export: false, server: false },
2652
+ currentItemEndArrowhead: { browser: true, export: false, server: false },
2653
+ currentItemFillStyle: { browser: true, export: false, server: false },
2654
+ currentItemFontFamily: { browser: true, export: false, server: false },
2655
+ currentItemFontSize: { browser: true, export: false, server: false },
2656
+ currentItemRoundness: {
2657
+ browser: true,
2658
+ export: false,
2659
+ server: false
2660
+ },
2661
+ currentItemArrowType: {
2662
+ browser: true,
2663
+ export: false,
2664
+ server: false
2665
+ },
2666
+ currentItemOpacity: { browser: true, export: false, server: false },
2667
+ currentItemRoughness: { browser: true, export: false, server: false },
2668
+ currentItemStartArrowhead: { browser: true, export: false, server: false },
2669
+ currentItemStrokeColor: { browser: true, export: false, server: false },
2670
+ currentItemStrokeStyle: { browser: true, export: false, server: false },
2671
+ currentItemStrokeWidth: { browser: true, export: false, server: false },
2672
+ currentItemTextAlign: { browser: true, export: false, server: false },
2673
+ currentHoveredFontFamily: { browser: false, export: false, server: false },
2674
+ cursorButton: { browser: true, export: false, server: false },
2675
+ activeEmbeddable: { browser: false, export: false, server: false },
2676
+ newElement: { browser: false, export: false, server: false },
2677
+ editingTextElement: { browser: false, export: false, server: false },
2678
+ editingGroupId: { browser: true, export: false, server: false },
2679
+ activeTool: { browser: true, export: false, server: false },
2680
+ preferredSelectionTool: { browser: true, export: false, server: false },
2681
+ penMode: { browser: true, export: false, server: false },
2682
+ penDetected: { browser: true, export: false, server: false },
2683
+ errorMessage: { browser: false, export: false, server: false },
2684
+ exportBackground: { browser: true, export: false, server: false },
2685
+ exportEmbedScene: { browser: true, export: false, server: false },
2686
+ exportScale: { browser: true, export: false, server: false },
2687
+ exportWithDarkMode: { browser: true, export: false, server: false },
2688
+ fileHandle: { browser: false, export: false, server: false },
2689
+ gridSize: { browser: true, export: true, server: true },
2690
+ gridStep: { browser: true, export: true, server: true },
2691
+ gridModeEnabled: { browser: true, export: true, server: true },
2692
+ height: { browser: false, export: false, server: false },
2693
+ isBindingEnabled: { browser: false, export: false, server: false },
2694
+ defaultSidebarDockedPreference: {
2695
+ browser: true,
2696
+ export: false,
2697
+ server: false
2698
+ },
2699
+ isLoading: { browser: false, export: false, server: false },
2700
+ isResizing: { browser: false, export: false, server: false },
2701
+ isRotating: { browser: false, export: false, server: false },
2702
+ lastPointerDownWith: { browser: true, export: false, server: false },
2703
+ multiElement: { browser: false, export: false, server: false },
2704
+ name: { browser: true, export: false, server: false },
2705
+ offsetLeft: { browser: false, export: false, server: false },
2706
+ offsetTop: { browser: false, export: false, server: false },
2707
+ contextMenu: { browser: false, export: false, server: false },
2708
+ openMenu: { browser: true, export: false, server: false },
2709
+ openPopup: { browser: false, export: false, server: false },
2710
+ openSidebar: { browser: true, export: false, server: false },
2711
+ openDialog: { browser: false, export: false, server: false },
2712
+ pasteDialog: { browser: false, export: false, server: false },
2713
+ previousSelectedElementIds: { browser: true, export: false, server: false },
2714
+ resizingElement: { browser: false, export: false, server: false },
2715
+ scrolledOutside: { browser: true, export: false, server: false },
2716
+ scrollX: { browser: true, export: false, server: false },
2717
+ scrollY: { browser: true, export: false, server: false },
2718
+ selectedElementIds: { browser: true, export: false, server: false },
2719
+ hoveredElementIds: { browser: false, export: false, server: false },
2720
+ selectedGroupIds: { browser: true, export: false, server: false },
2721
+ selectedElementsAreBeingDragged: {
2722
+ browser: false,
2723
+ export: false,
2724
+ server: false
2725
+ },
2726
+ selectionElement: { browser: false, export: false, server: false },
2727
+ shouldCacheIgnoreZoom: { browser: true, export: false, server: false },
2728
+ stats: { browser: true, export: false, server: false },
2729
+ startBoundElement: { browser: false, export: false, server: false },
2730
+ suggestedBinding: { browser: false, export: false, server: false },
2731
+ frameRendering: { browser: false, export: false, server: false },
2732
+ frameToHighlight: { browser: false, export: false, server: false },
2733
+ editingFrame: { browser: false, export: false, server: false },
2734
+ elementsToHighlight: { browser: false, export: false, server: false },
2735
+ toast: { browser: false, export: false, server: false },
2736
+ viewBackgroundColor: { browser: true, export: true, server: true },
2737
+ width: { browser: false, export: false, server: false },
2738
+ zenModeEnabled: { browser: true, export: false, server: false },
2739
+ zoom: { browser: true, export: false, server: false },
2740
+ viewModeEnabled: { browser: false, export: false, server: false },
2741
+ showHyperlinkPopup: { browser: false, export: false, server: false },
2742
+ selectedLinearElement: { browser: true, export: false, server: false },
2743
+ snapLines: { browser: false, export: false, server: false },
2744
+ originSnapOffset: { browser: false, export: false, server: false },
2745
+ objectsSnapModeEnabled: { browser: true, export: false, server: false },
2746
+ userToFollow: { browser: false, export: false, server: false },
2747
+ followedBy: { browser: false, export: false, server: false },
2748
+ isCropping: { browser: false, export: false, server: false },
2749
+ croppingElementId: { browser: false, export: false, server: false },
2750
+ searchMatches: { browser: false, export: false, server: false },
2751
+ lockedMultiSelections: { browser: true, export: true, server: true },
2752
+ activeLockedId: { browser: false, export: false, server: false },
2753
+ bindMode: { browser: true, export: false, server: false }
2754
+ });
2755
+ var _clearAppStateForStorage = (appState, exportType) => {
2756
+ const stateForExport = {};
2757
+ for (const key of Object.keys(appState)) {
2758
+ const propConfig = APP_STATE_STORAGE_CONF[key];
2759
+ if (propConfig?.[exportType]) {
2760
+ const nextValue = appState[key];
2761
+ stateForExport[key] = nextValue;
2762
+ }
2763
+ }
2764
+ return stateForExport;
2765
+ };
2766
+ var cleanAppStateForExport = (appState) => {
2767
+ return _clearAppStateForStorage(appState, "export");
2768
+ };
2769
+ var clearAppStateForDatabase = (appState) => {
2770
+ return _clearAppStateForStorage(appState, "server");
2771
+ };
2772
+ var isEraserActive = ({
2773
+ activeTool
2774
+ }) => activeTool.type === "eraser";
2775
+ var isHandToolActive = ({
2776
+ activeTool
2777
+ }) => {
2778
+ return activeTool.type === "hand";
2779
+ };
2780
+
2781
+ // scene/index.ts
2782
+ import {
2783
+ isSomeElementSelected,
2784
+ getElementsWithinSelection,
2785
+ getSelectedElements,
2786
+ getTargetElements
2787
+ } from "@orangecatai/element";
2788
+
2789
+ // scene/scroll.ts
2790
+ import { getVisibleElements } from "@orangecatai/element";
2791
+ import {
2792
+ sceneCoordsToViewportCoords,
2793
+ viewportCoordsToSceneCoords
2794
+ } from "@orangecatai/common";
2795
+ import { getClosestElementBounds } from "@orangecatai/element";
2796
+ import { getCommonBounds } from "@orangecatai/element";
2797
+ var isOutsideViewPort = (appState, cords) => {
2798
+ const [x1, y1, x2, y2] = cords;
2799
+ const { x: viewportX1, y: viewportY1 } = sceneCoordsToViewportCoords(
2800
+ { sceneX: x1, sceneY: y1 },
2801
+ appState
2802
+ );
2803
+ const { x: viewportX2, y: viewportY2 } = sceneCoordsToViewportCoords(
2804
+ { sceneX: x2, sceneY: y2 },
2805
+ appState
2806
+ );
2807
+ return viewportX2 - viewportX1 > appState.width || viewportY2 - viewportY1 > appState.height;
2808
+ };
2809
+ var centerScrollOn = ({
2810
+ scenePoint,
2811
+ viewportDimensions,
2812
+ zoom,
2813
+ offsets
2814
+ }) => {
2815
+ let scrollX = (viewportDimensions.width - (offsets?.right ?? 0)) / 2 / zoom.value - scenePoint.x;
2816
+ scrollX += (offsets?.left ?? 0) / 2 / zoom.value;
2817
+ let scrollY = (viewportDimensions.height - (offsets?.bottom ?? 0)) / 2 / zoom.value - scenePoint.y;
2818
+ scrollY += (offsets?.top ?? 0) / 2 / zoom.value;
2819
+ return {
2820
+ scrollX,
2821
+ scrollY
2822
+ };
2823
+ };
2824
+ var calculateScrollCenter = (elements, appState) => {
2825
+ elements = getVisibleElements(elements);
2826
+ if (!elements.length) {
2827
+ return {
2828
+ scrollX: 0,
2829
+ scrollY: 0
2830
+ };
2831
+ }
2832
+ let [x1, y1, x2, y2] = getCommonBounds(elements);
2833
+ if (isOutsideViewPort(appState, [x1, y1, x2, y2])) {
2834
+ [x1, y1, x2, y2] = getClosestElementBounds(
2835
+ elements,
2836
+ viewportCoordsToSceneCoords(
2837
+ { clientX: appState.scrollX, clientY: appState.scrollY },
2838
+ appState
2839
+ )
2840
+ );
2841
+ }
2842
+ const centerX = (x1 + x2) / 2;
2843
+ const centerY = (y1 + y2) / 2;
2844
+ return centerScrollOn({
2845
+ scenePoint: { x: centerX, y: centerY },
2846
+ viewportDimensions: { width: appState.width, height: appState.height },
2847
+ zoom: appState.zoom
2848
+ });
2849
+ };
2850
+
2851
+ // scene/index.ts
2852
+ import {
2853
+ hasBackground,
2854
+ hasStrokeWidth,
2855
+ hasStrokeStyle,
2856
+ canHaveArrowheads,
2857
+ canChangeRoundness
2858
+ } from "@orangecatai/element";
2859
+
2860
+ // scene/normalize.ts
2861
+ import { MAX_ZOOM, MIN_ZOOM } from "@orangecatai/common";
2862
+ import { clamp, round } from "@orangecatai/math";
2863
+ var getNormalizedZoom = (zoom) => {
2864
+ return clamp(round(zoom, 6), MIN_ZOOM, MAX_ZOOM);
2865
+ };
2866
+ var getNormalizedGridSize = (gridStep) => {
2867
+ return clamp(Math.round(gridStep), 1, 100);
2868
+ };
2869
+ var getNormalizedGridStep = (gridStep) => {
2870
+ return clamp(Math.round(gridStep), 1, 100);
2871
+ };
2872
+
2873
+ // scene/export.ts
2874
+ import rough from "roughjs/bin/rough";
2875
+ import {
2876
+ DEFAULT_EXPORT_PADDING,
2877
+ FRAME_STYLE as FRAME_STYLE3,
2878
+ FONT_FAMILY as FONT_FAMILY2,
2879
+ SVG_NS as SVG_NS2,
2880
+ THEME as THEME5,
2881
+ MIME_TYPES as MIME_TYPES5,
2882
+ EXPORT_DATA_TYPES as EXPORT_DATA_TYPES2,
2883
+ arrayToMap,
2884
+ distance,
2885
+ getFontString as getFontString2,
2886
+ toBrandedType,
2887
+ applyDarkModeFilter as applyDarkModeFilter4
2888
+ } from "@orangecatai/common";
2889
+ import {
2890
+ getCommonBounds as getCommonBounds2,
2891
+ getElementAbsoluteCoords as getElementAbsoluteCoords4
2892
+ } from "@orangecatai/element";
2893
+ import {
2894
+ getInitializedImageElements,
2895
+ updateImageCache
2896
+ } from "@orangecatai/element";
2897
+ import { newElementWith } from "@orangecatai/element";
2898
+ import { isFrameLikeElement } from "@orangecatai/element";
2899
+ import {
2900
+ getElementsOverlappingFrame,
2901
+ getFrameLikeElements,
2902
+ getFrameLikeTitle,
2903
+ getRootElements
2904
+ } from "@orangecatai/element";
2905
+ import { syncInvalidIndices } from "@orangecatai/element";
2906
+ import { newTextElement } from "@orangecatai/element";
2907
+
2908
+ // data/json.ts
2909
+ import {
2910
+ DEFAULT_FILENAME,
2911
+ EXPORT_DATA_TYPES,
2912
+ getExportSource,
2913
+ MIME_TYPES as MIME_TYPES2,
2914
+ VERSIONS
2915
+ } from "@orangecatai/common";
2916
+
2917
+ // data/filesystem.ts
2918
+ import {
2919
+ fileOpen as _fileOpen,
2920
+ fileSave as _fileSave,
2921
+ supported as nativeFileSystemSupported
2922
+ } from "browser-fs-access";
2923
+ import { EVENT, MIME_TYPES, debounce as debounce2 } from "@orangecatai/common";
2924
+ var INPUT_CHANGE_INTERVAL_MS = 5e3;
2925
+ var fileOpen = async (opts) => {
2926
+ const mimeTypes = opts.extensions?.reduce((mimeTypes2, type) => {
2927
+ mimeTypes2.push(MIME_TYPES[type]);
2928
+ return mimeTypes2;
2929
+ }, []);
2930
+ const extensions = opts.extensions?.reduce((acc, ext) => {
2931
+ if (ext === "jpg") {
2932
+ return acc.concat(".jpg", ".jpeg");
2933
+ }
2934
+ return acc.concat(`.${ext}`);
2935
+ }, []);
2936
+ const files = await _fileOpen({
2937
+ description: opts.description,
2938
+ extensions,
2939
+ mimeTypes,
2940
+ multiple: opts.multiple ?? false,
2941
+ legacySetup: (resolve, reject, input) => {
2942
+ const scheduleRejection = debounce2(reject, INPUT_CHANGE_INTERVAL_MS);
2943
+ const focusHandler = () => {
2944
+ checkForFile();
2945
+ document.addEventListener(EVENT.KEYUP, scheduleRejection);
2946
+ document.addEventListener(EVENT.POINTER_UP, scheduleRejection);
2947
+ scheduleRejection();
2948
+ };
2949
+ const checkForFile = () => {
2950
+ if (input.files?.length) {
2951
+ const ret = opts.multiple ? [...input.files] : input.files[0];
2952
+ resolve(ret);
2953
+ }
2954
+ };
2955
+ requestAnimationFrame(() => {
2956
+ window.addEventListener(EVENT.FOCUS, focusHandler);
2957
+ });
2958
+ const interval = window.setInterval(() => {
2959
+ checkForFile();
2960
+ }, INPUT_CHANGE_INTERVAL_MS);
2961
+ return (rejectPromise) => {
2962
+ clearInterval(interval);
2963
+ scheduleRejection.cancel();
2964
+ window.removeEventListener(EVENT.FOCUS, focusHandler);
2965
+ document.removeEventListener(EVENT.KEYUP, scheduleRejection);
2966
+ document.removeEventListener(EVENT.POINTER_UP, scheduleRejection);
2967
+ if (rejectPromise) {
2968
+ console.warn("Opening the file was canceled (legacy-fs).");
2969
+ rejectPromise(new AbortError());
3085
2970
  }
3086
- charsPerFamily[element.fontFamily].add(char);
3087
- }
2971
+ };
3088
2972
  }
3089
- return charsPerFamily;
3090
- }
3091
- /**
3092
- * Get characters for a given family.
3093
- */
3094
- static getCharacters(charsPerFamily, family) {
3095
- return charsPerFamily[family] ? Array.from(charsPerFamily[family]).join("") : "";
2973
+ });
2974
+ if (Array.isArray(files)) {
2975
+ return await Promise.all(
2976
+ files.map((file) => normalizeFile(file))
2977
+ );
3096
2978
  }
3097
- /**
3098
- * Get all registered font families.
3099
- */
3100
- static getAllFamilies() {
3101
- return Array.from(_Fonts.registered.keys());
2979
+ return await normalizeFile(files);
2980
+ };
2981
+ var fileSave = (blob, opts) => {
2982
+ return _fileSave(
2983
+ blob,
2984
+ {
2985
+ fileName: `${opts.name}.${opts.extension}`,
2986
+ description: opts.description,
2987
+ extensions: [`.${opts.extension}`],
2988
+ mimeTypes: opts.mimeTypes
2989
+ },
2990
+ opts.fileHandle
2991
+ );
2992
+ };
2993
+
2994
+ // data/json.ts
2995
+ var filterOutDeletedFiles = (elements, files) => {
2996
+ const nextFiles = {};
2997
+ for (const element of elements) {
2998
+ if (!element.isDeleted && "fileId" in element && element.fileId && files[element.fileId]) {
2999
+ nextFiles[element.fileId] = files[element.fileId];
3000
+ }
3102
3001
  }
3002
+ return nextFiles;
3003
+ };
3004
+ var serializeAsJSON = (elements, appState, files, type) => {
3005
+ const data = {
3006
+ type: EXPORT_DATA_TYPES.excalidraw,
3007
+ version: VERSIONS.excalidraw,
3008
+ source: getExportSource(),
3009
+ elements,
3010
+ appState: type === "local" ? cleanAppStateForExport(appState) : clearAppStateForDatabase(appState),
3011
+ files: type === "local" ? filterOutDeletedFiles(elements, files) : (
3012
+ // will be stripped from JSON
3013
+ void 0
3014
+ )
3015
+ };
3016
+ return JSON.stringify(data, null, 2);
3017
+ };
3018
+ var saveAsJSON = async (elements, appState, files, name = appState.name || DEFAULT_FILENAME) => {
3019
+ const serialized = serializeAsJSON(elements, appState, files, "local");
3020
+ const blob = new Blob([serialized], {
3021
+ type: MIME_TYPES2.excalidraw
3022
+ });
3023
+ const fileHandle = await fileSave(blob, {
3024
+ name,
3025
+ extension: "excalidraw",
3026
+ description: "Excalidraw file",
3027
+ fileHandle: isImageFileHandle(appState.fileHandle) ? null : appState.fileHandle
3028
+ });
3029
+ return { fileHandle };
3030
+ };
3031
+ var isValidExcalidrawData = (data) => {
3032
+ return data?.type === EXPORT_DATA_TYPES.excalidraw && (!data.elements || Array.isArray(data.elements) && (!data.appState || typeof data.appState === "object"));
3033
+ };
3034
+ var isValidLibrary = (json) => {
3035
+ return typeof json === "object" && json && json.type === EXPORT_DATA_TYPES.excalidrawLibrary && (json.version === 1 || json.version === 2);
3036
+ };
3037
+ var serializeLibraryAsJSON = (libraryItems) => {
3038
+ const data = {
3039
+ type: EXPORT_DATA_TYPES.excalidrawLibrary,
3040
+ version: VERSIONS.excalidrawLibrary,
3041
+ source: getExportSource(),
3042
+ libraryItems
3043
+ };
3044
+ return JSON.stringify(data, null, 2);
3045
+ };
3046
+ var saveLibraryAsJSON = async (libraryItems) => {
3047
+ const serialized = serializeLibraryAsJSON(libraryItems);
3048
+ await fileSave(
3049
+ new Blob([serialized], {
3050
+ type: MIME_TYPES2.excalidrawlib
3051
+ }),
3052
+ {
3053
+ name: "library",
3054
+ extension: "excalidrawlib",
3055
+ description: "Excalidraw library file"
3056
+ }
3057
+ );
3103
3058
  };
3104
- // it's ok to track fonts across multiple instances only once, so let's use
3105
- // a static member to reduce memory footprint
3106
- __publicField(_Fonts, "loadedFontsCache", /* @__PURE__ */ new Set());
3107
- __publicField(_Fonts, "_registered");
3108
- __publicField(_Fonts, "_initialized", false);
3109
- // Subscribers notified when a new custom font is registered so that
3110
- // components (FontPickerList) can re-render via useSyncExternalStore.
3111
- __publicField(_Fonts, "_customFontVersion", 0);
3112
- __publicField(_Fonts, "_subscribers", /* @__PURE__ */ new Set());
3113
- __publicField(_Fonts, "subscribeToCustomFonts", (callback) => {
3114
- _Fonts._subscribers.add(callback);
3115
- return () => _Fonts._subscribers.delete(callback);
3116
- });
3117
- __publicField(_Fonts, "getCustomFontVersion", () => _Fonts._customFontVersion);
3118
- /**
3119
- * Load font faces for passed elements - use when the scene is unavailable (i.e. export).
3120
- */
3121
- __publicField(_Fonts, "loadElementsFonts", async (elements) => {
3122
- const fontFamilies = _Fonts.getUniqueFamilies(elements);
3123
- const charsPerFamily = _Fonts.getCharsPerFamily(elements);
3124
- return _Fonts.loadFontFaces(fontFamilies, charsPerFamily);
3125
- });
3126
- var Fonts = _Fonts;
3127
3059
 
3128
3060
  // renderer/staticScene.ts
3129
3061
  import {
@@ -3625,7 +3557,9 @@ import {
3625
3557
  isArrowElement,
3626
3558
  isIframeLikeElement as isIframeLikeElement2,
3627
3559
  isInitializedImageElement,
3628
- isTextElement as isTextElement3
3560
+ isTextElement as isTextElement3,
3561
+ layoutTextElement,
3562
+ hasStyleRanges
3629
3563
  } from "@orangecatai/element";
3630
3564
  import { getContainingFrame, orderFramesToBack as orderFramesToBack2 } from "@orangecatai/element";
3631
3565
  import { getCornerRadius, isPathALoop } from "@orangecatai/element";
@@ -4099,22 +4033,109 @@ var renderElementToSvg = (element, elementsMap, rsvg, svgRoot, files, offsetX, o
4099
4033
  );
4100
4034
  const direction = isRTL(element.text) ? "rtl" : "ltr";
4101
4035
  const textAnchor = element.textAlign === "center" ? "middle" : element.textAlign === "right" || direction === "rtl" ? "end" : "start";
4102
- for (let i = 0; i < lines.length; i++) {
4103
- const text = svgRoot.ownerDocument.createElementNS(SVG_NS, "text");
4104
- text.textContent = lines[i];
4105
- text.setAttribute("x", `${horizontalOffset}`);
4106
- text.setAttribute("y", `${i * lineHeightPx + verticalOffset}`);
4107
- text.setAttribute("font-family", getFontFamilyString(element));
4108
- text.setAttribute("font-size", `${element.fontSize}px`);
4109
- text.setAttribute(
4110
- "fill",
4111
- renderConfig.theme === THEME4.DARK ? applyDarkModeFilter3(element.strokeColor) : element.strokeColor
4112
- );
4113
- text.setAttribute("text-anchor", textAnchor);
4114
- text.setAttribute("style", "white-space: pre;");
4115
- text.setAttribute("direction", direction);
4116
- text.setAttribute("dominant-baseline", "alphabetic");
4117
- node.appendChild(text);
4036
+ const resolveColor = (color) => renderConfig.theme === THEME4.DARK ? applyDarkModeFilter3(color) : color;
4037
+ if (hasStyleRanges(element)) {
4038
+ const layout = layoutTextElement(element);
4039
+ const svgRect = (x, y, width, height, fill) => {
4040
+ const rect = svgRoot.ownerDocument.createElementNS(SVG_NS, "rect");
4041
+ rect.setAttribute("x", `${x}`);
4042
+ rect.setAttribute("y", `${y}`);
4043
+ rect.setAttribute("width", `${width}`);
4044
+ rect.setAttribute("height", `${height}`);
4045
+ rect.setAttribute("fill", fill);
4046
+ return rect;
4047
+ };
4048
+ const decorations = [];
4049
+ for (const line of layout.lines) {
4050
+ const lineStartX = element.textAlign === "center" ? (element.width - line.width) / 2 : element.textAlign === "right" ? element.width - line.width : 0;
4051
+ const baselineY = line.y + line.baseline;
4052
+ for (const segment of line.segments) {
4053
+ if (segment.style.highlight) {
4054
+ node.appendChild(
4055
+ svgRect(
4056
+ lineStartX + segment.x,
4057
+ line.y,
4058
+ segment.width,
4059
+ line.height,
4060
+ resolveColor(segment.style.highlight)
4061
+ )
4062
+ );
4063
+ }
4064
+ }
4065
+ const text = svgRoot.ownerDocument.createElementNS(SVG_NS, "text");
4066
+ text.setAttribute("x", `${lineStartX}`);
4067
+ text.setAttribute("y", `${baselineY}`);
4068
+ text.setAttribute("text-anchor", "start");
4069
+ text.setAttribute("style", "white-space: pre;");
4070
+ text.setAttribute("direction", direction);
4071
+ text.setAttribute("dominant-baseline", "alphabetic");
4072
+ for (const segment of line.segments) {
4073
+ const x = lineStartX + segment.x;
4074
+ const tspan = svgRoot.ownerDocument.createElementNS(
4075
+ SVG_NS,
4076
+ "tspan"
4077
+ );
4078
+ tspan.textContent = segment.text;
4079
+ tspan.setAttribute("x", `${x}`);
4080
+ tspan.setAttribute("y", `${baselineY}`);
4081
+ tspan.setAttribute(
4082
+ "font-family",
4083
+ getFontFamilyString({ fontFamily: segment.style.fontFamily })
4084
+ );
4085
+ tspan.setAttribute("font-size", `${segment.style.fontSize}px`);
4086
+ tspan.setAttribute("fill", resolveColor(segment.style.color));
4087
+ if (segment.style.bold) {
4088
+ tspan.setAttribute("font-weight", "bold");
4089
+ }
4090
+ if (segment.style.italic) {
4091
+ tspan.setAttribute("font-style", "italic");
4092
+ }
4093
+ text.appendChild(tspan);
4094
+ const { fontSize } = segment.style;
4095
+ const thickness = Math.max(1, fontSize / 16);
4096
+ if (segment.style.underline) {
4097
+ decorations.push(
4098
+ svgRect(
4099
+ x,
4100
+ baselineY + fontSize * 0.12,
4101
+ segment.width,
4102
+ thickness,
4103
+ resolveColor(segment.style.color)
4104
+ )
4105
+ );
4106
+ }
4107
+ if (segment.style.strikethrough) {
4108
+ decorations.push(
4109
+ svgRect(
4110
+ x,
4111
+ baselineY - fontSize * 0.28,
4112
+ segment.width,
4113
+ thickness,
4114
+ resolveColor(segment.style.color)
4115
+ )
4116
+ );
4117
+ }
4118
+ }
4119
+ node.appendChild(text);
4120
+ }
4121
+ for (const decoration of decorations) {
4122
+ node.appendChild(decoration);
4123
+ }
4124
+ } else {
4125
+ for (let i = 0; i < lines.length; i++) {
4126
+ const text = svgRoot.ownerDocument.createElementNS(SVG_NS, "text");
4127
+ text.textContent = lines[i];
4128
+ text.setAttribute("x", `${horizontalOffset}`);
4129
+ text.setAttribute("y", `${i * lineHeightPx + verticalOffset}`);
4130
+ text.setAttribute("font-family", getFontFamilyString(element));
4131
+ text.setAttribute("font-size", `${element.fontSize}px`);
4132
+ text.setAttribute("fill", resolveColor(element.strokeColor));
4133
+ text.setAttribute("text-anchor", textAnchor);
4134
+ text.setAttribute("style", "white-space: pre;");
4135
+ text.setAttribute("direction", direction);
4136
+ text.setAttribute("dominant-baseline", "alphabetic");
4137
+ node.appendChild(text);
4138
+ }
4118
4139
  }
4119
4140
  const g = maybeWrapNodesInFrameClipPath(
4120
4141
  element,
@@ -4574,6 +4595,7 @@ import {
4574
4595
  } from "@orangecatai/element";
4575
4596
  import { syncInvalidIndices as syncInvalidIndices2 } from "@orangecatai/element";
4576
4597
  import { refreshTextDimensions } from "@orangecatai/element";
4598
+ import { normalizeStyleRanges } from "@orangecatai/element";
4577
4599
  import { getNormalizedDimensions } from "@orangecatai/element";
4578
4600
  import { isInvisiblySmallElement } from "@orangecatai/element";
4579
4601
  var AllowedExcalidrawActiveTools = {
@@ -4755,7 +4777,17 @@ var restoreElement = (element, targetElementsMap, existingElementsMap, opts) =>
4755
4777
  containerId: element.containerId ?? null,
4756
4778
  originalText: element.originalText || text,
4757
4779
  autoResize: element.autoResize ?? true,
4758
- lineHeight
4780
+ lineHeight,
4781
+ // per-range styles are indexed against `originalText`; normalizing
4782
+ // clamps them to it and drops anything malformed. The key is left off
4783
+ // entirely for uniformly styled text.
4784
+ ...(() => {
4785
+ const styleRanges = normalizeStyleRanges(
4786
+ element.styleRanges,
4787
+ (element.originalText || text).length
4788
+ );
4789
+ return styleRanges ? { styleRanges } : {};
4790
+ })()
4759
4791
  });
4760
4792
  if (opts?.deleteInvisibleElements && !text && !element.isDeleted) {
4761
4793
  element = { ...element, originalText: text, isDeleted: true };
@@ -5154,7 +5186,7 @@ var parseFileContents = async (blob) => {
5154
5186
  let contents;
5155
5187
  if (blob.type === MIME_TYPES6.png) {
5156
5188
  try {
5157
- return await (await import("./data/image-PUPXCX7M.js")).decodePngMetadata(blob);
5189
+ return await (await import("./data/image-MTDE3WXB.js")).decodePngMetadata(blob);
5158
5190
  } catch (error) {
5159
5191
  if (error.message === "INVALID") {
5160
5192
  throw new ImageSceneDataError(
@@ -5489,50 +5521,66 @@ var blobToArrayBuffer = (blob) => {
5489
5521
  });
5490
5522
  };
5491
5523
 
5492
- // data/image.ts
5493
- var getTEXtChunk = async (blob) => {
5494
- const chunks = decodePng(new Uint8Array(await blobToArrayBuffer(blob)));
5495
- const metadataChunk = chunks.find((chunk) => chunk.name === "tEXt");
5496
- if (metadataChunk) {
5497
- return tEXt.decode(metadataChunk.data);
5524
+ // data/encode.ts
5525
+ var toByteString = (data) => {
5526
+ const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data);
5527
+ let bstring = "";
5528
+ for (const byte of bytes) {
5529
+ bstring += String.fromCharCode(byte);
5498
5530
  }
5499
- return null;
5531
+ return bstring;
5500
5532
  };
5501
- var encodePngMetadata = async ({
5502
- blob,
5503
- metadata
5504
- }) => {
5505
- const chunks = decodePng(new Uint8Array(await blobToArrayBuffer(blob)));
5506
- const metadataChunk = tEXt.encode(
5507
- MIME_TYPES7.excalidraw,
5508
- JSON.stringify(
5509
- encode({
5510
- text: metadata,
5511
- compress: true
5512
- })
5513
- )
5514
- );
5515
- chunks.splice(-1, 0, metadataChunk);
5516
- return new Blob([encodePng(chunks)], { type: MIME_TYPES7.png });
5533
+ var byteStringToArrayBuffer = (byteString) => {
5534
+ const buffer = new ArrayBuffer(byteString.length);
5535
+ const bufferView = new Uint8Array(buffer);
5536
+ for (let i = 0, len = byteString.length; i < len; i++) {
5537
+ bufferView[i] = byteString.charCodeAt(i);
5538
+ }
5539
+ return buffer;
5540
+ };
5541
+ var byteStringToString = (byteString) => {
5542
+ return new TextDecoder("utf-8").decode(byteStringToArrayBuffer(byteString));
5543
+ };
5544
+ var stringToBase64 = (str, isByteString = false) => {
5545
+ return isByteString ? window.btoa(str) : window.btoa(toByteString(str));
5546
+ };
5547
+ var base64ToString = (base64, isByteString = false) => {
5548
+ return isByteString ? window.atob(base64) : byteStringToString(window.atob(base64));
5517
5549
  };
5518
- var decodePngMetadata = async (blob) => {
5519
- const metadata = await getTEXtChunk(blob);
5520
- if (metadata?.keyword === MIME_TYPES7.excalidraw) {
5550
+ var encode = ({
5551
+ text,
5552
+ compress
5553
+ }) => {
5554
+ let deflated;
5555
+ if (compress !== false) {
5521
5556
  try {
5522
- const encodedData = JSON.parse(metadata.text);
5523
- if (!("encoded" in encodedData)) {
5524
- if ("type" in encodedData && encodedData.type === EXPORT_DATA_TYPES3.excalidraw) {
5525
- return metadata.text;
5526
- }
5527
- throw new Error("FAILED");
5528
- }
5529
- return decode(encodedData);
5557
+ deflated = toByteString(deflate(text));
5530
5558
  } catch (error) {
5531
- console.error(error);
5532
- throw new Error("FAILED");
5559
+ console.error("encode: cannot deflate", error);
5533
5560
  }
5534
5561
  }
5535
- throw new Error("INVALID");
5562
+ return {
5563
+ version: "1",
5564
+ encoding: "bstring",
5565
+ compressed: !!deflated,
5566
+ encoded: deflated || toByteString(text)
5567
+ };
5568
+ };
5569
+ var decode = (data) => {
5570
+ let decoded;
5571
+ switch (data.encoding) {
5572
+ case "bstring":
5573
+ decoded = data.compressed ? data.encoded : byteStringToString(data.encoded);
5574
+ break;
5575
+ default:
5576
+ throw new Error(`decode: unknown encoding "${data.encoding}"`);
5577
+ }
5578
+ if (data.compressed) {
5579
+ return inflate(new Uint8Array(byteStringToArrayBuffer(decoded)), {
5580
+ to: "string"
5581
+ });
5582
+ }
5583
+ return decoded;
5536
5584
  };
5537
5585
 
5538
5586
  export {
@@ -5557,6 +5605,8 @@ export {
5557
5605
  getDefaultAppState,
5558
5606
  isEraserActive,
5559
5607
  isHandToolActive,
5608
+ encode,
5609
+ decode,
5560
5610
  nativeFileSystemSupported,
5561
5611
  fileOpen,
5562
5612
  fileSave,
@@ -5580,9 +5630,6 @@ export {
5580
5630
  restoreElements,
5581
5631
  restoreAppState,
5582
5632
  restoreLibraryItems,
5583
- getTEXtChunk,
5584
- encodePngMetadata,
5585
- decodePngMetadata,
5586
5633
  getFileHandleType,
5587
5634
  isImageFileHandleType,
5588
5635
  isImageFileHandle,
@@ -5604,6 +5651,7 @@ export {
5604
5651
  ImageURLToFile,
5605
5652
  getFileHandle,
5606
5653
  createFile,
5607
- normalizeFile
5654
+ normalizeFile,
5655
+ blobToArrayBuffer
5608
5656
  };
5609
- //# sourceMappingURL=chunk-5XP2WJAQ.js.map
5657
+ //# sourceMappingURL=chunk-7XZBXIDZ.js.map