@netless/fastboard 0.0.1 → 0.0.5

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 (43) hide show
  1. package/README.md +8 -10
  2. package/dist/index.cjs.js +4 -4
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +478 -168
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/svelte.cjs.js +2 -0
  7. package/dist/svelte.cjs.js.map +1 -0
  8. package/dist/svelte.es.js +31 -0
  9. package/dist/svelte.es.js.map +1 -0
  10. package/dist/vue.cjs.js +2 -0
  11. package/dist/vue.cjs.js.map +1 -0
  12. package/dist/vue.es.js +42 -0
  13. package/dist/vue.es.js.map +1 -0
  14. package/package.json +25 -41
  15. package/src/WhiteboardApp.ts +39 -3
  16. package/src/behaviors/style.ts +1 -1
  17. package/src/components/PlayerControl/PlayerControl.scss +145 -0
  18. package/src/components/PlayerControl/PlayerControl.tsx +158 -0
  19. package/src/components/PlayerControl/components/Button.tsx +55 -0
  20. package/src/components/PlayerControl/hooks.ts +95 -0
  21. package/src/components/PlayerControl/icons/Loading.tsx +13 -0
  22. package/src/components/PlayerControl/icons/Pause.tsx +13 -0
  23. package/src/components/PlayerControl/icons/Play.tsx +13 -0
  24. package/src/components/PlayerControl/icons/index.ts +10 -0
  25. package/src/components/PlayerControl/index.ts +1 -0
  26. package/src/components/Root.tsx +1 -2
  27. package/src/components/Toolbar/Content.tsx +28 -15
  28. package/src/components/Toolbar/components/ColorBox.tsx +3 -3
  29. package/src/components/Toolbar/components/UpDownButtons.tsx +7 -10
  30. package/src/components/Toolbar/hooks.ts +1 -1
  31. package/src/components/ZoomControl.tsx +1 -1
  32. package/src/hooks.ts +18 -60
  33. package/src/i18n/en.json +2 -1
  34. package/src/i18n/zh-CN.json +2 -1
  35. package/src/index.ts +9 -2
  36. package/src/internal/Instance.tsx +40 -19
  37. package/src/internal/helpers.ts +15 -0
  38. package/src/internal/index.ts +1 -0
  39. package/src/internal/mount-whiteboard.ts +13 -5
  40. package/src/style.scss +1 -0
  41. package/src/svelte.ts +45 -0
  42. package/src/vue.ts +74 -0
  43. package/src/helpers/index.ts +0 -18
package/dist/index.es.js CHANGED
@@ -17,12 +17,24 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
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
+ };
20
32
  var __publicField = (obj, key, value) => {
21
33
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
34
  return value;
23
35
  };
24
36
  import { WindowManager } from "@netless/window-manager";
25
- import { WhiteWebSdk, DefaultHotKeys, ApplianceNames, ShapeType } from "white-web-sdk";
37
+ import { WhiteWebSdk, DefaultHotKeys, ApplianceNames, ShapeType, PlayerPhase } from "white-web-sdk";
26
38
  import i18next from "i18next";
27
39
  import require$$0, { memo, forwardRef, useContext, useCallback, useState, useEffect, useRef, createContext } from "react";
28
40
  import ReactDOM from "react-dom";
@@ -67,6 +79,9 @@ WindowManager.register({
67
79
  HTML5Codebase: "https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d"
68
80
  }
69
81
  });
