@netless/fastboard-core 0.2.11 → 0.3.0-canary.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.
package/dist/index.mjs CHANGED
@@ -1,24 +1,589 @@
1
- import {
2
- DefaultApps,
3
- createFastboard,
4
- registerApps,
5
- replayFastboard
6
- } from "./chunk-IHDHV4XE.mjs";
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+
33
+ // src/utils/store.ts
34
+ function noop() {
35
+ }
36
+ function safe_not_equal(a, b) {
37
+ return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function";
38
+ }
39
+ function readable(value, start = noop) {
40
+ let stop;
41
+ const subscribers = /* @__PURE__ */ new Set();
42
+ function set(new_value) {
43
+ if (safe_not_equal(value, new_value)) {
44
+ value = new_value;
45
+ if (stop) {
46
+ for (const run of subscribers) {
47
+ run(value);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ function subscribe(run) {
53
+ subscribers.add(run);
54
+ if (subscribers.size === 1) {
55
+ stop = start(set) || noop;
56
+ }
57
+ run(value);
58
+ return () => {
59
+ subscribers.delete(run);
60
+ if (subscribers.size === 0) {
61
+ stop && stop();
62
+ stop = void 0;
63
+ }
64
+ };
65
+ }
66
+ function reaction(run) {
67
+ subscribers.add(run);
68
+ if (subscribers.size === 1) {
69
+ stop = start(set) || noop;
70
+ }
71
+ return () => {
72
+ subscribers.delete(run);
73
+ if (subscribers.size === 0) {
74
+ stop && stop();
75
+ stop = void 0;
76
+ }
77
+ };
78
+ }
79
+ return {
80
+ get value() {
81
+ return value;
82
+ },
83
+ subscribe,
84
+ reaction
85
+ };
86
+ }
87
+ function writable(value, start = noop, set) {
88
+ const internal = readable(value, start);
89
+ return {
90
+ get value() {
91
+ return internal.value;
92
+ },
93
+ subscribe: internal.subscribe,
94
+ reaction: internal.reaction,
95
+ set,
96
+ update(fn) {
97
+ set(fn(value));
98
+ }
99
+ };
100
+ }
101
+
102
+ // src/utils/misc.ts
103
+ function getImageSize(url, fallback) {
104
+ return new Promise((resolve) => {
105
+ const img = new Image();
106
+ img.onload = () => resolve(img);
107
+ img.onerror = () => resolve(fallback);
108
+ img.src = url;
109
+ });
110
+ }
111
+ function makeSlideParams(scenes) {
112
+ const emptyScenes = [];
113
+ let taskId = "";
114
+ let url = "";
115
+ const pptSrcRE = /^pptx?(?<prefix>:\/\/\S+?dynamicConvert)\/(?<taskId>\w+)\//;
116
+ for (const { name, ppt } of scenes) {
117
+ emptyScenes.push({ name });
118
+ if (!ppt || !ppt.src.startsWith("ppt")) {
119
+ continue;
120
+ }
121
+ const match = pptSrcRE.exec(ppt.src);
122
+ if (!match || !match.groups) {
123
+ continue;
124
+ }
125
+ taskId = match.groups.taskId;
126
+ url = "https" + match.groups.prefix;
127
+ break;
128
+ }
129
+ return { scenes: emptyScenes, taskId, url };
130
+ }
131
+ function convertedFileToScene(f, i) {
132
+ return {
133
+ name: String(i + 1),
134
+ ppt: {
135
+ src: f.conversionFileUrl,
136
+ width: f.width,
137
+ height: f.height,
138
+ previewURL: f.preview
139
+ }
140
+ };
141
+ }
142
+
143
+ // src/utils/uid.ts
144
+ var SOUP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
145
+ var SOUP_LEN = 62;
146
+ var ID_LEN = 20;
147
+ var reusedIdCarrier = /* @__PURE__ */ Array(ID_LEN);
148
+ function genUID() {
149
+ for (let i = 0; i < ID_LEN; i++) {
150
+ reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);
151
+ }
152
+ return reusedIdCarrier.join("");
153
+ }
7
154
 
8
- // src/behaviors/register-slide.ts
155
+ // src/utils/warn.ts
156
+ var warnings = {
157
+ "no-ppt-in-scenes": "You're probably inserting the slide app in a wrong way, there shouldn't exist `scenes[0].ppt`."
158
+ };
159
+ var warned = /* @__PURE__ */ new Set();
160
+ function warn(id) {
161
+ if (warned.has(id))
162
+ return;
163
+ warned.add(id);
164
+ console.warn(warnings[id]);
165
+ }
166
+
167
+ // src/impl/FastboardApp.ts
168
+ import { DefaultHotKeys, WhiteWebSdk, contentModeScale } from "white-web-sdk";
169
+ import { BuiltinApps, WindowManager as WindowManager2 } from "@netless/window-manager";
170
+
171
+ // src/internal.ts
9
172
  import { WindowManager } from "@netless/window-manager";
173
+ function ensure_window_manager(joinRoom) {
174
+ if (!joinRoom.invisiblePlugins || !joinRoom.invisiblePlugins.includes(WindowManager)) {
175
+ joinRoom.invisiblePlugins = [...joinRoom.invisiblePlugins || [], WindowManager];
176
+ }
177
+ return joinRoom;
178
+ }
179
+ function transform_app_status(status) {
180
+ return status === "start" ? "loading" : status === "failed" ? "failed" : "idle";
181
+ }
182
+
183
+ // src/impl/FastboardApp.ts
184
+ var FastboardAppBase = class {
185
+ constructor(sdk, room, manager, hotKeys) {
186
+ this.sdk = sdk;
187
+ this.room = room;
188
+ this.manager = manager;
189
+ this.hotKeys = hotKeys;
190
+ this._destroyed = false;
191
+ }
192
+ _assertNotDestroyed() {
193
+ if (this._destroyed) {
194
+ throw new Error("FastboardApp has been destroyed");
195
+ }
196
+ }
197
+ _addRoomListener(name, listener) {
198
+ this._assertNotDestroyed();
199
+ this.room.callbacks.on(name, listener);
200
+ return () => this.room.callbacks.off(name, listener);
201
+ }
202
+ _addManagerListener(name, listener) {
203
+ this._assertNotDestroyed();
204
+ this.manager.emitter.on(name, listener);
205
+ return () => this.manager.emitter.off(name, listener);
206
+ }
207
+ _addMainViewListener(name, listener) {
208
+ this._assertNotDestroyed();
209
+ this.manager.mainView.callbacks.on(name, listener);
210
+ return () => this.manager.mainView.callbacks.off(name, listener);
211
+ }
212
+ destroy() {
213
+ this._destroyed = true;
214
+ this.manager.destroy();
215
+ return this.room.disconnect();
216
+ }
217
+ };
218
+ var FastboardApp = class extends FastboardAppBase {
219
+ constructor() {
220
+ super(...arguments);
221
+ this.writable = writable(this.room.isWritable, (set) => this._addRoomListener("onEnableWriteNowChanged", () => set(this.room.isWritable)), this.room.setWritable.bind(this.room));
222
+ this.boxState = readable(this.manager.boxState, (set) => this._addManagerListener("boxStateChange", set));
223
+ this.focusedApp = readable(this.manager.focused, (set) => this._addManagerListener("focusedChange", set));
224
+ this.canRedoSteps = readable(this.manager.canRedoSteps, (set) => this._addManagerListener("canRedoStepsChange", set));
225
+ this.canUndoSteps = readable(this.manager.canUndoSteps, (set) => this._addManagerListener("canUndoStepsChange", set));
226
+ this.camera = readable(this.manager.mainView.camera, (set) => this._addMainViewListener("onCameraUpdated", set));
227
+ this.memberState = readable(this.room.state.memberState, (set) => this._addRoomListener("onRoomStateChanged", ({ memberState: m }) => m && set(m)));
228
+ this.sceneIndex = writable(this.manager.mainViewSceneIndex, (set) => this._addManagerListener("mainViewSceneIndexChange", set), this.manager.setMainViewSceneIndex.bind(this.manager));
229
+ this.sceneLength = readable(this.manager.mainViewScenesLength, (set) => this._addManagerListener("mainViewScenesLengthChange", set));
230
+ this._appsStatus = {};
231
+ this.appsStatus = readable({}, (set) => this._addManagerListener("loadApp", ({ kind, status, reason }) => {
232
+ this._appsStatus[kind] = { status: transform_app_status(status), reason };
233
+ set(this._appsStatus);
234
+ }));
235
+ }
236
+ bindContainer(container) {
237
+ this._assertNotDestroyed();
238
+ this.manager.bindContainer(container);
239
+ }
240
+ bindCollector(container) {
241
+ this._assertNotDestroyed();
242
+ this.manager.bindCollectorContainer(container);
243
+ }
244
+ undo() {
245
+ this._assertNotDestroyed();
246
+ this.manager.undo();
247
+ }
248
+ redo() {
249
+ this._assertNotDestroyed();
250
+ this.manager.redo();
251
+ }
252
+ moveCamera(camera) {
253
+ this._assertNotDestroyed();
254
+ this.manager.moveCamera(camera);
255
+ }
256
+ moveCameraToContain(rectangle) {
257
+ this._assertNotDestroyed();
258
+ this.manager.moveCameraToContain(rectangle);
259
+ }
260
+ cleanCurrentScene() {
261
+ this._assertNotDestroyed();
262
+ this.manager.cleanCurrentScene();
263
+ }
264
+ setAppliance(appliance, shape) {
265
+ this._assertNotDestroyed();
266
+ this.manager.mainView.setMemberState({
267
+ currentApplianceName: appliance,
268
+ shapeType: shape
269
+ });
270
+ }
271
+ setStrokeWidth(strokeWidth) {
272
+ this._assertNotDestroyed();
273
+ this.manager.mainView.setMemberState({ strokeWidth });
274
+ }
275
+ setStrokeColor(strokeColor) {
276
+ this._assertNotDestroyed();
277
+ this.manager.mainView.setMemberState({ strokeColor });
278
+ }
279
+ prevPage() {
280
+ this._assertNotDestroyed();
281
+ return this.manager.prevPage();
282
+ }
283
+ nextPage() {
284
+ this._assertNotDestroyed();
285
+ return this.manager.nextPage();
286
+ }
287
+ addPage(params) {
288
+ this._assertNotDestroyed();
289
+ return this.manager.addPage(params);
290
+ }
291
+ async insertImage(url) {
292
+ this._assertNotDestroyed();
293
+ await this.manager.switchMainViewToWriter();
294
+ const { divElement } = this.manager.mainView;
295
+ const containerSize = {
296
+ width: (divElement == null ? void 0 : divElement.scrollWidth) || window.innerWidth,
297
+ height: (divElement == null ? void 0 : divElement.scrollHeight) || window.innerHeight
298
+ };
299
+ const maxWidth = containerSize.width * 0.8;
300
+ let { width, height } = await getImageSize(url, containerSize);
301
+ const scale = Math.min(maxWidth / width, 1);
302
+ const uuid = genUID();
303
+ const { centerX, centerY } = this.manager.camera;
304
+ width *= scale;
305
+ height *= scale;
306
+ this.manager.mainView.insertImage({ uuid, centerX, centerY, width, height, locked: false });
307
+ this.manager.mainView.completeImageUpload(uuid, url);
308
+ width /= 0.8;
309
+ height /= 0.8;
310
+ const originX = centerX - width / 2;
311
+ const originY = centerY - height / 2;
312
+ this.manager.moveCameraToContain({ originX, originY, width, height });
313
+ }
314
+ insertDocs(arg1, arg2) {
315
+ this._assertNotDestroyed();
316
+ if (typeof arg1 === "object" && "fileType" in arg1) {
317
+ return this._insertDocsImpl(arg1);
318
+ } else if (arg2 && arg2.status !== "Finished") {
319
+ throw new Error("FastboardApp cannot insert a converting doc.");
320
+ } else if (arg2 && arg2.progress) {
321
+ const title = arg1;
322
+ const scenePath = `/${arg2.uuid}/${genUID()}`;
323
+ const scenes1 = arg2.progress.convertedFileList.map(convertedFileToScene);
324
+ const { scenes, taskId, url } = makeSlideParams(scenes1);
325
+ if (taskId && url) {
326
+ return this._insertDocsImpl({ fileType: "pptx", scenePath, scenes, title, taskId, url });
327
+ } else {
328
+ return this._insertDocsImpl({ fileType: "pdf", scenePath, scenes: scenes1, title });
329
+ }
330
+ }
331
+ }
332
+ _insertDocsImpl(_a) {
333
+ var _b = _a, { fileType, scenePath, title, scenes } = _b, attributes = __objRest(_b, ["fileType", "scenePath", "title", "scenes"]);
334
+ this._assertNotDestroyed();
335
+ switch (fileType) {
336
+ case "pdf":
337
+ return this.manager.addApp({
338
+ kind: "DocsViewer",
339
+ options: { scenePath, title, scenes }
340
+ });
341
+ case "pptx":
342
+ if (scenes && scenes[0].ppt) {
343
+ warn("no-ppt-in-scenes");
344
+ }
345
+ return this.manager.addApp({
346
+ kind: "Slide",
347
+ options: { scenePath, title, scenes },
348
+ attributes
349
+ });
350
+ }
351
+ }
352
+ insertCodeEditor() {
353
+ this._assertNotDestroyed();
354
+ return this.manager.addApp({
355
+ kind: "Monaco",
356
+ options: { title: "Code Editor" }
357
+ });
358
+ }
359
+ insertCountdown() {
360
+ this._assertNotDestroyed();
361
+ return this.manager.addApp({
362
+ kind: "Countdown",
363
+ options: { title: "Countdown" }
364
+ });
365
+ }
366
+ insertMedia(title, src) {
367
+ this._assertNotDestroyed();
368
+ return this.manager.addApp({
369
+ kind: BuiltinApps.MediaPlayer,
370
+ options: { title },
371
+ attributes: { src }
372
+ });
373
+ }
374
+ insertGeoGebra() {
375
+ this._assertNotDestroyed();
376
+ return this.manager.addApp({
377
+ kind: "GeoGebra",
378
+ options: { title: "GeoGebra" }
379
+ });
380
+ }
381
+ };
382
+ async function createFastboard(_a) {
383
+ var _b = _a, {
384
+ sdkConfig,
385
+ joinRoom: _c
386
+ } = _b, _d = _c, { callbacks } = _d, joinRoomParams = __objRest(_d, ["callbacks"]), {
387
+ managerConfig
388
+ } = _b;
389
+ const sdk = new WhiteWebSdk(__spreadProps(__spreadValues({}, sdkConfig), {
390
+ useMobXState: true
391
+ }));
392
+ const hotKeys = __spreadProps(__spreadValues({}, DefaultHotKeys), {
393
+ changeToSelector: "s",
394
+ changeToLaserPointer: "z",
395
+ changeToPencil: "p",
396
+ changeToRectangle: "r",
397
+ changeToEllipse: "c",
398
+ changeToEraser: "e",
399
+ changeToText: "t",
400
+ changeToStraight: "l",
401
+ changeToArrow: "a",
402
+ changeToHand: "h"
403
+ });
404
+ const room = await sdk.joinRoom(__spreadProps(__spreadValues({
405
+ floatBar: true,
406
+ hotKeys
407
+ }, ensure_window_manager(joinRoomParams)), {
408
+ useMultiViews: true,
409
+ disableNewPencil: false,
410
+ disableMagixEventDispatchLimit: true
411
+ }), callbacks);
412
+ const manager = await WindowManager2.mount(__spreadProps(__spreadValues({
413
+ cursor: true
414
+ }, managerConfig), {
415
+ room
416
+ }));
417
+ manager.mainView.setCameraBound({
418
+ minContentMode: contentModeScale(0.3),
419
+ maxContentMode: contentModeScale(3)
420
+ });
421
+ return new FastboardApp(sdk, room, manager, hotKeys);
422
+ }
423
+
424
+ // src/impl/FastboardPlayer.ts
425
+ import { WhiteWebSdk as WhiteWebSdk2 } from "white-web-sdk";
426
+ import { WindowManager as WindowManager3 } from "@netless/window-manager";
427
+ var FastboardPlayerBase = class {
428
+ constructor(sdk, player, manager) {
429
+ this.sdk = sdk;
430
+ this.player = player;
431
+ this.manager = manager;
432
+ this._destroyed = false;
433
+ }
434
+ _assertNotDestroyed() {
435
+ if (this._destroyed) {
436
+ throw new Error("FastboardApp has been destroyed");
437
+ }
438
+ }
439
+ _addPlayerListener(name, listener) {
440
+ this._assertNotDestroyed();
441
+ this.player.callbacks.on(name, listener);
442
+ return () => this.player.callbacks.off(name, listener);
443
+ }
444
+ _addManagerListener(name, listener) {
445
+ this._assertNotDestroyed();
446
+ this.manager.emitter.on(name, listener);
447
+ return () => this.manager.emitter.off(name, listener);
448
+ }
449
+ _addMainViewListener(name, listener) {
450
+ this._assertNotDestroyed();
451
+ this.manager.mainView.callbacks.on(name, listener);
452
+ return () => this.manager.mainView.callbacks.off(name, listener);
453
+ }
454
+ destroy() {
455
+ this._destroyed = true;
456
+ this.manager.destroy();
457
+ return this.player.callbacks.off();
458
+ }
459
+ };
460
+ var FastboardPlayer = class extends FastboardPlayerBase {
461
+ constructor() {
462
+ super(...arguments);
463
+ this.currentTime = writable(this.player.progressTime, (set) => this._addPlayerListener("onProgressTimeChanged", set), this.player.seekToProgressTime.bind(this.player));
464
+ this.phase = readable(this.player.phase, (set) => this._addPlayerListener("onPhaseChanged", set));
465
+ this.canplay = readable(this.player.isPlayable, (set) => this._addPlayerListener("onIsPlayableChanged", set));
466
+ this.speed = writable(this.player.playbackSpeed, (set) => {
467
+ this._setSpeed = set;
468
+ }, (value) => {
469
+ this.player.playbackSpeed = value;
470
+ this._setSpeed(value);
471
+ });
472
+ this.ready = readable(false, (set) => {
473
+ this._setReady = set;
474
+ });
475
+ this.duration = readable(0, (set) => {
476
+ this._setDuration = set;
477
+ });
478
+ this.state = readable(null, (set) => {
479
+ const update = () => set(this.player.state);
480
+ this.player.callbacks.once("onLoadFirstFrame", () => {
481
+ this._setDuration(this.player.timeDuration);
482
+ this._setReady(true);
483
+ update();
484
+ });
485
+ return this._addPlayerListener("onPlayerStateChanged", update);
486
+ });
487
+ }
488
+ bindContainer(container) {
489
+ this._assertNotDestroyed();
490
+ this.manager.bindContainer(container);
491
+ }
492
+ bindCollector(container) {
493
+ this._assertNotDestroyed();
494
+ this.manager.bindCollectorContainer(container);
495
+ }
496
+ seek(timestamp) {
497
+ this._assertNotDestroyed();
498
+ return this.player.seekToProgressTime(timestamp);
499
+ }
500
+ play() {
501
+ this._assertNotDestroyed();
502
+ this.player.play();
503
+ }
504
+ pause() {
505
+ this._assertNotDestroyed();
506
+ this.player.pause();
507
+ }
508
+ stop() {
509
+ this._assertNotDestroyed();
510
+ this.player.stop();
511
+ }
512
+ setSpeed(value) {
513
+ this._assertNotDestroyed();
514
+ this.speed.set(value);
515
+ }
516
+ };
517
+ async function replayFastboard(_a) {
518
+ var _b = _a, {
519
+ sdkConfig,
520
+ replayRoom: _c
521
+ } = _b, _d = _c, { callbacks } = _d, replayRoomParams = __objRest(_d, ["callbacks"]), {
522
+ managerConfig
523
+ } = _b;
524
+ const sdk = new WhiteWebSdk2(__spreadProps(__spreadValues({}, sdkConfig), {
525
+ useMobXState: true
526
+ }));
527
+ const player = await sdk.replayRoom(__spreadProps(__spreadValues({}, ensure_window_manager(replayRoomParams)), {
528
+ useMultiViews: true
529
+ }), callbacks);
530
+ const managerPromise = WindowManager3.mount(__spreadProps(__spreadValues({
531
+ cursor: true
532
+ }, managerConfig), {
533
+ room: player
534
+ }));
535
+ player.play();
536
+ const manager = await managerPromise;
537
+ player.pause();
538
+ return new FastboardPlayer(sdk, player, manager);
539
+ }
540
+
541
+ // src/behaviors/index.ts
542
+ import { WindowManager as WindowManager4 } from "@netless/window-manager";
10
543
  import AppSlide from "@netless/app-slide";
11
- WindowManager.register({
12
- kind: "Slide",
13
- appOptions: {
14
- debug: false
544
+ var DefaultApps = {
545
+ Monaco: {
546
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-monaco/0.1.12/dist/main.iife.js"
15
547
  },
548
+ Countdown: {
549
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-countdown/0.0.2/dist/main.iife.js"
550
+ },
551
+ GeoGebra: {
552
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-geogebra/0.0.4/dist/main.iife.js",
553
+ appOptions: {
554
+ HTML5Codebase: "https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d"
555
+ }
556
+ },
557
+ EmbeddedPage: {
558
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-embedded-page/0.1.1/dist/main.iife.js"
559
+ },
560
+ Player: {
561
+ name: "NetlessAppMediaPlayer",
562
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-media-player/0.1.1/dist/main.iife.js"
563
+ }
564
+ };
565
+ WindowManager4.register({
566
+ kind: "Slide",
567
+ appOptions: { debug: false },
16
568
  src: AppSlide
17
569
  });
570
+ for (const kind in DefaultApps) {
571
+ if (Object.prototype.hasOwnProperty.call(DefaultApps, kind)) {
572
+ const options = DefaultApps[kind];
573
+ WindowManager4.register(__spreadValues({ kind }, options));
574
+ }
575
+ }
18
576
  export {
19
- DefaultApps,
577
+ FastboardApp,
578
+ FastboardPlayer,
579
+ convertedFileToScene,
20
580
  createFastboard,
21
- registerApps,
22
- replayFastboard
581
+ genUID,
582
+ getImageSize,
583
+ makeSlideParams,
584
+ readable,
585
+ replayFastboard,
586
+ warn,
587
+ writable
23
588
  };
24
589
  //# sourceMappingURL=index.mjs.map