82
+ function noop() {
83
+ return;
84
+ }
70
85
  function applyStyles(css) {
71
86
  const el = document.createElement("style");
72
87
  el.appendChild(document.createTextNode(css));
@@ -74,13 +89,34 @@ function applyStyles(css) {
74
89
  return el;
75
90
  }
76
91
  function clamp(value, min, max) {
77
- return Math.min(Math.max(value, min), max);
92
+ return value < min ? min : value > max ? max : value;
78
93
  }
79
94
  function isEqualArray(a, b) {
80
95
  return a.length === b.length && a.every((e, i) => e === b[i]);
81
96
  }
82
- var style = '.netless-window-manager-playground{width:100%;height:100%;position:relative;z-index:1;overflow:hidden;user-select:none}.netless-window-manager-sizer{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;overflow:hidden;display:flex}.netless-window-manager-sizer-horizontal{flex-direction:column}.netless-window-manager-sizer:before,.netless-window-manager-sizer:after{flex:1;content:"";display:block}.netless-window-manager-chess-sizer:before,.netless-window-manager-chess-sizer:after{background-image:linear-gradient(45deg,#b0b0b0 25%,transparent 25%),linear-gradient(-45deg,#b0b0b0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#b0b0b0 75%),linear-gradient(-45deg,transparent 75%,#b0b0b0 75%);background-color:#fff;background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.netless-window-manager-wrapper{position:relative;z-index:1;width:100%;height:100%;overflow:hidden}.netless-window-manager-main-view{width:100%;height:100%}.netless-window-manager-cursor-pencil-image,.netless-window-manager-cursor-eraser-image{width:26px;height:26px}.netless-window-manager-cursor-selector-image{width:24px;height:24px}.netless-window-manager-cursor-selector-avatar{border-radius:50%;border-style:solid;border-width:2px;border-color:#fff;margin-bottom:2px}.netless-window-manager-cursor-selector-avatar img{width:12px}.netless-window-manager-cursor-inner{border-radius:4px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:4px;padding-right:4px;font-size:12px}.netless-window-manager-cursor-inner-mellow{height:32px;border-radius:16px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:16px;padding-right:16px}.netless-window-manager-cursor-tag-name{font-size:12px;margin-left:4px;padding:2px 8px;border-radius:4px}.netless-window-manager-cursor-mid{display:flex;flex-direction:column;align-items:center;justify-content:center;position:fixed;width:26px;height:26px;z-index:2147483647;left:0;top:0;will-change:transform;transition:transform .05s;transform-origin:0 0;user-select:none}.netless-window-manager-cursor-pencil-offset{margin-left:-20px}.netless-window-manager-cursor-selector-offset{margin-left:-22px;margin-top:56px}.netless-window-manager-cursor-text-offset{margin-left:-30px;margin-top:18px}.netless-window-manager-cursor-shape-offset{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:180px;height:64px;margin-left:-30px;margin-top:12px}.netless-window-manager-cursor-name{width:100%;height:48px;display:flex;align-items:center;justify-content:center;position:absolute;top:-40px}.cursor-image-wrapper{display:flex;justify-content:center}.tele-fancy-scrollbar{overscroll-behavior:contain;overflow:auto;overflow-y:scroll;overflow-y:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.tele-fancy-scrollbar::-webkit-scrollbar{height:8px;width:8px}.tele-fancy-scrollbar::-webkit-scrollbar-track{background-color:transparent}.tele-fancy-scrollbar::-webkit-scrollbar-thumb{background-color:#444e601a;background-color:transparent;border-radius:4px;transition:background-color .4s}.tele-fancy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#444e601a}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:active{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:vertical{min-height:50px}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-box{position:absolute;top:0;left:0;z-index:100;will-change:transform;transition:width .4s cubic-bezier(.4,.9,.71,1.02),height .4s cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .4s ease}.telebox-box-main{position:relative;width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#f9f9fc;box-shadow:0 4px 10px #2f419226;border-radius:6px;border:1px solid #e3e3ec}.telebox-titlebar-wrap{flex-shrink:0;position:relative;z-index:1}.telebox-content-wrap{flex:1;width:100%;overflow:hidden;display:flex;justify-content:center;align-items:center}.telebox-content{width:100%;height:100%;position:relative}.telebox-footer-wrap{flex-shrink:0;display:flex;flex-direction:column}.telebox-footer-wrap:before{content:"";display:block;flex:1}.telebox-resize-handle{position:absolute;z-index:2147483647}.telebox-n{width:100%;height:5px;left:0;top:-5px;cursor:n-resize}.telebox-s{width:100%;height:5px;left:0;bottom:-5px;cursor:s-resize}.telebox-w{width:5px;height:100%;left:-5px;top:0;cursor:w-resize}.telebox-e{width:5px;height:100%;right:-5px;top:0;cursor:e-resize}.telebox-nw{width:15px;height:15px;top:-5px;left:-5px;cursor:nw-resize}.telebox-ne{width:15px;height:15px;top:-5px;right:-5px;cursor:ne-resize}.telebox-se{width:15px;height:15px;bottom:-5px;right:-5px;cursor:se-resize}.telebox-sw{width:15px;height:15px;bottom:-5px;left:-5px;cursor:sw-resize}.telebox-track-mask{position:fixed;top:0;left:0;z-index:2147483647;width:100%;height:100%;background:rgba(0,0,0,.0001);cursor:move}.telebox-cursor-n{cursor:n-resize}.telebox-cursor-s{cursor:s-resize}.telebox-cursor-w{cursor:w-resize}.telebox-cursor-e{cursor:e-resize}.telebox-cursor-nw{cursor:nw-resize}.telebox-cursor-ne{cursor:ne-resize}.telebox-cursor-se{cursor:se-resize}.telebox-cursor-sw{cursor:sw-resize}.telebox-maximized .telebox-resize-handles,.telebox-no-resize .telebox-resize-handles{display:none}.telebox-maximized{box-shadow:none;transition:none}.telebox-minimized{will-change:transform;transition:width 50ms cubic-bezier(.4,.9,.71,1.02),height 50ms cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .6s ease;opacity:0;pointer-events:none;user-select:none}.telebox-transforming{will-change:transform;transition:opacity .6s cubic-bezier(.7,0,.84,0)}.telebox-readonly .telebox-resize-handle{cursor:initial!important;pointer-events:none!important}.telebox-color-scheme-dark .telebox-box-main{color:#e9e9e9;background:#212126;border-color:#43434d}.telebox-titlebar{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;background:#fff;user-select:none;border-bottom:1px solid #eeeef7}.telebox-title{overflow:hidden;margin:0 24px 0 0;padding:0;font-size:14px;font-weight:400;font-family:PingFangSC-Regular,PingFang SC;white-space:nowrap;word-break:keep-all;text-overflow:ellipsis;color:#191919}.telebox-titlebar-btns{white-space:nowrap;word-break:keep-all;margin-left:auto;font-size:0}.telebox-titlebar-btn{width:22px;height:22px;padding:0;outline:0;border:none;background:0 0;cursor:pointer}.telebox-titlebar-btn~.telebox-titlebar-btn{margin-left:10px}.telebox-titlebar-btn-icon{width:22px;height:22px}.telebox-readonly .telebox-titlebar-btn{cursor:not-allowed}.telebox-titlebar-icon-minimize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHBhdGggZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBkPSJNOSAxM2gxMHYxLjZIOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-titlebar-icon-maximize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPGcgZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBtYXNrPSJ1cmwoI2IpIj4KICAgICAgICAgICAgPHBhdGgKICAgICAgICAgICAgICAgIGQ9Ik0yMC40ODEgMTcuMWgxLjJ2NC41ODFIMTcuMXYtMS4yaDMuMzgxVjE3LjF6bS0xNC4xOTA1LS4wMDloMS4ydjMuMzgxaDMuMzgwOXYxLjJoLTQuNTgxdi00LjU4MXpNMTcuMSA2LjE5MDVoNC41ODF2NC41ODA5aC0xLjJ2LTMuMzgxSDE3LjF2LTEuMnptLTEwLjcwMDguMTA4N2g0Ljc5ODV2MS4ySDcuNTk5MnYzLjU5ODVoLTEuMlY2LjI5OTJ6IiAvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==)}.telebox-titlebar-icon-maximize.is-active{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjZ2MjZIMHoiIC8+CiAgICAgICAgPHBhdGggaWQ9ImMiIGQ9Ik0yNi44NjkgMEwyOCAxLjEzMVYyNi44N0wyNi44NjkgMjhIMS4xM0wwIDI2Ljg3VjEuMTMxTDEuMTMgMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMSkiPgogICAgICAgICAgICA8bWFzayBpZD0iYiIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNhIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tNC42NDI5LTQuNjQyOWgzNS4yODU4djM1LjI4NThILTQuNjQyOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8bWFzayBpZD0iZCIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNjIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tMTcuNTE2OCAxNEwxNC0xNy41MTY4IDQ1LjUxNjggMTQgMTQgNDUuNTE2OHoiIG1hc2s9InVybCgjZCkiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjIiCiAgICAgICAgICAgIGQ9Ik0xMC4wODg2IDIxLjQ4NjV2LTMuNjk2Nkg2LjM5Mk0yMS4zODU1IDEwLjE4OTVoLTMuNjk2NlY2LjQ5M00yMS40MDIgMTcuNzk4M2gtMy42OTY2djMuNjk2Nk0xMC4yNTAzIDYuMTQ5OHYzLjg5ODVINi4zNTE3IiAvPgogICAgPC9nPgo8L3N2Zz4K)}.telebox-titlebar-icon-close{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCI+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjQiPgogICAgICAgIDxwYXRoIGQ9Ik04LjM1MyAyMC4zMzIxTDIwLjMzMiA4LjM1M00yMC4zMzIyIDIwLjMzMjFMOC4zNTMgOC4zNTMiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-color-scheme-dark .telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-collector{visibility:hidden;display:block;position:absolute;z-index:200;width:40px;height:40px;margin:0;padding:0;border:none;outline:0;font-size:0;border-radius:50%;background:#fff;box-shadow:0 2px 6px #2f419226;cursor:pointer;user-select:none;pointer-events:none;background-repeat:no-repeat;background-size:18px 16px;background-position:center}.telebox-collector-visible{visibility:visible;pointer-events:initial}.telebox-collector-readonly{cursor:not-allowed}.telebox-color-scheme-dark.telebox-collector{background-color:#43434d}.telebox-max-titlebar{display:none;position:absolute;top:0;left:0;z-index:50000;user-select:none}.telebox-max-titlebar-maximized{display:flex}.telebox-titles{flex:1;height:100%;margin:0 16px 0 -16px;overflow-y:hidden;overflow-x:scroll;overflow-x:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.telebox-titles::-webkit-scrollbar{height:8px;width:8px}.telebox-titles::-webkit-scrollbar-track{background-color:transparent}.telebox-titles::-webkit-scrollbar-thumb{background-color:#eeeef7cc;background-color:transparent;border-radius:4px;transition:background-color .4s}.telebox-titles:hover::-webkit-scrollbar-thumb{background-color:#eeeef7cc}.telebox-titles::-webkit-scrollbar-thumb:hover{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:active{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:vertical{min-height:50px}.telebox-titles::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-titles-content{height:100%;display:flex;flex-wrap:nowrap;align-items:center;padding:0}.telebox-titles-tab{overflow:hidden;max-width:182px;min-width:50px;padding:0 26px 0 16px;outline:0;font-size:13px;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all;border:none;border-right:1px solid #e5e5f0;color:#7b88a0;background:0 0;cursor:pointer}.telebox-titles-tab~.telebox-titles-tab{margin-left:2px}.telebox-titles-tab-focus{color:#357bf6}.telebox-readonly .telebox-titles-tab{cursor:not-allowed}.telebox-color-scheme-dark{color-scheme:dark}.telebox-color-scheme-dark.telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-color-scheme-dark .telebox-titles-tab{border-right-color:#7b88a0}.telebox-color-scheme-dark .telebox-title{color:#e9e9e9}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}.tippy-box[data-theme~=light]{color:#26323d;box-shadow:0 0 20px 4px #9aa1b126,0 4px 80px -8px #24282f40,0 4px 4px -2px #5b5e6926;background-color:#fff}.tippy-box[data-theme~=light][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff}.tippy-box[data-theme~=light][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff}.tippy-box[data-theme~=light]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light]>.tippy-svg-arrow{fill:#fff}.rc-slider{position:relative;height:14px;padding:5px 0;width:100%;border-radius:6px;touch-action:none;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-rail{position:absolute;width:100%;background-color:#e9e9e9;height:4px;border-radius:6px}.rc-slider-track{position:absolute;left:0;height:4px;border-radius:6px;background-color:#abe2fb}.rc-slider-handle{position:absolute;width:14px;height:14px;cursor:pointer;cursor:-webkit-grab;margin-top:-5px;cursor:grab;border-radius:50%;border:solid 2px #96dbfa;background-color:#fff;touch-action:pan-x}.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging{border-color:#57c5f7;box-shadow:0 0 0 5px #96dbfa}.rc-slider-handle:focus{outline:none}.rc-slider-handle-click-focused:focus{border-color:#96dbfa;box-shadow:unset}.rc-slider-handle:hover{border-color:#57c5f7}.rc-slider-handle:active{border-color:#57c5f7;box-shadow:0 0 5px #57c5f7;cursor:-webkit-grabbing;cursor:grabbing}.rc-slider-mark{position:absolute;top:18px;left:0;width:100%;font-size:12px}.rc-slider-mark-text{position:absolute;display:inline-block;vertical-align:middle;text-align:center;cursor:pointer;color:#999}.rc-slider-mark-text-active{color:#666}.rc-slider-step{position:absolute;width:100%;height:4px;background:transparent}.rc-slider-dot{position:absolute;bottom:-2px;margin-left:-4px;width:8px;height:8px;border:2px solid #e9e9e9;background-color:#fff;cursor:pointer;border-radius:50%;vertical-align:middle}.rc-slider-dot-active{border-color:#96dbfa}.rc-slider-dot-reverse{margin-right:-4px}.rc-slider-disabled{background-color:#e9e9e9}.rc-slider-disabled .rc-slider-track{background-color:#ccc}.rc-slider-disabled .rc-slider-handle,.rc-slider-disabled .rc-slider-dot{border-color:#ccc;box-shadow:none;background-color:#fff;cursor:not-allowed}.rc-slider-disabled .rc-slider-mark-text,.rc-slider-disabled .rc-slider-dot{cursor:not-allowed!important}.rc-slider-vertical{width:14px;height:100%;padding:0 5px}.rc-slider-vertical .rc-slider-rail{height:100%;width:4px}.rc-slider-vertical .rc-slider-track{left:5px;bottom:0;width:4px}.rc-slider-vertical .rc-slider-handle{margin-left:-5px;touch-action:pan-y}.rc-slider-vertical .rc-slider-mark{top:0;left:18px;height:100%}.rc-slider-vertical .rc-slider-step{height:100%;width:4px}.rc-slider-vertical .rc-slider-dot{left:2px;margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:first-child{margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:last-child{margin-bottom:-4px}.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-appear,.rc-slider-tooltip-zoom-down-leave{animation-duration:.3s;animation-fill-mode:both;display:block!important;animation-play-state:paused}.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active{animation-name:rcSliderTooltipZoomDownIn;animation-play-state:running}.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active{animation-name:rcSliderTooltipZoomDownOut;animation-play-state:running}.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-appear{transform:scale(0);animation-timing-function:cubic-bezier(.23,1,.32,1)}.rc-slider-tooltip-zoom-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes rcSliderTooltipZoomDownIn{0%{opacity:0;transform-origin:50% 100%;transform:scale(0)}to{transform-origin:50% 100%;transform:scale(1)}}@keyframes rcSliderTooltipZoomDownOut{0%{transform-origin:50% 100%;transform:scale(1)}to{opacity:0;transform-origin:50% 100%;transform:scale(0)}}.rc-slider-tooltip{position:absolute;left:-9999px;top:-9999px;visibility:visible;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-tooltip *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-tooltip-hidden{display:none}.rc-slider-tooltip-placement-top{padding:4px 0 8px}.rc-slider-tooltip-inner{padding:6px 2px;min-width:24px;height:24px;font-size:12px;line-height:1;color:#fff;text-align:center;text-decoration:none;background-color:#6c6c6c;border-radius:6px;box-shadow:0 0 4px #d9d9d9}.rc-slider-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow{bottom:4px;left:50%;margin-left:-4px;border-width:4px 4px 0;border-top-color:#6c6c6c}.fastboard-root{position:relative;width:100%;height:100%;overflow:hidden}.fastboard-loading{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;opacity:.6}.fastboard-view{position:absolute;top:0;left:0;width:100%;height:100%}.fastboard-left{position:absolute;top:0;left:0;height:calc(100% - 48px);padding:16px;z-index:201;display:flex;align-items:center}.fastboard-bottom-left,.fastboard-bottom-right{display:flex;gap:10px;position:absolute;bottom:8px;left:8px;padding:8px;z-index:200}.fastboard-bottom-right{left:initial;right:8px}.fastboard-redo-undo{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-redo-undo.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-redo-undo.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-redo-undo-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-redo-undo-btn svg,.fastboard-redo-undo-btn img{width:1em;height:1em}.fastboard-redo-undo-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-redo-undo-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-redo-undo-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-page-control{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-page-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-page-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-page-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-page-control-btn svg,.fastboard-page-control-btn img{width:1em;height:1em}.fastboard-page-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-page-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-page-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-page-control-cut-line{height:24px;width:.5px}.fastboard-page-control-cut-line.light{background-color:#e7e7e7}.fastboard-page-control-cut-line.dark{background-color:#ffffff26}.fastboard-page-control-slash{opacity:.6}.fastboard-page-control-page,.fastboard-page-control-slash,.fastboard-page-control-page-count{font-size:12px;font-variant-numeric:tabular-nums}.fastboard-zoom-control{position:relative;display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-zoom-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-zoom-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-zoom-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-zoom-control-btn svg,.fastboard-zoom-control-btn img{width:1em;height:1em}.fastboard-zoom-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-zoom-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-zoom-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-zoom-control-cut-line{height:24px;width:.5px}.fastboard-zoom-control-cut-line.light{background-color:#e7e7e7}.fastboard-zoom-control-cut-line.dark{background-color:#ffffff26}.fastboard-zoom-control-percent{opacity:.6}.fastboard-zoom-control-scale,.fastboard-zoom-control-percent{font-size:12px;font-variant-numeric:tabular-nums}.fastboard-toolbar{display:flex;align-items:center;padding:4px;border-radius:4px;flex-direction:column;gap:4px;position:absolute;z-index:100;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-toolbar .rc-slider{padding:6px 0}.fastboard-toolbar .rc-slider-rail,.fastboard-toolbar .rc-slider-track{height:2px}.fastboard-toolbar .tippy-content{padding:8px}.fastboard-toolbar .tippy-box{border:1px solid rgba(0,0,0,.15);background-color:#333333f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-toolbar .tippy-box[data-theme~=light]{background-color:#fffffff2;box-shadow:0 5px 10px #00000040}.fastboard-toolbar.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-toolbar.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-toolbar-tooltip{display:inline-flex;align-items:center;gap:4px}.fastboard-toolbar-hotkey{margin-right:-4px;width:24px;height:24px;border-radius:4px;background-color:#ffffff1a;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:4px;width:32px;height:32px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1;position:relative}.fastboard-toolbar-btn-interactive{display:inline-block;width:32px;height:32px}.fastboard-toolbar-btn svg,.fastboard-toolbar-btn img{width:1em;height:1em}.fastboard-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-toolbar-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-toolbar-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-toolbar-triangle{width:0px;height:0px;border-bottom:4px solid;border-left:4px solid transparent;position:absolute;bottom:0;right:0}.fastboard-toolbar-cut-line{display:inline-block;height:.5px;width:100%}.fastboard-toolbar-cut-line.light{background-color:#e7e7e7}.fastboard-toolbar-cut-line.dark{background-color:#ffffff26}.fastboard-toolbar-section{display:inline-flex;flex-flow:column nowrap;gap:4px;scroll-behavior:smooth}.fastboard-toolbar-panel{width:120px;padding:0;display:flex;flex-flow:column nowrap;align-items:center;gap:8px}.fastboard-toolbar-panel.apps{width:224px}.fastboard-toolbar-color-box,.fastboard-toolbar-shapes{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;align-items:center;justify-items:center}.fastboard-toolbar-color-box .fastboard-toolbar-btn,.fastboard-toolbar-shapes .fastboard-toolbar-btn{padding:0;width:24px;height:24px}.fastboard-toolbar-apps{width:100%;display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-items:center;justify-items:center}.fastboard-toolbar-apps .fastboard-toolbar-btn{width:40px;height:40px;font-size:40px}.fastboard-toolbar-app-icon{padding-top:4px;display:inline-flex;flex-flow:column nowrap;align-items:center;gap:4px}.fastboard-toolbar-app-icon .fastboard-toolbar-btn{padding:0}.fastboard-toolbar-app-icon-text{font-size:12px;color:#5d5d5d;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fastboard-toolbar-color-item{width:24px;height:24px;border-radius:4px;cursor:pointer}.fastboard-toolbar-color-item *.light:hover{background-color:#f5f5f5}.fastboard-toolbar-color-item *.dark:hover{background-color:#333}.fastboard-toolbar-color-border{width:24px;height:24px;border:1px solid transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-color-border.active.light,.fastboard-toolbar-color-border.active.dark{border:1px solid rgba(51,129,255,.8)}.fastboard-toolbar-color-btn{margin:0;border:1px solid rgba(0,0,0,.24);padding:0;appearance:none;width:16px;height:16px;border-radius:4px;cursor:pointer}.fastboard-toolbar-color-btn:focus-visible{outline-offset:2px}.tippy-box.fastboard-tip{color:#eee;background-color:#000000f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.tippy-box.fastboard-tip[data-placement^=right]>.tippy-arrow:before{top:4px;border-width:4px;border-right-color:#000}.tippy-box.fastboard-tip[data-placement^=top]>.tippy-arrow:before{left:4px;border-width:4px;border-top-color:#000}\n';
83
- applyStyles(style);
97
+ class Lock {
98
+ constructor() {
99
+ __publicField(this, "running", false);
100
+ __publicField(this, "nextFn", null);
101
+ __publicField(this, "step", () => {
102
+ if (this.nextFn) {
103
+ const fn = this.nextFn;
104
+ this.nextFn = null;
105
+ Promise.resolve(fn()).then(this.step);
106
+ } else {
107
+ this.running = false;
108
+ }
109
+ });
110
+ }
111
+ schedule(fn) {
112
+ if (this.running) {
113
+ this.nextFn = fn;
114
+ } else {
115
+ this.running = true;
116
+ Promise.resolve(fn()).then(this.step);
117
+ }
118
+ }
119
+ }
84
120
  const translation$1 = {
85
121
  clicker: "clicker",
86
122
  selector: "selector",
@@ -107,7 +143,8 @@ const translation$1 = {
107
143
  speechBalloon: "Speech Balloon",
108
144
  rectangle: "Rectangle",
109
145
  ellipse: "Ellipse",
110
- straight: "Straight"
146
+ straight: "Straight",
147
+ speed: "Speed"
111
148
  };
112
149
  var en = {
113
150
  translation: translation$1
@@ -139,7 +176,8 @@ const translation = {
139
176
  speechBalloon: "\u6C14\u7403",
140
177
  rectangle: "\u77E9\u5F62",
141
178
  ellipse: "\u692D\u5706",
142
- straight: "\u76F4\u7EBF"
179
+ straight: "\u76F4\u7EBF",
180
+ speed: "\u901F\u5EA6"
143
181
  };
144
182
  var zhCN = {
145
183
  translation
@@ -181,14 +219,18 @@ async function mountWhiteboard(sdkConfig, joinRoom, managerConfig, language) {
181
219
  useMobXState: true
182
220
  }));
183
221
  ensureWindowManager(joinRoom);
184
- const room = await sdk.joinRoom(__spreadProps(__spreadValues({
222
+ joinRoom = __spreadValues({}, joinRoom);
223
+ const callbacks = joinRoom.callbacks;
224
+ delete joinRoom.callbacks;
225
+ const joinRoomParams = __spreadProps(__spreadValues({
185
226
  floatBar: true,
186
227
  hotKeys: __spreadValues(__spreadValues({}, DefaultHotKeys), defaultHotKeys)
187
228
  }, joinRoom), {
188
229
  useMultiViews: true,
189
230
  disableNewPencil: false,
190
231
  disableMagixEventDispatchLimit: true
191
- }));
232
+ });
233
+ const room = await sdk.joinRoom(joinRoomParams, callbacks);
192
234
  const manager = await WindowManager.mount(__spreadProps(__spreadValues({
193
235
  cursor: true,
194
236
  debug: false
@@ -198,32 +240,6 @@ async function mountWhiteboard(sdkConfig, joinRoom, managerConfig, language) {
198
240
  const i18n = await createI18n({ language });
199
241
  return { sdk, room, manager, i18n };
200
242
  }
201
- function noop() {
202
- return;
203
- }
204
- class Lock {
205
- constructor() {
206
- __publicField(this, "running", false);
207
- __publicField(this, "nextFn", null);
208
- __publicField(this, "step", () => {
209
- if (this.nextFn) {
210
- const fn = this.nextFn;
211
- this.nextFn = null;
212
- Promise.resolve(fn()).then(this.step);
213
- } else {
214
- this.running = false;
215
- }
216
- });
217
- }
218
- schedule(fn) {
219
- if (this.running) {
220
- this.nextFn = fn;
221
- } else {
222
- this.running = true;
223
- Promise.resolve(fn()).then(this.step);
224
- }
225
- }
226
- }
227
243
  var jsxRuntime = { exports: {} };
228
244
  var reactJsxRuntime_production_min = {};
229
245
  /*
@@ -576,7 +592,7 @@ const Up = (props) => {
576
592
  })
577
593
  });
578
594
  };
579
- const Icons = {
595
+ const Icons$1 = {
580
596
  Clicker: memo(Clicker),
581
597
  Collapse: memo(Collapse),
582
598
  Eraser: memo(Eraser),
@@ -597,7 +613,7 @@ const Icons = {
597
613
  Up: memo(Up),
598
614
  Down: memo(Down)
599
615
  };
600
- const Button = forwardRef((props, ref) => {
616
+ const Button$1 = forwardRef((props, ref) => {
601
617
  const {
602
618
  content,
603
619
  disabled,
@@ -636,7 +652,7 @@ function CutLine() {
636
652
  theme
637
653
  } = useContext(ToolbarContext);
638
654
  return /* @__PURE__ */ jsx("span", {
639
- className: clsx(`${name$3}-cut-line`, theme)
655
+ className: clsx(`${name$4}-cut-line`, theme)
640
656
  });
641
657
  }
642
658
  function useWritable(room) {
@@ -710,14 +726,14 @@ const EmptyToolbarHook = {
710
726
  setStrokeColor: noop
711
727
  };
712
728
  const ShapesMap = {
713
- [ApplianceNames.rectangle]: Icons.Rectangle,
714
- [ApplianceNames.ellipse]: Icons.Circle,
715
- [ApplianceNames.straight]: Icons.Line,
716
- [ApplianceNames.arrow]: Icons.Arrow,
717
- [ShapeType.Pentagram]: Icons.Star,
718
- [ShapeType.Rhombus]: Icons.Diamond,
719
- [ShapeType.Triangle]: Icons.Triangle,
720
- [ShapeType.SpeechBalloon]: Icons.SpeechBalloon
729
+ [ApplianceNames.rectangle]: Icons$1.Rectangle,
730
+ [ApplianceNames.ellipse]: Icons$1.Circle,
731
+ [ApplianceNames.straight]: Icons$1.Line,
732
+ [ApplianceNames.arrow]: Icons$1.Arrow,
733
+ [ShapeType.Pentagram]: Icons$1.Star,
734
+ [ShapeType.Rhombus]: Icons$1.Diamond,
735
+ [ShapeType.Triangle]: Icons$1.Triangle,
736
+ [ShapeType.SpeechBalloon]: Icons$1.SpeechBalloon
721
737
  };
722
738
  const ApplianceShapes = [
723
739
  ApplianceNames.rectangle,
@@ -736,21 +752,21 @@ const ItemsCount = 8;
736
752
  const MaxHeight = ItemHeight * ItemsCount - 4;
737
753
  const MinHeight = ItemHeight * 2 - 4;
738
754
  function UpButton({
755
+ disabled,
739
756
  scrollTo
740
757
  }) {
741
758
  const {
742
759
  theme,
743
- icons,
744
- writable
760
+ icons
745
761
  } = useContext(ToolbarContext);
746
762
  const scrollUp = useCallback(() => scrollTo(-ItemHeight), [scrollTo]);
747
- const disabled = !writable;
748
763
  return /* @__PURE__ */ jsxs(Fragment, {
749
- children: [/* @__PURE__ */ jsx(Button, {
764
+ children: [/* @__PURE__ */ jsx(Button$1, {
750
765
  content: "Up",
766
+ disabled,
751
767
  onClick: scrollUp,
752
768
  children: /* @__PURE__ */ jsx(Icon, {
753
- fallback: /* @__PURE__ */ jsx(Icons.Up, {
769
+ fallback: /* @__PURE__ */ jsx(Icons$1.Up, {
754
770
  theme
755
771
  }),
756
772
  src: disabled ? icons == null ? void 0 : icons.upIconDisable : icons == null ? void 0 : icons.upIcon,
@@ -760,21 +776,21 @@ function UpButton({
760
776
  });
761
777
  }
762
778
  function DownButton({
779
+ disabled,
763
780
  scrollTo
764
781
  }) {
765
782
  const {
766
783
  theme,
767
- icons,
768
- writable
784
+ icons
769
785
  } = useContext(ToolbarContext);
770
786
  const scrollDown = useCallback(() => scrollTo(ItemHeight), [scrollTo]);
771
- const disabled = !writable;
772
787
  return /* @__PURE__ */ jsxs(Fragment, {
773
- children: [/* @__PURE__ */ jsx(CutLine, {}), /* @__PURE__ */ jsx(Button, {
788
+ children: [/* @__PURE__ */ jsx(CutLine, {}), /* @__PURE__ */ jsx(Button$1, {
774
789
  content: "Down",
790
+ disabled,
775
791
  onClick: scrollDown,
776
792
  children: /* @__PURE__ */ jsx(Icon, {
777
- fallback: /* @__PURE__ */ jsx(Icons.Down, {
793
+ fallback: /* @__PURE__ */ jsx(Icons$1.Down, {
778
794
  theme
779
795
  }),
780
796
  src: disabled ? icons == null ? void 0 : icons.downIconDisable : icons == null ? void 0 : icons.downIcon,
@@ -812,12 +828,12 @@ function ClickerButton() {
812
828
  const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
813
829
  const active = appliance === ApplianceNames.clicker;
814
830
  const disabled = !writable;
815
- return /* @__PURE__ */ jsx(Button, {
831
+ return /* @__PURE__ */ jsx(Button$1, {
816
832
  content: renderToolTip(i18n == null ? void 0 : i18n.t("clicker"), shortcut),
817
833
  onClick: changeAppliance,
818
834
  active,
819
835
  children: /* @__PURE__ */ jsx(Icon, {
820
- fallback: /* @__PURE__ */ jsx(Icons.Clicker, {
836
+ fallback: /* @__PURE__ */ jsx(Icons$1.Clicker, {
821
837
  theme,
822
838
  active
823
839
  }),
@@ -841,12 +857,12 @@ function SelectorButton() {
841
857
  const active = appliance === ApplianceNames.selector;
842
858
  const disabled = !writable;
843
859
  const shortcut = ((app == null ? void 0 : app.config.joinRoom.hotKeys) || defaultHotKeys).changeToSelector;
844
- return /* @__PURE__ */ jsx(Button, {
860
+ return /* @__PURE__ */ jsx(Button$1, {
845
861
  content: renderToolTip(i18n == null ? void 0 : i18n.t("selector"), shortcut),
846
862
  onClick: changeAppliance,
847
863
  active,
848
864
  children: /* @__PURE__ */ jsx(Icon, {
849
- fallback: /* @__PURE__ */ jsx(Icons.Selector, {
865
+ fallback: /* @__PURE__ */ jsx(Icons$1.Selector, {
850
866
  theme,
851
867
  active
852
868
  }),
@@ -870,12 +886,12 @@ function EraserButton() {
870
886
  const active = appliance === ApplianceNames.eraser;
871
887
  const disabled = !writable;
872
888
  const shortcut = ((app == null ? void 0 : app.config.joinRoom.hotKeys) || defaultHotKeys).changeToEraser;
873
- return /* @__PURE__ */ jsx(Button, {
889
+ return /* @__PURE__ */ jsx(Button$1, {
874
890
  content: renderToolTip(i18n == null ? void 0 : i18n.t("eraser"), shortcut),
875
891
  onClick: changeAppliance,
876
892
  active,
877
893
  children: /* @__PURE__ */ jsx(Icon, {
878
- fallback: /* @__PURE__ */ jsx(Icons.Eraser, {
894
+ fallback: /* @__PURE__ */ jsx(Icons$1.Eraser, {
879
895
  theme,
880
896
  active
881
897
  }),
@@ -893,11 +909,11 @@ function CleanButton() {
893
909
  i18n
894
910
  } = useContext(ToolbarContext);
895
911
  const disabled = !writable;
896
- return /* @__PURE__ */ jsx(Button, {
912
+ return /* @__PURE__ */ jsx(Button$1, {
897
913
  content: i18n == null ? void 0 : i18n.t("clean"),
898
914
  onClick: cleanCurrentScene,
899
915
  children: /* @__PURE__ */ jsx(Icon, {
900
- fallback: /* @__PURE__ */ jsx(Icons.Clean, {
916
+ fallback: /* @__PURE__ */ jsx(Icons$1.Clean, {
901
917
  theme
902
918
  }),
903
919
  src: disabled ? icons == null ? void 0 : icons.cleanIconDisable : icons == null ? void 0 : icons.cleanIcon,
@@ -918,11 +934,11 @@ function AppsButton({
918
934
  writable
919
935
  } = useContext(ToolbarContext);
920
936
  const disabled = !writable;
921
- const button = /* @__PURE__ */ jsx(Button, {
937
+ const button = /* @__PURE__ */ jsx(Button$1, {
922
938
  content: "Apps",
923
939
  onClick,
924
940
  children: /* @__PURE__ */ jsx(Icon, {
925
- fallback: /* @__PURE__ */ jsx(Icons.Apps, {
941
+ fallback: /* @__PURE__ */ jsx(Icons$1.Apps, {
926
942
  theme
927
943
  }),
928
944
  src: disabled ? icons == null ? void 0 : icons.appsIconDisable : icons == null ? void 0 : icons.appsIcon,
@@ -982,7 +998,7 @@ function AppIcon({
982
998
  }) {
983
999
  return /* @__PURE__ */ jsxs("span", {
984
1000
  className: "fastboard-toolbar-app-icon",
985
- children: [/* @__PURE__ */ jsx(Button, {
1001
+ children: [/* @__PURE__ */ jsx(Button$1, {
986
1002
  placement: "top",
987
1003
  content: title,
988
1004
  onClick,
@@ -1095,12 +1111,12 @@ function PencilButton() {
1095
1111
  offset: RightOffset,
1096
1112
  arrow: false,
1097
1113
  interactive: true,
1098
- children: /* @__PURE__ */ jsxs(Button, {
1114
+ children: /* @__PURE__ */ jsxs(Button$1, {
1099
1115
  content: renderToolTip(i18n == null ? void 0 : i18n.t("pencil"), shortcut),
1100
1116
  active,
1101
1117
  onClick: changeAppliance,
1102
1118
  children: [/* @__PURE__ */ jsx(Icon, {
1103
- fallback: /* @__PURE__ */ jsx(Icons.Pencil, {
1119
+ fallback: /* @__PURE__ */ jsx(Icons$1.Pencil, {
1104
1120
  theme,
1105
1121
  active
1106
1122
  }),
@@ -1147,12 +1163,12 @@ function TextButton() {
1147
1163
  offset: RightOffset,
1148
1164
  arrow: false,
1149
1165
  interactive: true,
1150
- children: /* @__PURE__ */ jsxs(Button, {
1166
+ children: /* @__PURE__ */ jsxs(Button$1, {
1151
1167
  content: renderToolTip(i18n == null ? void 0 : i18n.t("text"), shortcut),
1152
1168
  active,
1153
1169
  onClick: changeAppliance,
1154
1170
  children: [/* @__PURE__ */ jsx(Icon, {
1155
- fallback: /* @__PURE__ */ jsx(Icons.Text, {
1171
+ fallback: /* @__PURE__ */ jsx(Icons$1.Text, {
1156
1172
  theme,
1157
1173
  active
1158
1174
  }),
@@ -1182,7 +1198,7 @@ function ShapesButton() {
1182
1198
  const shape = memberState == null ? void 0 : memberState.shapeType;
1183
1199
  const key = appliance === ApplianceNames.shape ? shape : appliance;
1184
1200
  const active = ShapeTypes.has(key);
1185
- const CurrentIcon = ShapesMap[key] || Icons.Rectangle;
1201
+ const CurrentIcon = ShapesMap[key] || Icons$1.Rectangle;
1186
1202
  return /* @__PURE__ */ jsx("span", {
1187
1203
  className: "fastboard-toolbar-btn-interactive",
1188
1204
  children: /* @__PURE__ */ jsx(Tippy, {
@@ -1194,7 +1210,7 @@ function ShapesButton() {
1194
1210
  offset: RightOffset,
1195
1211
  arrow: false,
1196
1212
  interactive: true,
1197
- children: /* @__PURE__ */ jsxs(Button, {
1213
+ children: /* @__PURE__ */ jsxs(Button$1, {
1198
1214
  content: i18n == null ? void 0 : i18n.t("shape"),
1199
1215
  active,
1200
1216
  children: [/* @__PURE__ */ jsx(CurrentIcon, {
@@ -1243,7 +1259,7 @@ function ApplianceShapeButton({
1243
1259
  } = useContext(ToolbarContext);
1244
1260
  const current = memberState == null ? void 0 : memberState.currentApplianceName;
1245
1261
  const disabled = !writable;
1246
- return /* @__PURE__ */ jsx(Button, {
1262
+ return /* @__PURE__ */ jsx(Button$1, {
1247
1263
  content,
1248
1264
  disabled,
1249
1265
  placement: "top",
@@ -1268,7 +1284,7 @@ function ShapeShapeButton({
1268
1284
  const appliance = memberState == null ? void 0 : memberState.currentApplianceName;
1269
1285
  const current = appliance === ApplianceNames.shape && (memberState == null ? void 0 : memberState.shapeType);
1270
1286
  const disabled = !writable;
1271
- return /* @__PURE__ */ jsx(Button, {
1287
+ return /* @__PURE__ */ jsx(Button$1, {
1272
1288
  content,
1273
1289
  disabled,
1274
1290
  placement: "top",
@@ -1279,54 +1295,67 @@ function ShapeShapeButton({
1279
1295
  })
1280
1296
  });
1281
1297
  }
1282
- function Content({
1283
- padding = 16
1284
- }) {
1298
+ function Content() {
1285
1299
  var _a, _b, _c, _d, _e, _f, _g;
1286
1300
  const app = useInstance();
1287
1301
  const ref = useRef(null);
1302
+ const [scrollTop, setScrollTop] = useState(0);
1288
1303
  const [parentHeight, setParentHeight] = useState(0);
1304
+ const hasAppButton = (_c = (_b = (_a = app == null ? void 0 : app.config.toolbar) == null ? void 0 : _a.apps) == null ? void 0 : _b.enable) != null ? _c : true;
1289
1305
  const needScroll = parentHeight < ItemHeight * ItemsCount + 48;
1290
1306
  const sectionHeight = clamp(parentHeight - 48 * (needScroll ? 3 : 1), MinHeight, MaxHeight);
1307
+ const scrollBuffer = Math.max(parentHeight - sectionHeight - 1, 0);
1308
+ const disableScrollUp = scrollTop === 0;
1309
+ const disableScrollDown = scrollTop === scrollBuffer;
1291
1310
  const scrollTo = useCallback((height) => {
1311
+ setScrollTop(clamp(scrollTop + height, 0, scrollBuffer));
1312
+ }, [scrollBuffer, scrollTop]);
1313
+ useEffect(() => {
1292
1314
  if (ref.current) {
1293
- ref.current.scrollTop = ref.current.scrollTop + height;
1315
+ ref.current.scrollTop = scrollTop;
1294
1316
  }
1295
- }, []);
1317
+ }, [scrollTop]);
1296
1318
  useEffect(() => {
1297
1319
  var _a2, _b2;
1298
1320
  const container = (_b2 = (_a2 = ref.current) == null ? void 0 : _a2.parentElement) == null ? void 0 : _b2.parentElement;
1299
1321
  if (container) {
1322
+ const {
1323
+ paddingTop,
1324
+ paddingBottom
1325
+ } = getComputedStyle(container);
1326
+ const padding = parseInt(paddingTop) + parseInt(paddingBottom) || 0;
1300
1327
  const resizeObserver = new ResizeObserver(() => {
1301
- setParentHeight(container.getBoundingClientRect().height - padding * 2);
1328
+ setParentHeight(container.getBoundingClientRect().height - padding);
1302
1329
  });
1303
1330
  resizeObserver.observe(container);
1304
1331
  return () => resizeObserver.disconnect();
1305
1332
  }
1306
- }, [padding]);
1333
+ }, []);
1307
1334
  return /* @__PURE__ */ jsxs(Fragment, {
1308
1335
  children: [needScroll && /* @__PURE__ */ jsx(UpButton, {
1309
- scrollTo
1336
+ scrollTo,
1337
+ disabled: disableScrollUp
1310
1338
  }), /* @__PURE__ */ jsxs("div", {
1311
1339
  ref,
1312
- className: `${name$3}-section`,
1340
+ className: `${name$4}-section`,
1313
1341
  style: {
1314
1342
  height: `${sectionHeight}px`,
1315
1343
  overflow: needScroll ? "hidden" : "visible"
1316
1344
  },
1317
- children: [/* @__PURE__ */ jsx(ClickerButton, {}), /* @__PURE__ */ jsx(SelectorButton, {}), /* @__PURE__ */ jsx(PencilButton, {}), /* @__PURE__ */ jsx(TextButton, {}), /* @__PURE__ */ jsx(ShapesButton, {}), /* @__PURE__ */ jsx(EraserButton, {}), /* @__PURE__ */ jsx(CleanButton, {}), ((_c = (_b = (_a = app == null ? void 0 : app.config.toolbar) == null ? void 0 : _a.apps) == null ? void 0 : _b.enable) != null ? _c : true) && /* @__PURE__ */ jsx(AppsButton, {
1345
+ children: [/* @__PURE__ */ jsx(ClickerButton, {}), /* @__PURE__ */ jsx(SelectorButton, {}), /* @__PURE__ */ jsx(PencilButton, {}), /* @__PURE__ */ jsx(TextButton, {}), /* @__PURE__ */ jsx(ShapesButton, {}), /* @__PURE__ */ jsx(EraserButton, {}), /* @__PURE__ */ jsx(CleanButton, {}), hasAppButton && /* @__PURE__ */ jsx(AppsButton, {
1318
1346
  content: (_e = (_d = app == null ? void 0 : app.config.toolbar) == null ? void 0 : _d.apps) == null ? void 0 : _e.content,
1319
1347
  onClick: (_g = (_f = app == null ? void 0 : app.config.toolbar) == null ? void 0 : _f.apps) == null ? void 0 : _g.onClick
1320
1348
  })]
1321
1349
  }), needScroll && /* @__PURE__ */ jsx(DownButton, {
1322
- scrollTo
1350
+ scrollTo,
1351
+ disabled: disableScrollDown
1323
1352
  })]
1324
1353
  });
1325
1354
  }
1326
1355
  const ToolbarContext = createContext(__spreadValues({
1327
1356
  theme: "light"
1328
1357
  }, EmptyToolbarHook));
1329
- const name$3 = "fastboard-toolbar";
1358
+ const name$4 = "fastboard-toolbar";
1330
1359
  const Toolbar = ({
1331
1360
  theme = "light",
1332
1361
  icons,
@@ -1345,21 +1374,21 @@ const Toolbar = ({
1345
1374
  i18n
1346
1375
  }),
1347
1376
  children: /* @__PURE__ */ jsxs("div", {
1348
- className: clsx(name$3, theme),
1349
- children: [expanded ? /* @__PURE__ */ jsx(Button, {
1377
+ className: clsx(name$4, theme),
1378
+ children: [expanded ? /* @__PURE__ */ jsx(Button$1, {
1350
1379
  content: i18n == null ? void 0 : i18n.t("collapse"),
1351
1380
  onClick: toggle,
1352
1381
  children: /* @__PURE__ */ jsx(Icon, {
1353
- fallback: /* @__PURE__ */ jsx(Icons.Collapse, {
1382
+ fallback: /* @__PURE__ */ jsx(Icons$1.Collapse, {
1354
1383
  theme
1355
1384
  }),
1356
1385
  src: disabled ? icons == null ? void 0 : icons.collapseIconDisable : icons == null ? void 0 : icons.collapseIcon
1357
1386
  })
1358
- }) : /* @__PURE__ */ jsx(Button, {
1387
+ }) : /* @__PURE__ */ jsx(Button$1, {
1359
1388
  content: i18n == null ? void 0 : i18n.t("expand"),
1360
1389
  onClick: toggle,
1361
1390
  children: /* @__PURE__ */ jsx(Icon, {
1362
- fallback: /* @__PURE__ */ jsx(Icons.Expand, {
1391
+ fallback: /* @__PURE__ */ jsx(Icons$1.Expand, {
1363
1392
  theme
1364
1393
  }),
1365
1394
  src: disabled ? icons == null ? void 0 : icons.expandIconDisable : icons == null ? void 0 : icons.expandIcon
@@ -1414,7 +1443,7 @@ function Redo({
1414
1443
  })
1415
1444
  });
1416
1445
  }
1417
- const name$2 = "fastboard-redo-undo";
1446
+ const name$3 = "fastboard-redo-undo";
1418
1447
  function RedoUndo({
1419
1448
  room,
1420
1449
  theme = "light",
@@ -1444,7 +1473,7 @@ function RedoUndo({
1444
1473
  }, [room]);
1445
1474
  const disabled = !writable;
1446
1475
  return /* @__PURE__ */ jsxs("div", {
1447
- className: clsx(name$2, theme),
1476
+ className: clsx(name$3, theme),
1448
1477
  children: [/* @__PURE__ */ jsx(Tippy, {
1449
1478
  className: "fastboard-tip",
1450
1479
  content: i18n == null ? void 0 : i18n.t("undo"),
@@ -1454,7 +1483,7 @@ function RedoUndo({
1454
1483
  duration: 300,
1455
1484
  offset: TopOffset,
1456
1485
  children: /* @__PURE__ */ jsx("button", {
1457
- className: clsx(`${name$2}-btn`, "undo", theme),
1486
+ className: clsx(`${name$3}-btn`, "undo", theme),
1458
1487
  disabled: disabled || undoSteps === 0,
1459
1488
  onClick: useCallback(() => room && room.undo(), [room]),
1460
1489
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1474,7 +1503,7 @@ function RedoUndo({
1474
1503
  duration: 300,
1475
1504
  offset: TopOffset,
1476
1505
  children: /* @__PURE__ */ jsx("button", {
1477
- className: clsx(`${name$2}-btn`, "redo", theme),
1506
+ className: clsx(`${name$3}-btn`, "redo", theme),
1478
1507
  disabled: disabled || redoSteps === 0,
1479
1508
  onClick: useCallback(() => room && room.redo(), [room]),
1480
1509
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1552,7 +1581,7 @@ function Reset({
1552
1581
  })
1553
1582
  });
1554
1583
  }
1555
- const name$1 = "fastboard-zoom-control";
1584
+ const name$2 = "fastboard-zoom-control";
1556
1585
  const ScalePoints = [0.10737418240000011, 0.13421772800000012, 0.16777216000000014, 0.20971520000000016, 0.26214400000000015, 0.3276800000000002, 0.4096000000000002, 0.5120000000000001, 0.6400000000000001, 0.8, 1, 1.26, 1.5876000000000001, 2.000376, 2.5204737600000002, 3.1757969376000004, 4.001504141376, 5.041895218133761, 6.352787974848539, 8.00451284830916, 10];
1557
1586
  function nextScale(scale, delta) {
1558
1587
  const {
@@ -1680,7 +1709,7 @@ function ZoomControl({
1680
1709
  }, [room, manager]);
1681
1710
  const disabled = !writable;
1682
1711
  return /* @__PURE__ */ jsxs("div", {
1683
- className: clsx(name$1, theme),
1712
+ className: clsx(name$2, theme),
1684
1713
  children: [/* @__PURE__ */ jsx(Tippy, {
1685
1714
  className: "fastboard-tip",
1686
1715
  content: i18n == null ? void 0 : i18n.t("zoomOut"),
@@ -1690,7 +1719,7 @@ function ZoomControl({
1690
1719
  duration: 300,
1691
1720
  offset: TopOffset,
1692
1721
  children: /* @__PURE__ */ jsx("button", {
1693
- className: clsx(`${name$1}-btn`, "minus", theme),
1722
+ className: clsx(`${name$2}-btn`, "minus", theme),
1694
1723
  disabled,
1695
1724
  onClick: zoomOut,
1696
1725
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1702,10 +1731,10 @@ function ZoomControl({
1702
1731
  })
1703
1732
  })
1704
1733
  }), /* @__PURE__ */ jsx("span", {
1705
- className: clsx(`${name$1}-scale`, theme),
1734
+ className: clsx(`${name$2}-scale`, theme),
1706
1735
  children: Math.ceil(scale * 100)
1707
1736
  }), /* @__PURE__ */ jsx("span", {
1708
- className: clsx(`${name$1}-percent`, theme),
1737
+ className: clsx(`${name$2}-percent`, theme),
1709
1738
  children: "%"
1710
1739
  }), /* @__PURE__ */ jsx(Tippy, {
1711
1740
  className: "fastboard-tip",
@@ -1716,7 +1745,7 @@ function ZoomControl({
1716
1745
  duration: 300,
1717
1746
  offset: TopOffset,
1718
1747
  children: /* @__PURE__ */ jsx("button", {
1719
- className: clsx(`${name$1}-btn`, "plus", theme),
1748
+ className: clsx(`${name$2}-btn`, "plus", theme),
1720
1749
  disabled,
1721
1750
  onClick: zoomIn,
1722
1751
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1736,7 +1765,7 @@ function ZoomControl({
1736
1765
  duration: 300,
1737
1766
  offset: TopOffset,
1738
1767
  children: /* @__PURE__ */ jsx("button", {
1739
- className: clsx(`${name$1}-btn`, "reset", theme),
1768
+ className: clsx(`${name$2}-btn`, "reset", theme),
1740
1769
  disabled,
1741
1770
  onClick: resetCamera,
1742
1771
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1798,7 +1827,7 @@ function ChevronRight({
1798
1827
  })
1799
1828
  });
1800
1829
  }
1801
- const name = "fastboard-page-control";
1830
+ const name$1 = "fastboard-page-control";
1802
1831
  function PageControl({
1803
1832
  room,
1804
1833
  manager,
@@ -1878,7 +1907,7 @@ function PageControl({
1878
1907
  }, [room, manager]);
1879
1908
  const disabled = !writable;
1880
1909
  return /* @__PURE__ */ jsxs("div", {
1881
- className: clsx(name, theme),
1910
+ className: clsx(name$1, theme),
1882
1911
  children: [/* @__PURE__ */ jsx(Tippy, {
1883
1912
  className: "fastboard-tip",
1884
1913
  content: i18n == null ? void 0 : i18n.t("prevPage"),
@@ -1888,7 +1917,7 @@ function PageControl({
1888
1917
  duration: 300,
1889
1918
  offset: TopOffset,
1890
1919
  children: /* @__PURE__ */ jsx("button", {
1891
- className: clsx(`${name}-btn`, "prev", theme),
1920
+ className: clsx(`${name$1}-btn`, "prev", theme),
1892
1921
  disabled: disabled || pageIndex === 0,
1893
1922
  onClick: prevPage,
1894
1923
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1900,13 +1929,13 @@ function PageControl({
1900
1929
  })
1901
1930
  })
1902
1931
  }), /* @__PURE__ */ jsx("span", {
1903
- className: clsx(`${name}-page`, theme),
1932
+ className: clsx(`${name$1}-page`, theme),
1904
1933
  children: pageCount === 0 ? "\u2026" : pageIndex + 1
1905
1934
  }), /* @__PURE__ */ jsx("span", {
1906
- className: clsx(`${name}-slash`, theme),
1935
+ className: clsx(`${name$1}-slash`, theme),
1907
1936
  children: "/"
1908
1937
  }), /* @__PURE__ */ jsx("span", {
1909
- className: clsx(`${name}-page-count`, theme),
1938
+ className: clsx(`${name$1}-page-count`, theme),
1910
1939
  children: pageCount
1911
1940
  }), /* @__PURE__ */ jsx(Tippy, {
1912
1941
  className: "fastboard-tip",
@@ -1917,7 +1946,7 @@ function PageControl({
1917
1946
  duration: 300,
1918
1947
  offset: TopOffset,
1919
1948
  children: /* @__PURE__ */ jsx("button", {
1920
- className: clsx(`${name}-btn`, "next", theme),
1949
+ className: clsx(`${name$1}-btn`, "next", theme),
1921
1950
  disabled: disabled || pageIndex === pageCount - 1,
1922
1951
  onClick: nextPage,
1923
1952
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1937,7 +1966,7 @@ function PageControl({
1937
1966
  duration: 300,
1938
1967
  offset: TopOffset,
1939
1968
  children: /* @__PURE__ */ jsx("button", {
1940
- className: clsx(`${name}-btn`, "add", theme),
1969
+ className: clsx(`${name$1}-btn`, "add", theme),
1941
1970
  disabled,
1942
1971
  onClick: addPage,
1943
1972
  children: /* @__PURE__ */ jsx(Icon, {
@@ -1998,7 +2027,6 @@ function Root({
1998
2027
  class Instance {
1999
2028
  constructor(config) {
2000
2029
  __publicField(this, "config");
2001
- __publicField(this, "target", null);
2002
2030
  __publicField(this, "sdk", null);
2003
2031
  __publicField(this, "room", null);
2004
2032
  __publicField(this, "manager", null);
@@ -2006,10 +2034,10 @@ class Instance {
2006
2034
  __publicField(this, "ready", false);
2007
2035
  __publicField(this, "resolveReady");
2008
2036
  __publicField(this, "readyPromise");
2009
- this.target = config.target;
2037
+ __publicField(this, "_target", null);
2010
2038
  this.config = config;
2011
2039
  this.refreshReadyPromise();
2012
- this.forceUpdate();
2040
+ this.initialize();
2013
2041
  }
2014
2042
  refreshReadyPromise() {
2015
2043
  this.readyPromise = new Promise((resolve) => {
@@ -2020,10 +2048,28 @@ class Instance {
2020
2048
  };
2021
2049
  });
2022
2050
  }
2023
- forceUpdate() {
2024
- ReactDOM.render(/* @__PURE__ */ jsx(Root, {
2025
- instance: this
2026
- }), this.target);
2051
+ async initialize() {
2052
+ const essentials = await mountWhiteboard(this.config.sdkConfig, this.config.joinRoom, this.config.managerConfig || {}, this.config.language || "en-US");
2053
+ this.accept(essentials);
2054
+ this.resolveReady();
2055
+ }
2056
+ get target() {
2057
+ return this._target;
2058
+ }
2059
+ set target(value) {
2060
+ if (this._target && value) {
2061
+ ReactDOM.unmountComponentAtNode(this._target);
2062
+ }
2063
+ this._target = value;
2064
+ this.forceUpdate();
2065
+ }
2066
+ async forceUpdate() {
2067
+ await this.readyPromise;
2068
+ if (this.target) {
2069
+ ReactDOM.render(/* @__PURE__ */ jsx(Root, {
2070
+ instance: this
2071
+ }), this.target);
2072
+ }
2027
2073
  }
2028
2074
  accept({
2029
2075
  sdk,
@@ -2046,16 +2092,11 @@ class Instance {
2046
2092
  this.sdk = this.room = this.manager = this.target = null;
2047
2093
  }
2048
2094
  }
2049
- async mount(container) {
2050
- if (this.room) {
2051
- console.warn("[WhiteboardApp] already mounted");
2052
- return;
2095
+ async mount(node) {
2096
+ await this.readyPromise;
2097
+ if (this.manager) {
2098
+ this.manager.bindContainer(node);
2053
2099
  }
2054
- const essentials = await mountWhiteboard(this.config.sdkConfig, this.config.joinRoom, __spreadProps(__spreadValues({}, this.config.managerConfig), {
2055
- container
2056
- }), this.config.language);
2057
- this.accept(essentials);
2058
- this.resolveReady();
2059
2100
  }
2060
2101
  async unmount() {
2061
2102
  if (this.manager) {
@@ -2133,74 +2174,343 @@ class Instance {
2133
2174
  }
2134
2175
  });
2135
2176
  }
2136
- changeLanguage(language) {
2177
+ async changeLanguage(language) {
2137
2178
  var _a;
2138
- return (_a = this.i18n) == null ? void 0 : _a.changeLanguage(language);
2179
+ try {
2180
+ await ((_a = this.i18n) == null ? void 0 : _a.changeLanguage(language));
2181
+ } finally {
2182
+ await this.forceUpdate();
2183
+ }
2139
2184
  }
2140
2185
  }
2141
2186
  __publicField(Instance, "Context", createContext(null));
2142
2187
  function useInstance() {
2143
2188
  return useContext(Instance.Context);
2144
2189
  }
2190
+ var style = '.netless-window-manager-playground{width:100%;height:100%;position:relative;z-index:1;overflow:hidden;user-select:none}.netless-window-manager-sizer{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;overflow:hidden;display:flex}.netless-window-manager-sizer-horizontal{flex-direction:column}.netless-window-manager-sizer:before,.netless-window-manager-sizer:after{flex:1;content:"";display:block}.netless-window-manager-chess-sizer:before,.netless-window-manager-chess-sizer:after{background-image:linear-gradient(45deg,#b0b0b0 25%,transparent 25%),linear-gradient(-45deg,#b0b0b0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#b0b0b0 75%),linear-gradient(-45deg,transparent 75%,#b0b0b0 75%);background-color:#fff;background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.netless-window-manager-wrapper{position:relative;z-index:1;width:100%;height:100%;overflow:hidden}.netless-window-manager-main-view{width:100%;height:100%}.netless-window-manager-cursor-pencil-image,.netless-window-manager-cursor-eraser-image{width:26px;height:26px}.netless-window-manager-cursor-selector-image{width:24px;height:24px}.netless-window-manager-cursor-selector-avatar{border-radius:50%;border-style:solid;border-width:2px;border-color:#fff;margin-bottom:2px}.netless-window-manager-cursor-selector-avatar img{width:12px}.netless-window-manager-cursor-inner{border-radius:4px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:4px;padding-right:4px;font-size:12px}.netless-window-manager-cursor-inner-mellow{height:32px;border-radius:16px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:16px;padding-right:16px}.netless-window-manager-cursor-tag-name{font-size:12px;margin-left:4px;padding:2px 8px;border-radius:4px}.netless-window-manager-cursor-mid{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:26px;height:26px;z-index:2147483647;left:0;top:0;will-change:transform;transition:transform .05s;transform-origin:0 0;user-select:none}.netless-window-manager-cursor-pencil-offset{margin-left:-20px}.netless-window-manager-cursor-selector-offset{margin-left:-22px;margin-top:56px}.netless-window-manager-cursor-text-offset{margin-left:-30px;margin-top:18px}.netless-window-manager-cursor-shape-offset{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:180px;height:64px;margin-left:-30px;margin-top:12px}.netless-window-manager-cursor-name{width:100%;height:48px;display:flex;align-items:center;justify-content:center;position:absolute;top:-40px}.cursor-image-wrapper{display:flex;justify-content:center}.tele-fancy-scrollbar{overscroll-behavior:contain;overflow:auto;overflow-y:scroll;overflow-y:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.tele-fancy-scrollbar::-webkit-scrollbar{height:8px;width:8px}.tele-fancy-scrollbar::-webkit-scrollbar-track{background-color:transparent}.tele-fancy-scrollbar::-webkit-scrollbar-thumb{background-color:#444e601a;background-color:transparent;border-radius:4px;transition:background-color .4s}.tele-fancy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#444e601a}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:active{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:vertical{min-height:50px}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-box{position:absolute;top:0;left:0;z-index:100;will-change:transform;transition:width .4s cubic-bezier(.4,.9,.71,1.02),height .4s cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .4s ease}.telebox-box-main{position:relative;width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#f9f9fc;box-shadow:0 4px 10px #2f419226;border-radius:6px;border:1px solid #e3e3ec}.telebox-titlebar-wrap{flex-shrink:0;position:relative;z-index:1}.telebox-content-wrap{flex:1;width:100%;overflow:hidden;display:flex;justify-content:center;align-items:center}.telebox-content{width:100%;height:100%;position:relative}.telebox-footer-wrap{flex-shrink:0;display:flex;flex-direction:column}.telebox-footer-wrap:before{content:"";display:block;flex:1}.telebox-resize-handle{position:absolute;z-index:2147483647}.telebox-n{width:100%;height:5px;left:0;top:-5px;cursor:n-resize}.telebox-s{width:100%;height:5px;left:0;bottom:-5px;cursor:s-resize}.telebox-w{width:5px;height:100%;left:-5px;top:0;cursor:w-resize}.telebox-e{width:5px;height:100%;right:-5px;top:0;cursor:e-resize}.telebox-nw{width:15px;height:15px;top:-5px;left:-5px;cursor:nw-resize}.telebox-ne{width:15px;height:15px;top:-5px;right:-5px;cursor:ne-resize}.telebox-se{width:15px;height:15px;bottom:-5px;right:-5px;cursor:se-resize}.telebox-sw{width:15px;height:15px;bottom:-5px;left:-5px;cursor:sw-resize}.telebox-track-mask{position:fixed;top:0;left:0;z-index:2147483647;width:100%;height:100%;background:rgba(0,0,0,.0001);cursor:move}.telebox-cursor-n{cursor:n-resize}.telebox-cursor-s{cursor:s-resize}.telebox-cursor-w{cursor:w-resize}.telebox-cursor-e{cursor:e-resize}.telebox-cursor-nw{cursor:nw-resize}.telebox-cursor-ne{cursor:ne-resize}.telebox-cursor-se{cursor:se-resize}.telebox-cursor-sw{cursor:sw-resize}.telebox-maximized .telebox-resize-handles,.telebox-no-resize .telebox-resize-handles{display:none}.telebox-maximized{box-shadow:none;transition:none}.telebox-minimized{will-change:transform;transition:width 50ms cubic-bezier(.4,.9,.71,1.02),height 50ms cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .6s ease;opacity:0;pointer-events:none;user-select:none}.telebox-transforming{will-change:transform;transition:opacity .6s cubic-bezier(.7,0,.84,0)}.telebox-readonly .telebox-resize-handle{cursor:initial!important;pointer-events:none!important}.telebox-color-scheme-dark .telebox-box-main{color:#e9e9e9;background:#212126;border-color:#43434d}.telebox-titlebar{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;background:#fff;user-select:none;border-bottom:1px solid #eeeef7}.telebox-title{overflow:hidden;margin:0 24px 0 0;padding:0;font-size:14px;font-weight:400;font-family:PingFangSC-Regular,PingFang SC;white-space:nowrap;word-break:keep-all;text-overflow:ellipsis;color:#191919}.telebox-titlebar-btns{white-space:nowrap;word-break:keep-all;margin-left:auto;font-size:0}.telebox-titlebar-btn{width:22px;height:22px;padding:0;outline:0;border:none;background:0 0;cursor:pointer}.telebox-titlebar-btn~.telebox-titlebar-btn{margin-left:10px}.telebox-titlebar-btn-icon{width:22px;height:22px}.telebox-readonly .telebox-titlebar-btn{cursor:not-allowed}.telebox-titlebar-icon-minimize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHBhdGggZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBkPSJNOSAxM2gxMHYxLjZIOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-titlebar-icon-maximize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPGcgZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBtYXNrPSJ1cmwoI2IpIj4KICAgICAgICAgICAgPHBhdGgKICAgICAgICAgICAgICAgIGQ9Ik0yMC40ODEgMTcuMWgxLjJ2NC41ODFIMTcuMXYtMS4yaDMuMzgxVjE3LjF6bS0xNC4xOTA1LS4wMDloMS4ydjMuMzgxaDMuMzgwOXYxLjJoLTQuNTgxdi00LjU4MXpNMTcuMSA2LjE5MDVoNC41ODF2NC41ODA5aC0xLjJ2LTMuMzgxSDE3LjF2LTEuMnptLTEwLjcwMDguMTA4N2g0Ljc5ODV2MS4ySDcuNTk5MnYzLjU5ODVoLTEuMlY2LjI5OTJ6IiAvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==)}.telebox-titlebar-icon-maximize.is-active{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjZ2MjZIMHoiIC8+CiAgICAgICAgPHBhdGggaWQ9ImMiIGQ9Ik0yNi44NjkgMEwyOCAxLjEzMVYyNi44N0wyNi44NjkgMjhIMS4xM0wwIDI2Ljg3VjEuMTMxTDEuMTMgMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMSkiPgogICAgICAgICAgICA8bWFzayBpZD0iYiIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNhIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tNC42NDI5LTQuNjQyOWgzNS4yODU4djM1LjI4NThILTQuNjQyOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8bWFzayBpZD0iZCIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNjIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tMTcuNTE2OCAxNEwxNC0xNy41MTY4IDQ1LjUxNjggMTQgMTQgNDUuNTE2OHoiIG1hc2s9InVybCgjZCkiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjIiCiAgICAgICAgICAgIGQ9Ik0xMC4wODg2IDIxLjQ4NjV2LTMuNjk2Nkg2LjM5Mk0yMS4zODU1IDEwLjE4OTVoLTMuNjk2NlY2LjQ5M00yMS40MDIgMTcuNzk4M2gtMy42OTY2djMuNjk2Nk0xMC4yNTAzIDYuMTQ5OHYzLjg5ODVINi4zNTE3IiAvPgogICAgPC9nPgo8L3N2Zz4K)}.telebox-titlebar-icon-close{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCI+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjQiPgogICAgICAgIDxwYXRoIGQ9Ik04LjM1MyAyMC4zMzIxTDIwLjMzMiA4LjM1M00yMC4zMzIyIDIwLjMzMjFMOC4zNTMgOC4zNTMiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-color-scheme-dark .telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-collector{visibility:hidden;display:block;position:absolute;z-index:200;width:40px;height:40px;margin:0;padding:0;border:none;outline:0;font-size:0;border-radius:50%;background:#fff;box-shadow:0 2px 6px #2f419226;cursor:pointer;user-select:none;pointer-events:none;background-repeat:no-repeat;background-size:18px 16px;background-position:center}.telebox-collector-visible{visibility:visible;pointer-events:initial}.telebox-collector-readonly{cursor:not-allowed}.telebox-color-scheme-dark.telebox-collector{background-color:#43434d}.telebox-max-titlebar{display:none;position:absolute;top:0;left:0;z-index:50000;user-select:none}.telebox-max-titlebar-maximized{display:flex}.telebox-titles{flex:1;height:100%;margin:0 16px 0 -16px;overflow-y:hidden;overflow-x:scroll;overflow-x:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.telebox-titles::-webkit-scrollbar{height:8px;width:8px}.telebox-titles::-webkit-scrollbar-track{background-color:transparent}.telebox-titles::-webkit-scrollbar-thumb{background-color:#eeeef7cc;background-color:transparent;border-radius:4px;transition:background-color .4s}.telebox-titles:hover::-webkit-scrollbar-thumb{background-color:#eeeef7cc}.telebox-titles::-webkit-scrollbar-thumb:hover{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:active{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:vertical{min-height:50px}.telebox-titles::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-titles-content{height:100%;display:flex;flex-wrap:nowrap;align-items:center;padding:0}.telebox-titles-tab{overflow:hidden;max-width:182px;min-width:50px;padding:0 26px 0 16px;outline:0;font-size:13px;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all;border:none;border-right:1px solid #e5e5f0;color:#7b88a0;background:0 0;cursor:pointer}.telebox-titles-tab~.telebox-titles-tab{margin-left:2px}.telebox-titles-tab-focus{color:#357bf6}.telebox-readonly .telebox-titles-tab{cursor:not-allowed}.telebox-color-scheme-dark{color-scheme:dark}.telebox-color-scheme-dark.telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-color-scheme-dark .telebox-titles-tab{border-right-color:#7b88a0}.telebox-color-scheme-dark .telebox-title{color:#e9e9e9}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}.tippy-box[data-theme~=light]{color:#26323d;box-shadow:0 0 20px 4px #9aa1b126,0 4px 80px -8px #24282f40,0 4px 4px -2px #5b5e6926;background-color:#fff}.tippy-box[data-theme~=light][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff}.tippy-box[data-theme~=light][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff}.tippy-box[data-theme~=light]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light]>.tippy-svg-arrow{fill:#fff}.rc-slider{position:relative;height:14px;padding:5px 0;width:100%;border-radius:6px;touch-action:none;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-rail{position:absolute;width:100%;background-color:#e9e9e9;height:4px;border-radius:6px}.rc-slider-track{position:absolute;left:0;height:4px;border-radius:6px;background-color:#abe2fb}.rc-slider-handle{position:absolute;width:14px;height:14px;cursor:pointer;cursor:-webkit-grab;margin-top:-5px;cursor:grab;border-radius:50%;border:solid 2px #96dbfa;background-color:#fff;touch-action:pan-x}.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging{border-color:#57c5f7;box-shadow:0 0 0 5px #96dbfa}.rc-slider-handle:focus{outline:none}.rc-slider-handle-click-focused:focus{border-color:#96dbfa;box-shadow:unset}.rc-slider-handle:hover{border-color:#57c5f7}.rc-slider-handle:active{border-color:#57c5f7;box-shadow:0 0 5px #57c5f7;cursor:-webkit-grabbing;cursor:grabbing}.rc-slider-mark{position:absolute;top:18px;left:0;width:100%;font-size:12px}.rc-slider-mark-text{position:absolute;display:inline-block;vertical-align:middle;text-align:center;cursor:pointer;color:#999}.rc-slider-mark-text-active{color:#666}.rc-slider-step{position:absolute;width:100%;height:4px;background:transparent}.rc-slider-dot{position:absolute;bottom:-2px;margin-left:-4px;width:8px;height:8px;border:2px solid #e9e9e9;background-color:#fff;cursor:pointer;border-radius:50%;vertical-align:middle}.rc-slider-dot-active{border-color:#96dbfa}.rc-slider-dot-reverse{margin-right:-4px}.rc-slider-disabled{background-color:#e9e9e9}.rc-slider-disabled .rc-slider-track{background-color:#ccc}.rc-slider-disabled .rc-slider-handle,.rc-slider-disabled .rc-slider-dot{border-color:#ccc;box-shadow:none;background-color:#fff;cursor:not-allowed}.rc-slider-disabled .rc-slider-mark-text,.rc-slider-disabled .rc-slider-dot{cursor:not-allowed!important}.rc-slider-vertical{width:14px;height:100%;padding:0 5px}.rc-slider-vertical .rc-slider-rail{height:100%;width:4px}.rc-slider-vertical .rc-slider-track{left:5px;bottom:0;width:4px}.rc-slider-vertical .rc-slider-handle{margin-left:-5px;touch-action:pan-y}.rc-slider-vertical .rc-slider-mark{top:0;left:18px;height:100%}.rc-slider-vertical .rc-slider-step{height:100%;width:4px}.rc-slider-vertical .rc-slider-dot{left:2px;margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:first-child{margin-bottom:-4px}.rc-slider-vertical .rc-slider-dot:last-child{margin-bottom:-4px}.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-appear,.rc-slider-tooltip-zoom-down-leave{animation-duration:.3s;animation-fill-mode:both;display:block!important;animation-play-state:paused}.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active{animation-name:rcSliderTooltipZoomDownIn;animation-play-state:running}.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active{animation-name:rcSliderTooltipZoomDownOut;animation-play-state:running}.rc-slider-tooltip-zoom-down-enter,.rc-slider-tooltip-zoom-down-appear{transform:scale(0);animation-timing-function:cubic-bezier(.23,1,.32,1)}.rc-slider-tooltip-zoom-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes rcSliderTooltipZoomDownIn{0%{opacity:0;transform-origin:50% 100%;transform:scale(0)}to{transform-origin:50% 100%;transform:scale(1)}}@keyframes rcSliderTooltipZoomDownOut{0%{transform-origin:50% 100%;transform:scale(1)}to{opacity:0;transform-origin:50% 100%;transform:scale(0)}}.rc-slider-tooltip{position:absolute;left:-9999px;top:-9999px;visibility:visible;box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-tooltip *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rc-slider-tooltip-hidden{display:none}.rc-slider-tooltip-placement-top{padding:4px 0 8px}.rc-slider-tooltip-inner{padding:6px 2px;min-width:24px;height:24px;font-size:12px;line-height:1;color:#fff;text-align:center;text-decoration:none;background-color:#6c6c6c;border-radius:6px;box-shadow:0 0 4px #d9d9d9}.rc-slider-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow{bottom:4px;left:50%;margin-left:-4px;border-width:4px 4px 0;border-top-color:#6c6c6c}.fastboard-root{position:relative;width:100%;height:100%;overflow:hidden}.fastboard-loading{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;opacity:.6}.fastboard-view{position:absolute;top:0;left:0;width:100%;height:100%}.fastboard-left{position:absolute;top:0;left:0;height:calc(100% - 48px);padding:16px;z-index:201;display:flex;align-items:center}.fastboard-bottom-left,.fastboard-bottom-right{display:flex;gap:10px;position:absolute;bottom:8px;left:8px;padding:8px;z-index:200}.fastboard-bottom-right{left:initial;right:8px}.fastboard-redo-undo{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-redo-undo.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-redo-undo.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-redo-undo-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-redo-undo-btn svg,.fastboard-redo-undo-btn img{width:1em;height:1em}.fastboard-redo-undo-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-redo-undo-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-redo-undo-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-page-control{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-page-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-page-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-page-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-page-control-btn svg,.fastboard-page-control-btn img{width:1em;height:1em}.fastboard-page-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-page-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-page-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-page-control-cut-line{height:24px;width:.5px}.fastboard-page-control-cut-line.light{background-color:#e7e7e7}.fastboard-page-control-cut-line.dark{background-color:#ffffff26}.fastboard-page-control-slash{opacity:.6}.fastboard-page-control-page,.fastboard-page-control-slash,.fastboard-page-control-page-count{font-size:12px;font-variant-numeric:tabular-nums}.fastboard-zoom-control{position:relative;display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-zoom-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-zoom-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-zoom-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1}.fastboard-zoom-control-btn svg,.fastboard-zoom-control-btn img{width:1em;height:1em}.fastboard-zoom-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-zoom-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-zoom-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-zoom-control-cut-line{height:24px;width:.5px}.fastboard-zoom-control-cut-line.light{background-color:#e7e7e7}.fastboard-zoom-control-cut-line.dark{background-color:#ffffff26}.fastboard-zoom-control-percent{opacity:.6}.fastboard-zoom-control-scale,.fastboard-zoom-control-percent{font-size:12px;font-variant-numeric:tabular-nums}.fastboard-toolbar{display:flex;align-items:center;padding:4px;border-radius:4px;flex-direction:column;gap:4px;position:absolute;z-index:100;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-toolbar .rc-slider{padding:6px 0}.fastboard-toolbar .rc-slider-rail,.fastboard-toolbar .rc-slider-track{height:2px}.fastboard-toolbar .tippy-content{padding:8px}.fastboard-toolbar .tippy-box{border:1px solid rgba(0,0,0,.15);background-color:#333333f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-toolbar .tippy-box[data-theme~=light]{background-color:#fffffff2;box-shadow:0 5px 10px #00000040}.fastboard-toolbar.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-toolbar.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-toolbar-tooltip{display:inline-flex;align-items:center;gap:4px}.fastboard-toolbar-hotkey{margin-right:-4px;width:24px;height:24px;border-radius:4px;background-color:#ffffff1a;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:4px;width:32px;height:32px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1;position:relative}.fastboard-toolbar-btn-interactive{display:inline-block;width:32px;height:32px}.fastboard-toolbar-btn svg,.fastboard-toolbar-btn img{width:1em;height:1em}.fastboard-toolbar-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-toolbar-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-toolbar-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-toolbar-triangle{width:0px;height:0px;border-bottom:4px solid;border-left:4px solid transparent;position:absolute;bottom:0;right:0}.fastboard-toolbar-cut-line{display:inline-block;height:.5px;width:100%}.fastboard-toolbar-cut-line.light{background-color:#e7e7e7}.fastboard-toolbar-cut-line.dark{background-color:#ffffff26}.fastboard-toolbar-section{display:inline-flex;flex-flow:column nowrap;gap:4px;scroll-behavior:smooth}.fastboard-toolbar-panel{width:120px;padding:0;display:flex;flex-flow:column nowrap;align-items:center;gap:8px}.fastboard-toolbar-panel.apps{width:224px}.fastboard-toolbar-color-box,.fastboard-toolbar-shapes{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;align-items:center;justify-items:center}.fastboard-toolbar-color-box .fastboard-toolbar-btn,.fastboard-toolbar-shapes .fastboard-toolbar-btn{padding:0;width:24px;height:24px}.fastboard-toolbar-apps{width:100%;display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-items:center;justify-items:center}.fastboard-toolbar-apps .fastboard-toolbar-btn{width:40px;height:40px;font-size:40px}.fastboard-toolbar-app-icon{padding-top:4px;display:inline-flex;flex-flow:column nowrap;align-items:center;gap:4px}.fastboard-toolbar-app-icon .fastboard-toolbar-btn{padding:0}.fastboard-toolbar-app-icon-text{font-size:12px;color:#5d5d5d;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.fastboard-toolbar-color-item{width:24px;height:24px;border-radius:4px;cursor:pointer}.fastboard-toolbar-color-item *.light:hover{background-color:#f5f5f5}.fastboard-toolbar-color-item *.dark:hover{background-color:#333}.fastboard-toolbar-color-border{width:24px;height:24px;border:1px solid transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center}.fastboard-toolbar-color-border.active.light,.fastboard-toolbar-color-border.active.dark{border:1px solid rgba(51,129,255,.8)}.fastboard-toolbar-color-btn{margin:0;border:1px solid rgba(0,0,0,.24);padding:0;appearance:none;width:16px;height:16px;border-radius:4px;cursor:pointer}.fastboard-toolbar-color-btn:focus-visible{outline-offset:2px}.fastboard-player-control{width:100%;display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:4px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-player-control.auto-hide{opacity:0;transition:opacity .2s}.fastboard-player-control.auto-hide:hover{opacity:1}.fastboard-player-control .rc-slider-disabled{background:transparent;opacity:.5}.fastboard-player-control .rc-slider-rail,.fastboard-player-control .rc-slider-track{height:2px}.fastboard-player-control .tippy-content{padding:8px}.fastboard-player-control .tippy-box{border:1px solid rgba(0,0,0,.15);background-color:#333333f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.fastboard-player-control .tippy-box[data-theme~=light]{background-color:#fffffff2;box-shadow:0 5px 10px #00000040}.fastboard-player-control.light{color:#333;background-color:#ffffffd9;border:1px solid rgba(0,0,0,.15)}.fastboard-player-control.dark{color:#ddd;background-color:#333333d9;border:1px solid rgba(0,0,0,.45)}.fastboard-player-control-btn{appearance:none;cursor:pointer;margin:0;border:0;padding:0;min-width:24px;height:24px;background-color:transparent;border-radius:4px;font-size:24px;line-height:1;display:inline-flex;align-items:center;justify-content:center}.fastboard-player-control-btn svg,.fastboard-player-control-btn img{width:1em;height:1em}.fastboard-player-control-btn:disabled{opacity:.5;cursor:not-allowed}.fastboard-player-control-btn.light:not(:disabled):hover{background-color:#3381ff1a}.fastboard-player-control-btn.dark:not(:disabled):hover{background-color:#3381ff40}.fastboard-player-control-btn.loading{animation:fastboard-player-control-rotate .5s linear infinite}@keyframes fastboard-player-control-rotate{to{transform:rotate(360deg)}}.fastboard-player-control-panel{padding:0;display:flex;flex-flow:column nowrap;align-items:stretch;gap:4px}.fastboard-player-control-panel .fastboard-player-control-btn{width:initial;height:initial;user-select:none;font-size:12px;padding:4px;justify-content:flex-end}.fastboard-player-control-panel .fastboard-player-control-btn.active{color:#3381ff}.fastboard-player-control-slider{width:100%;padding:0 7px}.fastboard-player-control-slider.loading{cursor:not-allowed}.fastboard-player-control-slash{opacity:.6}.fastboard-player-control-current,.fastboard-player-control-slash,.fastboard-player-control-total,.fastboard-player-control-speed-text{font-size:12px;font-variant-numeric:tabular-nums}.tippy-box.fastboard-tip{color:#eee;background-color:#000000f2;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.tippy-box.fastboard-tip[data-placement^=right]>.tippy-arrow:before{top:4px;border-width:4px;border-right-color:#000}.tippy-box.fastboard-tip[data-placement^=top]>.tippy-arrow:before{left:4px;border-width:4px;border-top-color:#000}\n';
2191
+ applyStyles(style);
2145
2192
  class WhiteboardApp {
2146
2193
  constructor(config) {
2147
2194
  __publicField(this, "_instance");
2195
+ __publicField(this, "_target", null);
2148
2196
  this.config = config;
2149
2197
  this._instance = new Instance(config);
2150
2198
  }
2199
+ get target() {
2200
+ return this._target;
2201
+ }
2202
+ get room() {
2203
+ return this._instance.room;
2204
+ }
2205
+ get manager() {
2206
+ return this._instance.manager;
2207
+ }
2208
+ get sdk() {
2209
+ return this._instance.sdk;
2210
+ }
2211
+ get i18n() {
2212
+ return this._instance.i18n;
2213
+ }
2214
+ bindElement(target) {
2215
+ this._target = target || null;
2216
+ this._instance.target = target || null;
2217
+ }
2151
2218
  insertDocs(params) {
2152
2219
  return this._instance.insertDocs(params);
2153
2220
  }
2221
+ insertCodeEditor() {
2222
+ return this._instance.insertCodeEditor();
2223
+ }
2224
+ insertGeoGebra() {
2225
+ return this._instance.insertGeoGebra();
2226
+ }
2227
+ insertCountdown() {
2228
+ return this._instance.insertCountdown();
2229
+ }
2154
2230
  changeLanguage(language) {
2155
- var _a;
2156
- return (_a = this._instance.changeLanguage(language)) == null ? void 0 : _a.finally(() => {
2157
- this._instance.forceUpdate();
2158
- });
2231
+ return this._instance.changeLanguage(language);
2159
2232
  }
2160
2233
  dispose() {
2161
2234
  return this._instance.dispose();
2162
2235
  }
2163
2236
  }
2164
- const version = "0.0.1";
2237
+ const version = "0.0.5";
2238
+ const EMPTY_ARRAY = [];
2239
+ function useForceUpdate() {
2240
+ const [, forceUpdate_] = useState({});
2241
+ return useCallback(() => forceUpdate_({}), EMPTY_ARRAY);
2242
+ }
2243
+ function useLastValue(value) {
2244
+ const ref = useRef(value);
2245
+ useEffect(() => {
2246
+ ref.current = value;
2247
+ }, [value]);
2248
+ return ref.current;
2249
+ }
2250
+ function usePlayer(player) {
2251
+ const togglePlay = useCallback(() => {
2252
+ if (player) {
2253
+ switch (player.phase) {
2254
+ case PlayerPhase.WaitingFirstFrame:
2255
+ case PlayerPhase.Pause:
2256
+ case PlayerPhase.Ended: {
2257
+ player.play();
2258
+ break;
2259
+ }
2260
+ case PlayerPhase.Playing: {
2261
+ player.pause();
2262
+ break;
2263
+ }
2264
+ }
2265
+ }
2266
+ }, [player]);
2267
+ const seekToProgressTime = useCallback((time) => {
2268
+ if (player) {
2269
+ player.seekToProgressTime(time);
2270
+ }
2271
+ }, [player]);
2272
+ const lastPlayer = useLastValue(player);
2273
+ const forceUpdate = useForceUpdate();
2274
+ const setSpeed = useCallback((speed2) => {
2275
+ if (player) {
2276
+ player.playbackSpeed = speed2;
2277
+ forceUpdate();
2278
+ }
2279
+ }, [forceUpdate, player]);
2280
+ useEffect(() => {
2281
+ if (!lastPlayer && player) {
2282
+ forceUpdate();
2283
+ }
2284
+ }, [forceUpdate, lastPlayer, player]);
2285
+ useEffect(() => {
2286
+ if (player) {
2287
+ player.callbacks.on("onPhaseChanged", forceUpdate);
2288
+ player.callbacks.on("onProgressTimeChanged", forceUpdate);
2289
+ return () => {
2290
+ player.callbacks.off("onPhaseChanged", forceUpdate);
2291
+ player.callbacks.off("onProgressTimeChanged", forceUpdate);
2292
+ };
2293
+ }
2294
+ }, [forceUpdate, player]);
2295
+ const phase = player ? player.phase : PlayerPhase.WaitingFirstFrame;
2296
+ const currentTime = player ? player.progressTime : 0;
2297
+ const totalTime = player ? player.timeDuration : 0;
2298
+ const speed = player ? player.playbackSpeed : 1;
2299
+ return {
2300
+ phase,
2301
+ currentTime,
2302
+ totalTime,
2303
+ speed,
2304
+ setSpeed,
2305
+ togglePlay,
2306
+ seekToProgressTime
2307
+ };
2308
+ }
2309
+ const Loading = (props) => {
2310
+ const stroke = getStroke(props);
2311
+ return /* @__PURE__ */ jsx("svg", {
2312
+ viewBox: "0 0 24 24",
2313
+ children: /* @__PURE__ */ jsx("path", {
2314
+ d: "M12 4V2A10 10 0 0 0 2 12h2a8 8 0 0 1 8-8z",
2315
+ fill: stroke
2316
+ })
2317
+ });
2318
+ };
2319
+ const Pause = (props) => {
2320
+ const stroke = getStroke(props);
2321
+ return /* @__PURE__ */ jsx("svg", {
2322
+ viewBox: "0 0 24 24",
2323
+ children: /* @__PURE__ */ jsx("path", {
2324
+ d: "M14 19h4V5h-4M6 19h4V5H6v14z",
2325
+ fill: stroke
2326
+ })
2327
+ });
2328
+ };
2329
+ const Play = (props) => {
2330
+ const stroke = getStroke(props);
2331
+ return /* @__PURE__ */ jsx("svg", {
2332
+ viewBox: "0 0 24 24",
2333
+ children: /* @__PURE__ */ jsx("path", {
2334
+ d: "M8 5.14v14l11-7l-11-7z",
2335
+ fill: stroke
2336
+ })
2337
+ });
2338
+ };
2339
+ const Icons = {
2340
+ Play: memo(Play),
2341
+ Pause: memo(Pause),
2342
+ Loading: memo(Loading)
2343
+ };
2344
+ const Button = forwardRef((props, ref) => {
2345
+ const {
2346
+ theme,
2347
+ content,
2348
+ disabled,
2349
+ active,
2350
+ onClick,
2351
+ interactive,
2352
+ placement = "top",
2353
+ children
2354
+ } = props;
2355
+ return /* @__PURE__ */ jsx(Tippy, {
2356
+ className: "fastboard-tip",
2357
+ content,
2358
+ interactive,
2359
+ theme,
2360
+ disabled,
2361
+ placement,
2362
+ offset: TopOffset,
2363
+ duration: 300,
2364
+ children: /* @__PURE__ */ jsx("button", {
2365
+ ref,
2366
+ className: clsx("fastboard-player-control-btn", theme, {
2367
+ active
2368
+ }),
2369
+ onClick,
2370
+ disabled,
2371
+ children
2372
+ })
2373
+ });
2374
+ });
2375
+ const name = "fastboard-player-control";
2376
+ function PlayerControl(_a) {
2377
+ var _b = _a, {
2378
+ autoHide = false,
2379
+ player: player_,
2380
+ theme = "light",
2381
+ i18n
2382
+ } = _b, icons = __objRest(_b, [
2383
+ "autoHide",
2384
+ "player",
2385
+ "theme",
2386
+ "i18n"
2387
+ ]);
2388
+ const [currentTime, setCurrentTime] = useState(0);
2389
+ const player = usePlayer(player_);
2390
+ useEffect(() => {
2391
+ setCurrentTime(player.currentTime);
2392
+ }, [player.currentTime]);
2393
+ useEffect(() => {
2394
+ if (player.currentTime !== currentTime) {
2395
+ player.seekToProgressTime(currentTime);
2396
+ }
2397
+ }, [currentTime]);
2398
+ const isLoading = player.phase === PlayerPhase.WaitingFirstFrame || player.phase === PlayerPhase.Buffering;
2399
+ const isPlaying = player.phase === PlayerPhase.Playing;
2400
+ const {
2401
+ activeColor
2402
+ } = themes[theme];
2403
+ return /* @__PURE__ */ jsxs("div", {
2404
+ className: clsx(name, theme, {
2405
+ "auto-hide": autoHide
2406
+ }),
2407
+ children: [/* @__PURE__ */ jsx("button", {
2408
+ className: clsx(`${name}-btn`, isLoading ? "loading" : isPlaying ? "pause" : "play", theme),
2409
+ disabled: isLoading,
2410
+ onClick: player.togglePlay,
2411
+ children: /* @__PURE__ */ jsx(Icon, {
2412
+ fallback: isLoading ? /* @__PURE__ */ jsx(Icons.Loading, {
2413
+ theme
2414
+ }) : isPlaying ? /* @__PURE__ */ jsx(Icons.Pause, {
2415
+ theme
2416
+ }) : /* @__PURE__ */ jsx(Icons.Play, {
2417
+ theme
2418
+ }),
2419
+ src: isLoading ? icons.loadingIcon : isPlaying ? icons.pauseIcon : icons.playIcon,
2420
+ alt: isLoading ? "[loading]" : isPlaying ? "[pause]" : "[play]"
2421
+ })
2422
+ }), /* @__PURE__ */ jsx("span", {
2423
+ className: clsx(`${name}-slider`, {
2424
+ loading: isLoading
2425
+ }, theme),
2426
+ children: /* @__PURE__ */ jsx(RcSlider, {
2427
+ disabled: isLoading,
2428
+ trackStyle: {
2429
+ background: activeColor
2430
+ },
2431
+ handleStyle: {
2432
+ border: `1px solid ${activeColor}`
2433
+ },
2434
+ value: currentTime,
2435
+ onChange: setCurrentTime,
2436
+ min: 0,
2437
+ max: player.totalTime,
2438
+ step: 100
2439
+ })
2440
+ }), /* @__PURE__ */ jsx("span", {
2441
+ className: clsx(`${name}-current`, theme),
2442
+ children: renderTime(player.currentTime)
2443
+ }), /* @__PURE__ */ jsx("span", {
2444
+ className: clsx(`${name}-slash`, theme),
2445
+ children: "/"
2446
+ }), /* @__PURE__ */ jsx("span", {
2447
+ className: clsx(`${name}-total`, theme),
2448
+ children: renderTime(player.totalTime)
2449
+ }), /* @__PURE__ */ jsx("span", {
2450
+ className: `${name}-btn-interactive`,
2451
+ children: /* @__PURE__ */ jsx(Tippy, {
2452
+ className: "fastboard-tip",
2453
+ content: renderSpeeds(player),
2454
+ theme,
2455
+ placement: "top-end",
2456
+ trigger: "click",
2457
+ offset: TopOffset,
2458
+ arrow: false,
2459
+ interactive: true,
2460
+ children: /* @__PURE__ */ jsx(Button, {
2461
+ content: i18n == null ? void 0 : i18n.t("speed"),
2462
+ theme,
2463
+ disabled: isLoading,
2464
+ children: /* @__PURE__ */ jsxs("span", {
2465
+ className: clsx(`${name}-speed-text`, theme),
2466
+ children: [player.speed, "x"]
2467
+ })
2468
+ })
2469
+ })
2470
+ })]
2471
+ });
2472
+ }
2473
+ function renderTime(ms) {
2474
+ let seconds = ms / 1e3;
2475
+ const minutes = Math.floor(seconds / 60);
2476
+ seconds = Math.floor(seconds) % 60;
2477
+ return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
2478
+ }
2479
+ const Speeds = [2, 1.5, 1.25, 1, 0.75, 0.5];
2480
+ function renderSpeeds({
2481
+ speed: current,
2482
+ setSpeed
2483
+ }) {
2484
+ return /* @__PURE__ */ jsx("div", {
2485
+ className: clsx(`${name}-panel`, "speed"),
2486
+ children: Speeds.map((speed) => /* @__PURE__ */ jsxs("button", {
2487
+ className: clsx(`${name}-btn`, "speed", {
2488
+ active: speed === current
2489
+ }),
2490
+ onClick: () => setSpeed(speed),
2491
+ children: [speed, "x"]
2492
+ }, speed))
2493
+ });
2494
+ }
2165
2495
  function useFastboard(config) {
2166
2496
  const [app, setApp] = useState(null);
2167
2497
  const [currentTarget, ref] = useState(null);
2168
- const working = useRef({
2169
- app: void 0,
2170
- type: void 0,
2171
- next: void 0
2172
- });
2173
2498
  useEffect(() => {
2174
- if (working.current.type) {
2175
- working.current.next = currentTarget;
2176
- return;
2499
+ let isMounted = true;
2500
+ const promise = createWhiteboardApp(config).then((app2) => {
2501
+ if (isMounted)
2502
+ setApp(app2);
2503
+ });
2504
+ return () => {
2505
+ isMounted = false;
2506
+ promise.then(() => app == null ? void 0 : app.dispose());
2507
+ };
2508
+ }, []);
2509
+ useEffect(() => {
2510
+ if (app) {
2511
+ app.bindElement(currentTarget);
2177
2512
  }
2178
- (async () => {
2179
- let target = currentTarget;
2180
- do {
2181
- if (target) {
2182
- working.current.type = "creating";
2183
- if (working.current.app) {
2184
- await working.current.app.dispose();
2185
- }
2186
- working.current.app = await createWhiteboardApp(__spreadProps(__spreadValues({}, config), {
2187
- target
2188
- }));
2189
- setApp(working.current.app);
2190
- } else if (target === null) {
2191
- working.current.type = "disposing";
2192
- if (working.current.app) {
2193
- await working.current.app.dispose();
2194
- working.current.app = void 0;
2195
- }
2196
- setApp(null);
2197
- }
2198
- working.current.type = void 0;
2199
- target = working.current.next;
2200
- working.current.next = void 0;
2201
- } while (target !== void 0);
2202
- })();
2203
- }, [config, currentTarget]);
2513
+ }, [app, currentTarget]);
2204
2514
  return Object.assign([app, ref], { app, ref });
2205
2515
  }
2206
2516
  const register = WindowManager.register.bind(WindowManager);
@@ -2209,5 +2519,5 @@ async function createWhiteboardApp(config) {
2209
2519
  await app._instance.readyPromise;
2210
2520
  return app;
2211
2521
  }
2212
- export { PageControl, RedoUndo, Toolbar, WhiteboardApp, ZoomControl, createWhiteboardApp, register, useFastboard, version };
2522
+ export { PageControl, PlayerControl, RedoUndo, Toolbar, WhiteboardApp, ZoomControl, createWhiteboardApp, register, useFastboard, version };
2213
2523
  //# sourceMappingURL=index.es.js.map