@zero-library/common 2.4.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -33,6 +33,8 @@ var zh_CN = require('@react-pdf-viewer/locales/lib/zh_CN.json');
33
33
  require('@react-pdf-viewer/page-navigation/lib/styles/index.css');
34
34
  require('@react-pdf-viewer/thumbnail/lib/styles/index.css');
35
35
  require('@react-pdf-viewer/zoom/lib/styles/index.css');
36
+ var microApp = require('@micro-zoe/micro-app');
37
+ var jsxCustomEvent = require('@micro-zoe/micro-app/polyfill/jsx-custom-event');
36
38
  var react = require('@tiptap/react');
37
39
  var extensionHighlight = require('@tiptap/extension-highlight');
38
40
  var extensionImage = require('@tiptap/extension-image');
@@ -94,6 +96,8 @@ var axios__default = /*#__PURE__*/_interopDefault(axios);
94
96
  var markdownItKatex__default = /*#__PURE__*/_interopDefault(markdownItKatex);
95
97
  var parse__default = /*#__PURE__*/_interopDefault(parse);
96
98
  var zh_CN__default = /*#__PURE__*/_interopDefault(zh_CN);
99
+ var microApp__default = /*#__PURE__*/_interopDefault(microApp);
100
+ var jsxCustomEvent__default = /*#__PURE__*/_interopDefault(jsxCustomEvent);
97
101
  var TiptapHorizontalRule__default = /*#__PURE__*/_interopDefault(TiptapHorizontalRule);
98
102
  var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
99
103
  var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
@@ -1117,6 +1121,10 @@ function createRequest(config) {
1117
1121
  // 默认基础URL
1118
1122
  timeout: 6e4,
1119
1123
  // 请求超时时间设为60秒
1124
+ paramsSerializer: {
1125
+ // 自定义序列化参数,处理数组格式为 key=value&key=value
1126
+ serialize: (params) => buildUrlParams(params)
1127
+ },
1120
1128
  ...config
1121
1129
  // 合并传入的配置项
1122
1130
  });
@@ -1145,6 +1153,9 @@ function createRequest(config) {
1145
1153
  return response;
1146
1154
  },
1147
1155
  function(err) {
1156
+ if (axios__default.default.isCancel(err)) {
1157
+ return Promise.reject(err);
1158
+ }
1148
1159
  if (!err.response) {
1149
1160
  if (showError(err?.config?.showError)) cachedMessage({ content: "\u7F51\u7EDC\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC", type: "error" });
1150
1161
  } else {
@@ -1393,7 +1404,7 @@ var LazyComponent_default = ({ type, customComponents, unknownContent, ...rest }
1393
1404
  lazyCache.set(type, component);
1394
1405
  return component;
1395
1406
  }, [loader]);
1396
- if (!LazyComponent) return unknownContent || /* @__PURE__ */ jsxRuntime.jsx(antd.Alert, { message: `\u672A\u77E5\u7C7B\u578B\uFF1A${type}`, type: "warning" });
1407
+ if (!LazyComponent) return unknownContent || /* @__PURE__ */ jsxRuntime.jsx(antd.Alert, { title: `\u672A\u77E5\u7C7B\u578B\uFF1A${type}`, type: "warning" });
1397
1408
  return /* @__PURE__ */ jsxRuntime.jsx(
1398
1409
  React.Suspense,
1399
1410
  {
@@ -1570,9 +1581,9 @@ ${fence}`;
1570
1581
  function emit(type, data, to = "top") {
1571
1582
  const payload = { type, data, to };
1572
1583
  try {
1573
- window.parent.postMessage(payload, "*");
1584
+ window.postMessage(payload, "*");
1574
1585
  } catch (err) {
1575
- console.warn("emit parent failed", err);
1586
+ console.warn("emit failed", err);
1576
1587
  }
1577
1588
  }
1578
1589
  function emitToChild(iframeWindow, type, data, origin = "*") {
@@ -1587,33 +1598,91 @@ function emitToChild(iframeWindow, type, data, origin = "*") {
1587
1598
  console.warn("emit to child failed", err);
1588
1599
  }
1589
1600
  }
1590
- var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
1591
- const handlers = React.useRef({});
1592
- React.useEffect(() => {
1593
- const onMessage = (evt) => {
1594
- const { data, source, origin } = evt;
1595
- if (!data || !isObject(data) || !data.type) return;
1596
- if (allowedOrigins[0] !== "*" && !allowedOrigins.includes(origin)) return;
1597
- const { type, data: params, to = "parent" } = data;
1598
- const isTop = window.parent === window;
1599
- if (to === "top" && !isTop) {
1600
- window.parent.postMessage(data, allowedOrigins[0] === "*" ? "*" : origin);
1601
- return;
1601
+ var hookInstances = /* @__PURE__ */ new Set();
1602
+ var handleGlobalMessage = (evt) => {
1603
+ const { data, source, origin } = evt;
1604
+ if (!data || !isObject(data) || !data.type) return;
1605
+ const { type, data: params, to = "top" } = data;
1606
+ const safeOrigin = origin || "*";
1607
+ const fns = [];
1608
+ let isAllowed = hookInstances.size === 0;
1609
+ hookInstances.forEach((ctx) => {
1610
+ const isMatch = ctx.allowedOrigins[0] === "*" || ctx.allowedOrigins.includes(safeOrigin);
1611
+ if (isMatch) {
1612
+ isAllowed = true;
1613
+ if (ctx.handlers[type]) {
1614
+ fns.push(...ctx.handlers[type]);
1602
1615
  }
1603
- const fns = handlers.current[type] || [];
1604
- fns.forEach((fn) => fn(params, source, origin));
1605
- };
1606
- window.addEventListener("message", onMessage);
1607
- return () => window.removeEventListener("message", onMessage);
1608
- }, [allowedOrigins]);
1609
- function on(type, handler) {
1610
- handlers.current[type] = handlers.current[type] || [];
1611
- handlers.current[type].push(handler);
1616
+ }
1617
+ });
1618
+ if (!isAllowed) return;
1619
+ const isTop = window.parent === window;
1620
+ const hasHandler = fns.length > 0;
1621
+ let shouldExecute = false;
1622
+ let shouldForward = false;
1623
+ switch (to) {
1624
+ case "nearest":
1625
+ shouldExecute = hasHandler;
1626
+ shouldForward = !hasHandler && !isTop;
1627
+ break;
1628
+ case "broadcast":
1629
+ shouldExecute = true;
1630
+ shouldForward = !isTop;
1631
+ break;
1632
+ case "top":
1633
+ shouldExecute = isTop;
1634
+ shouldForward = !isTop;
1635
+ break;
1636
+ case "parent":
1637
+ shouldExecute = true;
1638
+ shouldForward = source === window && !isTop;
1639
+ break;
1640
+ case "sibling":
1641
+ case "child":
1642
+ default:
1643
+ shouldExecute = true;
1644
+ shouldForward = false;
1645
+ break;
1612
1646
  }
1613
- function off(type, handler) {
1614
- handlers.current[type] = (handlers.current[type] || []).filter((fn) => fn !== handler);
1647
+ if (shouldExecute && hasHandler) {
1648
+ fns.forEach((fn) => fn(params, source, origin));
1649
+ }
1650
+ if (shouldForward && !isTop && window.parent !== window) {
1651
+ try {
1652
+ window.parent.postMessage(data, "*");
1653
+ } catch (err) {
1654
+ console.warn("IframeRelayBridge forward failed:", err);
1655
+ }
1615
1656
  }
1616
- return { on, off };
1657
+ };
1658
+ if (window) {
1659
+ window.addEventListener("message", handleGlobalMessage);
1660
+ }
1661
+ var useIframeRelayBridge_default = (allowedOrigins = ["*"]) => {
1662
+ const ctxRef = React.useRef({
1663
+ handlers: {},
1664
+ allowedOrigins
1665
+ });
1666
+ ctxRef.current.allowedOrigins = allowedOrigins;
1667
+ React.useEffect(() => {
1668
+ const ctx = ctxRef.current;
1669
+ hookInstances.add(ctx);
1670
+ return () => {
1671
+ hookInstances.delete(ctx);
1672
+ };
1673
+ }, []);
1674
+ const on = React.useCallback((type, handler) => {
1675
+ const handlers = ctxRef.current.handlers;
1676
+ handlers[type] = handlers[type] || [];
1677
+ handlers[type].push(handler);
1678
+ }, []);
1679
+ const off = React.useCallback((type, handler) => {
1680
+ const handlers = ctxRef.current.handlers;
1681
+ if (handlers[type]) {
1682
+ handlers[type] = handlers[type].filter((fn) => fn !== handler);
1683
+ }
1684
+ }, []);
1685
+ return React.useMemo(() => ({ on, off }), [on, off]);
1617
1686
  };
1618
1687
  var useRefState_default = (init) => {
1619
1688
  const [state, setState] = React.useState(init);
@@ -1832,140 +1901,325 @@ var useThrottle_default = (func, wait) => {
1832
1901
  throttle2.cancel = cancel;
1833
1902
  return React.useCallback(throttle2, []);
1834
1903
  };
1835
- var useWebSocket_default = ({
1836
- url,
1837
- onMessage,
1838
- onClose,
1839
- heartbeatInterval = 3e4,
1840
- heartbeatMessage = "ping",
1841
- clientHeartbeat = true,
1842
- reconnectInterval = 5e3,
1843
- maxReconnectAttempts,
1844
- isReconnect = true
1845
- }) => {
1846
- const socketRef = React.useRef(null);
1847
- const heartbeatIntervalRef = React.useRef(null);
1848
- const [socketReadyState, setSocketReadyState] = React.useState(null);
1849
- const reconnectIntervalRef = React.useRef(null);
1850
- const reconnectAttempts = React.useRef(0);
1851
- const documentHide = React.useRef(document.visibilityState === "hidden");
1852
- const isDestroy = React.useRef(false);
1853
- const onMessageEctype = React.useCallback(onMessage, [onMessage]);
1854
- const startHeartbeat = (currentSocket) => {
1855
- if (!clientHeartbeat) {
1856
- return;
1857
- }
1904
+
1905
+ // src/hooks/webSocket/WebSocketManager.ts
1906
+ var WebSocketManager = class _WebSocketManager {
1907
+ /** 存储不同 URL 对应的 WebSocketManager 单例实例 */
1908
+ static instances = /* @__PURE__ */ new Map();
1909
+ /** 当前 WebSocket 的服务器地址 */
1910
+ url;
1911
+ /** WebSocket 原生实例 */
1912
+ socket = null;
1913
+ /** 当前连接状态 */
1914
+ readyState = null;
1915
+ /** 当前连接的所有订阅者(监听器)集合 */
1916
+ listeners = /* @__PURE__ */ new Set();
1917
+ // --- 配置参数 ---
1918
+ heartbeatInterval;
1919
+ heartbeatMessage;
1920
+ clientHeartbeat;
1921
+ reconnectInterval;
1922
+ maxReconnectAttempts;
1923
+ isReconnect;
1924
+ // --- 内部状态与定时器 ---
1925
+ /** 心跳定时器引用 */
1926
+ heartbeatIntervalRef = null;
1927
+ /** 重连定时器引用 */
1928
+ reconnectIntervalRef = null;
1929
+ /** 销毁防抖定时器引用(用于避免 React StrictMode 导致的连接抖动) */
1930
+ destroyTimeoutRef = null;
1931
+ /** 当前已尝试重连的次数 */
1932
+ reconnectAttempts = 0;
1933
+ /** 记录页面是否处于隐藏状态 */
1934
+ documentHide = document.visibilityState === "hidden";
1935
+ /** 标记实例是否已被销毁,防止销毁后继续重连 */
1936
+ isDestroy = false;
1937
+ /**
1938
+ * 私有构造函数,确保只能通过 getInstance 获取实例
1939
+ */
1940
+ constructor(props) {
1941
+ this.url = props.url;
1942
+ this.heartbeatInterval = props.heartbeatInterval ?? 3e4;
1943
+ this.heartbeatMessage = props.heartbeatMessage ?? "ping";
1944
+ this.clientHeartbeat = props.clientHeartbeat ?? true;
1945
+ this.reconnectInterval = props.reconnectInterval ?? 5e3;
1946
+ this.maxReconnectAttempts = props.maxReconnectAttempts;
1947
+ this.isReconnect = props.isReconnect ?? true;
1948
+ window.addEventListener("visibilitychange", this.handleVisibilityChange);
1949
+ this.createAndListenWebSocket();
1950
+ }
1951
+ /**
1952
+ * 获取指定 URL 的 WebSocketManager 单例
1953
+ * @param props WebSocket 配置参数
1954
+ * @returns WebSocketManager 实例
1955
+ */
1956
+ static getInstance(props) {
1957
+ if (!_WebSocketManager.instances.has(props.url)) {
1958
+ _WebSocketManager.instances.set(props.url, new _WebSocketManager(props));
1959
+ }
1960
+ return _WebSocketManager.instances.get(props.url);
1961
+ }
1962
+ /**
1963
+ * 添加监听器(组件挂载时调用)
1964
+ * @param listener 组件级别的监听器
1965
+ */
1966
+ addListener(listener) {
1967
+ this.listeners.add(listener);
1968
+ if (this.destroyTimeoutRef) {
1969
+ clearTimeout(this.destroyTimeoutRef);
1970
+ this.destroyTimeoutRef = null;
1971
+ }
1972
+ listener.onStateChange(this.readyState);
1973
+ }
1974
+ /**
1975
+ * 移除监听器(组件卸载时调用)
1976
+ * @param listener 组件级别的监听器
1977
+ */
1978
+ removeListener(listener) {
1979
+ this.listeners.delete(listener);
1980
+ if (this.listeners.size === 0) {
1981
+ this.destroyTimeoutRef = setTimeout(() => {
1982
+ this.destroy();
1983
+ _WebSocketManager.instances.delete(this.url);
1984
+ }, 200);
1985
+ }
1986
+ }
1987
+ /**
1988
+ * 更新连接状态并广播给所有监听器
1989
+ */
1990
+ setSocketReadyState(state) {
1991
+ this.readyState = state;
1992
+ this.listeners.forEach((l) => l.onStateChange(state));
1993
+ }
1994
+ /**
1995
+ * 启动心跳机制
1996
+ */
1997
+ startHeartbeat = (currentSocket) => {
1998
+ if (!this.clientHeartbeat) return;
1999
+ this.stopHeartbeat();
1858
2000
  const intervalId = setInterval(() => {
1859
2001
  if (currentSocket.readyState === WebSocket.OPEN) {
1860
- currentSocket.send(heartbeatMessage);
2002
+ currentSocket.send(this.heartbeatMessage);
1861
2003
  }
1862
- }, heartbeatInterval);
1863
- heartbeatIntervalRef.current = intervalId;
2004
+ }, this.heartbeatInterval);
2005
+ this.heartbeatIntervalRef = intervalId;
2006
+ };
2007
+ /**
2008
+ * 停止心跳机制
2009
+ */
2010
+ stopHeartbeat = () => {
2011
+ if (this.heartbeatIntervalRef !== null) {
2012
+ clearInterval(this.heartbeatIntervalRef);
2013
+ this.heartbeatIntervalRef = null;
2014
+ }
1864
2015
  };
1865
- const stopHeartbeat = () => {
1866
- if (heartbeatIntervalRef.current) {
1867
- clearInterval(heartbeatIntervalRef.current);
1868
- heartbeatIntervalRef.current = null;
2016
+ /**
2017
+ * 停止重连定时器
2018
+ */
2019
+ stopReconnectTimer = () => {
2020
+ if (this.reconnectIntervalRef !== null) {
2021
+ clearTimeout(this.reconnectIntervalRef);
2022
+ this.reconnectIntervalRef = null;
1869
2023
  }
1870
2024
  };
1871
- const stopReconnectTimer = () => {
1872
- if (reconnectIntervalRef.current) {
1873
- clearTimeout(reconnectIntervalRef.current);
1874
- reconnectIntervalRef.current = null;
2025
+ /**
2026
+ * 重置心跳定时器
2027
+ */
2028
+ resetHeartbeat = (currentSocket = this.socket) => {
2029
+ if (!currentSocket) return;
2030
+ this.startHeartbeat(currentSocket);
2031
+ };
2032
+ /**
2033
+ * 广播消息给所有订阅者
2034
+ */
2035
+ emitMessage = (message3) => {
2036
+ this.listeners.forEach((listener) => listener.onMessage(message3));
2037
+ };
2038
+ /**
2039
+ * 解析消息内容,JSON 解析失败时回退为原始字符串
2040
+ */
2041
+ parseMessage = (data) => {
2042
+ try {
2043
+ return JSON.parse(data);
2044
+ } catch {
2045
+ return data;
1875
2046
  }
1876
2047
  };
1877
- const tryReconnect = () => {
1878
- if (isDestroy.current) return;
1879
- if (isReconnect && !documentHide.current) {
1880
- if ((!isNumber(maxReconnectAttempts) || reconnectAttempts.current < maxReconnectAttempts) && isNullOrUnDef(reconnectIntervalRef.current)) {
1881
- reconnectIntervalRef.current = setTimeout(() => {
1882
- console.log(`\u5C1D\u8BD5\u7B2C ${reconnectAttempts.current + 1} \u6B21\u91CD\u8FDE...`, url);
1883
- reconnectAttempts.current = reconnectAttempts.current + 1;
1884
- createAndListenWebSocket();
1885
- stopReconnectTimer();
1886
- }, reconnectInterval);
2048
+ /**
2049
+ * 尝试重新连接
2050
+ */
2051
+ tryReconnect = () => {
2052
+ if (this.isDestroy || this.listeners.size === 0) return;
2053
+ if (this.isReconnect && !this.documentHide) {
2054
+ if ((!isNumber(this.maxReconnectAttempts) || this.reconnectAttempts < this.maxReconnectAttempts) && this.reconnectIntervalRef === null) {
2055
+ this.reconnectIntervalRef = setTimeout(() => {
2056
+ this.reconnectIntervalRef = null;
2057
+ console.log(`\u5C1D\u8BD5\u7B2C ${this.reconnectAttempts + 1} \u6B21\u91CD\u8FDE...`, this.url);
2058
+ this.reconnectAttempts++;
2059
+ this.createAndListenWebSocket();
2060
+ }, this.reconnectInterval);
1887
2061
  } else {
1888
- if (isNumber(maxReconnectAttempts)) {
2062
+ if (isNumber(this.maxReconnectAttempts) && this.reconnectAttempts >= this.maxReconnectAttempts) {
1889
2063
  console.log("\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u5C1D\u8BD5\u6B21\u6570\uFF0C\u505C\u6B62\u91CD\u8FDE");
1890
2064
  }
1891
2065
  }
1892
2066
  }
1893
2067
  };
1894
- const handleOpen = (newSocket) => {
2068
+ /**
2069
+ * WebSocket onopen 事件处理
2070
+ */
2071
+ handleOpen = (newSocket) => {
1895
2072
  console.log("WebSocket \u8FDE\u63A5\u5DF2\u6253\u5F00");
1896
- setSocketReadyState(newSocket.readyState);
1897
- startHeartbeat(newSocket);
1898
- reconnectAttempts.current = 0;
2073
+ this.stopReconnectTimer();
2074
+ this.setSocketReadyState(newSocket.readyState);
2075
+ this.resetHeartbeat(newSocket);
2076
+ this.reconnectAttempts = 0;
1899
2077
  };
1900
- const handleMessage = (event) => {
1901
- if (isString(event.data)) {
1902
- try {
1903
- const parsedData = JSON.parse(event.data);
1904
- onMessageEctype?.(parsedData);
1905
- stopHeartbeat();
1906
- startHeartbeat(socketRef.current);
1907
- } catch (error) {
1908
- console.error("\u89E3\u6790\u6D88\u606F\u6570\u636E\u65F6\u51FA\u9519:", error);
1909
- }
1910
- }
2078
+ /**
2079
+ * WebSocket onmessage 事件处理
2080
+ */
2081
+ handleMessage = (event) => {
2082
+ const message3 = this.parseMessage(event.data);
2083
+ this.emitMessage(message3);
2084
+ this.resetHeartbeat();
1911
2085
  };
1912
- const handleClose = (event) => {
2086
+ /**
2087
+ * WebSocket onclose 事件处理
2088
+ */
2089
+ handleClose = (event) => {
1913
2090
  console.log("WebSocket \u8FDE\u63A5\u5DF2\u5173\u95ED", event.code, event.reason);
1914
- setSocketReadyState(event.code);
1915
- stopHeartbeat();
1916
- onClose?.();
1917
- tryReconnect();
2091
+ this.setSocketReadyState(WebSocket.CLOSED);
2092
+ this.stopHeartbeat();
2093
+ this.listeners.forEach((l) => l.onClose?.());
2094
+ this.tryReconnect();
1918
2095
  };
1919
- const handleError = (error) => {
2096
+ /**
2097
+ * WebSocket onerror 事件处理
2098
+ */
2099
+ handleError = (error) => {
1920
2100
  console.error("WebSocket \u53D1\u751F\u9519\u8BEF:", error);
1921
- setSocketReadyState(null);
1922
- stopHeartbeat();
1923
- tryReconnect();
2101
+ this.setSocketReadyState(null);
2102
+ this.stopHeartbeat();
2103
+ this.tryReconnect();
2104
+ };
2105
+ /**
2106
+ * 清理当前的 WebSocket 实例,取消所有事件绑定并关闭连接
2107
+ */
2108
+ cleanupSocket = (notifyClose = false) => {
2109
+ this.stopHeartbeat();
2110
+ if (this.socket) {
2111
+ this.socket.onopen = null;
2112
+ this.socket.onmessage = null;
2113
+ this.socket.onerror = null;
2114
+ if (!notifyClose) {
2115
+ this.socket.onclose = null;
2116
+ }
2117
+ if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {
2118
+ this.socket.close();
2119
+ }
2120
+ }
1924
2121
  };
1925
- const createAndListenWebSocket = () => {
1926
- const newSocket = new WebSocket(url);
1927
- socketRef.current = newSocket;
1928
- setSocketReadyState(newSocket.readyState);
1929
- newSocket.onopen = () => handleOpen(newSocket);
1930
- newSocket.onmessage = handleMessage;
1931
- newSocket.onclose = handleClose;
1932
- newSocket.onerror = handleError;
2122
+ /**
2123
+ * 创建新的 WebSocket 实例并绑定事件
2124
+ */
2125
+ createAndListenWebSocket = () => {
2126
+ this.cleanupSocket();
2127
+ const newSocket = new WebSocket(this.url);
2128
+ this.socket = newSocket;
2129
+ this.setSocketReadyState(newSocket.readyState);
2130
+ newSocket.onopen = () => this.handleOpen(newSocket);
2131
+ newSocket.onmessage = this.handleMessage;
2132
+ newSocket.onclose = this.handleClose;
2133
+ newSocket.onerror = this.handleError;
1933
2134
  };
1934
- const handleVisibilityChange = () => {
1935
- documentHide.current = document.visibilityState === "hidden";
1936
- if (socketRef.current?.readyState !== WebSocket.OPEN) {
1937
- tryReconnect();
2135
+ /**
2136
+ * 处理页面可见性变化
2137
+ * 页面隐藏时暂停部分活动,重新显示且断开时尝试重连
2138
+ */
2139
+ handleVisibilityChange = () => {
2140
+ this.documentHide = document.visibilityState === "hidden";
2141
+ if (!this.documentHide && (this.readyState === WebSocket.CLOSED || this.readyState === null)) {
2142
+ this.tryReconnect();
1938
2143
  }
1939
2144
  };
2145
+ /**
2146
+ * 供外部调用的发送消息方法
2147
+ * @param message 要发送的消息内容(字符串)
2148
+ */
2149
+ sendMessage = (message3) => {
2150
+ if (this.socket?.readyState === WebSocket.OPEN) {
2151
+ this.socket.send(message3);
2152
+ this.resetHeartbeat(this.socket);
2153
+ } else {
2154
+ console.warn("WebSocket \u672A\u8FDE\u63A5\uFF0C\u65E0\u6CD5\u53D1\u9001\u6D88\u606F:", message3);
2155
+ }
2156
+ };
2157
+ /**
2158
+ * 销毁当前实例,清理所有资源
2159
+ */
2160
+ destroy = () => {
2161
+ this.isDestroy = true;
2162
+ window.removeEventListener("visibilitychange", this.handleVisibilityChange);
2163
+ if (this.destroyTimeoutRef) {
2164
+ clearTimeout(this.destroyTimeoutRef);
2165
+ this.destroyTimeoutRef = null;
2166
+ }
2167
+ this.cleanupSocket(true);
2168
+ this.stopHeartbeat();
2169
+ this.stopReconnectTimer();
2170
+ };
2171
+ };
2172
+
2173
+ // src/hooks/webSocket/useWebSocket.ts
2174
+ var useWebSocket_default = ({
2175
+ url,
2176
+ onMessage,
2177
+ onClose,
2178
+ heartbeatInterval = 3e4,
2179
+ heartbeatMessage = "ping",
2180
+ clientHeartbeat = true,
2181
+ reconnectInterval = 5e3,
2182
+ maxReconnectAttempts,
2183
+ isReconnect = true
2184
+ }) => {
2185
+ const [socketReadyState, setSocketReadyState] = React.useState(null);
2186
+ const onMessageRef = React.useRef(onMessage);
2187
+ React.useEffect(() => {
2188
+ onMessageRef.current = onMessage;
2189
+ }, [onMessage]);
2190
+ const onCloseRef = React.useRef(onClose);
2191
+ React.useEffect(() => {
2192
+ onCloseRef.current = onClose;
2193
+ }, [onClose]);
2194
+ const managerRef = React.useRef(null);
1940
2195
  React.useEffect(() => {
1941
2196
  if (!url) return;
1942
- isDestroy.current = false;
1943
- createAndListenWebSocket();
1944
- window.addEventListener("visibilitychange", handleVisibilityChange);
2197
+ const manager = WebSocketManager.getInstance({
2198
+ url,
2199
+ heartbeatInterval,
2200
+ heartbeatMessage,
2201
+ clientHeartbeat,
2202
+ reconnectInterval,
2203
+ maxReconnectAttempts,
2204
+ isReconnect
2205
+ });
2206
+ managerRef.current = manager;
2207
+ const listener = {
2208
+ onMessage: (msg) => onMessageRef.current?.(msg),
2209
+ onClose: () => onCloseRef.current?.(),
2210
+ onStateChange: (state) => setSocketReadyState(state)
2211
+ };
2212
+ manager.addListener(listener);
1945
2213
  return () => {
1946
- window.removeEventListener("visibilitychange", handleVisibilityChange);
1947
- isDestroy.current = true;
1948
- if (socketRef.current) {
1949
- socketRef.current.close();
1950
- return;
1951
- }
1952
- stopHeartbeat();
1953
- stopReconnectTimer();
2214
+ manager.removeListener(listener);
2215
+ managerRef.current = null;
1954
2216
  };
1955
2217
  }, [url]);
1956
- const sendMessage = (message3) => {
1957
- if (socketRef.current?.readyState === WebSocket.OPEN) {
1958
- socketRef.current.send(message3);
1959
- stopHeartbeat();
1960
- startHeartbeat(socketRef.current);
1961
- } else {
1962
- console.warn("WebSocket \u672A\u8FDE\u63A5\uFF0C\u65E0\u6CD5\u53D1\u9001\u6D88\u606F:", message3);
1963
- }
1964
- };
2218
+ const sendMessage = React.useCallback((message3) => {
2219
+ managerRef.current?.sendMessage(message3);
2220
+ }, []);
1965
2221
  return {
1966
- /** 发送消息方法 */
1967
2222
  sendMessage,
1968
- /** Socket 连接状态 */
1969
2223
  socketReadyState
1970
2224
  };
1971
2225
  };
@@ -2198,7 +2452,7 @@ var ProtectedView = ({
2198
2452
  });
2199
2453
  };
2200
2454
  return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "center", align: "center", className: "height-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: 300 }, children: [
2201
- passwordStatus === core$1.PasswordStatus.WrongPassword && /* @__PURE__ */ jsxRuntime.jsx(antd.Alert, { message: "\u5BC6\u7801\u65E0\u6548\u3002\u8BF7\u518D\u8BD5\u4E00\u6B21\uFF01", type: "error" }),
2455
+ passwordStatus === core$1.PasswordStatus.WrongPassword && /* @__PURE__ */ jsxRuntime.jsx(antd.Alert, { title: "\u5BC6\u7801\u65E0\u6548\u3002\u8BF7\u518D\u8BD5\u4E00\u6B21\uFF01", type: "error" }),
2202
2456
  /* @__PURE__ */ jsxRuntime.jsxs(antd.Form, { form, size: "large", className: "m-t-24", children: [
2203
2457
  /* @__PURE__ */ jsxRuntime.jsx(antd.Form.Item, { name: "password", rules: [{ required: true, message: "\u8BF7\u8F93\u5165\u5BC6\u7801" }], children: /* @__PURE__ */ jsxRuntime.jsx(antd.Input.Password, { autoComplete: "new-password", placeholder: "\u8BF7\u8F93\u5165\u5BC6\u7801" }) }),
2204
2458
  /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { justify: "center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { type: "primary", onClick: onSubmit, children: "\u63D0 \u4EA4" }) })
@@ -2308,7 +2562,7 @@ var PdfPreview_default = ({ password, fileUrl, pageNo = 1, scale = 1, isHasThumb
2308
2562
  message3 = "\u65E0\u6CD5\u52A0\u8F7D\u6587\u6863";
2309
2563
  break;
2310
2564
  }
2311
- return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { className: "height-full", justify: "center", align: "center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Alert, { message: message3, type: "error", showIcon: true }) });
2565
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Flex, { className: "height-full", justify: "center", align: "center", children: /* @__PURE__ */ jsxRuntime.jsx(antd.Alert, { title: message3, type: "error", showIcon: true }) });
2312
2566
  };
2313
2567
  const onPageChange = (e) => {
2314
2568
  let newCurrentPage = e.currentPage;
@@ -2385,7 +2639,7 @@ var FilePreview_default = ({ suffix, fileUrl, pdfParams, password, searchValue,
2385
2639
  case "JPG":
2386
2640
  case "JPEG":
2387
2641
  case "GIF":
2388
- return /* @__PURE__ */ jsxRuntime.jsx(antd.Image, { rootClassName: styles_module_default.nsPreviewImage, src: fileUrl, alt: "\u9884\u89C8\u56FE\u7247" });
2642
+ return /* @__PURE__ */ jsxRuntime.jsx(antd.Image, { classNames: { root: styles_module_default.nsPreviewImage }, src: fileUrl, alt: "\u9884\u89C8\u56FE\u7247" });
2389
2643
  case "PDF":
2390
2644
  return /* @__PURE__ */ jsxRuntime.jsx(PdfPreview_default, { fileUrl, ...pdfParams, password, onSetPassword });
2391
2645
  case "PDF_IMG":
@@ -2416,7 +2670,7 @@ var FilePreviewDrawer_default = ({ open, title = "\u6587\u4EF6\u9884\u89C8", onC
2416
2670
  {
2417
2671
  title,
2418
2672
  push: false,
2419
- width: "100%",
2673
+ size: "100%",
2420
2674
  open,
2421
2675
  onClose,
2422
2676
  children: /* @__PURE__ */ jsxRuntime.jsx(FilePreview_default, { ...props })
@@ -2424,8 +2678,114 @@ var FilePreviewDrawer_default = ({ open, title = "\u6587\u4EF6\u9884\u89C8", onC
2424
2678
  );
2425
2679
  };
2426
2680
 
2427
- // src/components/Iframe/styles.module.less
2681
+ // src/components/MicroApp/styles.module.less
2428
2682
  var styles_module_default3 = {
2683
+ microApp: "styles_module_microApp"
2684
+ };
2685
+ var MicroApp_default = ({ name, url, className, onMounted, onError, data, ...rest }) => {
2686
+ const [loading, setLoading] = React.useState(false);
2687
+ React.useEffect(() => {
2688
+ setLoading(true);
2689
+ }, [url]);
2690
+ const handleLoad = () => {
2691
+ setLoading(false);
2692
+ onMounted?.();
2693
+ };
2694
+ const handleError = (e) => {
2695
+ setLoading(false);
2696
+ onError?.(e);
2697
+ };
2698
+ const microAppData = React.useMemo(() => {
2699
+ const parentMainSource = window?.microApp?.getData?.()?.mainSource || [];
2700
+ return { mainSource: [...parentMainSource, name], ...data };
2701
+ }, [data, name]);
2702
+ const TagName = microApp__default.default.tagName || "micro-app";
2703
+ return /* @__PURE__ */ jsxCustomEvent__default.default(antd.Spin, { spinning: loading, classNames: { root: "full-spin" }, description: "\u52A0\u8F7D\u4E2D..." }, /* @__PURE__ */ jsxCustomEvent__default.default(
2704
+ TagName,
2705
+ {
2706
+ name,
2707
+ url,
2708
+ data: microAppData,
2709
+ class: classNames2__default.default(styles_module_default3.microApp, className),
2710
+ onMounted: handleLoad,
2711
+ onError: handleError,
2712
+ ...rest
2713
+ }
2714
+ ));
2715
+ };
2716
+ var Drawer_default = ({ name: podName }) => {
2717
+ const [currentPod, setCurrentPod] = React.useState({ title: "", url: "" });
2718
+ const [fullPodOpen, setFullPodOpen] = React.useState(false);
2719
+ const { on, off } = useIframeRelayBridge_default();
2720
+ const openPod = React.useCallback(({ title, url, name }) => {
2721
+ if (name === podName) {
2722
+ setCurrentPod({ title, url });
2723
+ setFullPodOpen(true);
2724
+ }
2725
+ }, []);
2726
+ const onClosePod = React.useCallback(() => {
2727
+ setFullPodOpen(false);
2728
+ }, []);
2729
+ React.useEffect(() => {
2730
+ on("openPod", openPod);
2731
+ on("onClosePod", onClosePod);
2732
+ return () => {
2733
+ off("openPod", openPod);
2734
+ off("onClosePod", onClosePod);
2735
+ };
2736
+ }, [openPod, onClosePod]);
2737
+ return /* @__PURE__ */ jsxRuntime.jsx(
2738
+ antd.Drawer,
2739
+ {
2740
+ className: "no-padding-drawer",
2741
+ destroyOnHidden: true,
2742
+ title: currentPod.title,
2743
+ classNames: {
2744
+ header: currentPod.title === false ? "hidden" : ""
2745
+ },
2746
+ size: "100%",
2747
+ open: fullPodOpen,
2748
+ onClose: () => setFullPodOpen(false),
2749
+ children: /* @__PURE__ */ jsxRuntime.jsx(MicroApp_default, { iframe: true, name: podName, url: currentPod.url, "router-mode": "pure" }, currentPod.url)
2750
+ }
2751
+ );
2752
+ };
2753
+ var Window_default = ({ defaultUrl, name: appName }) => {
2754
+ const [windowUrl, setWindowUrl] = React.useState("");
2755
+ const [windowUrlKey, setWindowUrlKey, getWindowUrlKey] = useRefState_default(0);
2756
+ const { on, off } = useIframeRelayBridge_default();
2757
+ const onWindowUrlChange = (url) => {
2758
+ setWindowUrl(url);
2759
+ setWindowUrlKey(getWindowUrlKey() + 1);
2760
+ };
2761
+ React.useEffect(() => {
2762
+ const urlParams = getAllUrlParams(location.href);
2763
+ if (urlParams[appName]) {
2764
+ const url = microApp__default.default.router.decode(urlParams[appName]);
2765
+ onWindowUrlChange(url);
2766
+ } else {
2767
+ onWindowUrlChange(defaultUrl);
2768
+ }
2769
+ }, [defaultUrl, appName]);
2770
+ const openWindow = React.useCallback(
2771
+ ({ url, name }) => {
2772
+ if (appName === name) {
2773
+ onWindowUrlChange(url);
2774
+ }
2775
+ },
2776
+ [appName]
2777
+ );
2778
+ React.useEffect(() => {
2779
+ on("openWindow", openWindow);
2780
+ return () => {
2781
+ off("openWindow", openWindow);
2782
+ };
2783
+ }, [openWindow]);
2784
+ return windowUrl ? /* @__PURE__ */ jsxRuntime.jsx(MicroApp_default, { name: appName, url: windowUrl }, windowUrlKey) : null;
2785
+ };
2786
+
2787
+ // src/components/Iframe/styles.module.less
2788
+ var styles_module_default4 = {
2429
2789
  iframe: "styles_module_iframe"
2430
2790
  };
2431
2791
  var Iframe_default = React.forwardRef(({ defaultMainSource, id, src, className, onLoad }, ref) => {
@@ -2440,13 +2800,13 @@ var Iframe_default = React.forwardRef(({ defaultMainSource, id, src, className,
2440
2800
  React.useEffect(() => {
2441
2801
  setLoading(true);
2442
2802
  }, [src]);
2443
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, wrapperClassName: "full-spin", tip: "\u52A0\u8F7D\u4E2D...", children: /* @__PURE__ */ jsxRuntime.jsx(
2803
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { spinning: loading, classNames: { root: "full-spin" }, description: "\u52A0\u8F7D\u4E2D...", children: /* @__PURE__ */ jsxRuntime.jsx(
2444
2804
  "iframe",
2445
2805
  {
2446
2806
  id,
2447
2807
  ref,
2448
2808
  src: finalSrc,
2449
- className: classNames2__default.default(styles_module_default3.iframe, className),
2809
+ className: classNames2__default.default(styles_module_default4.iframe, className),
2450
2810
  onLoad: onHandleLoad,
2451
2811
  allow: "clipboard-write"
2452
2812
  }
@@ -2454,7 +2814,7 @@ var Iframe_default = React.forwardRef(({ defaultMainSource, id, src, className,
2454
2814
  });
2455
2815
 
2456
2816
  // src/components/MarkdownEditor/styles.module.less
2457
- var styles_module_default4 = {
2817
+ var styles_module_default5 = {
2458
2818
  editorParent: "styles_module_editorParent",
2459
2819
  extraToolbar: "styles_module_extraToolbar",
2460
2820
  editorFloatingToolbar: "styles_module_editorFloatingToolbar",
@@ -3145,7 +3505,7 @@ var ANNOTATION_KEY = "annotation";
3145
3505
  var ANNOTATION_ATTRS = ["annotation-id", "user-name", "user-id", "update-time", "content"];
3146
3506
 
3147
3507
  // src/components/MarkdownEditor/annotation/styles.module.less
3148
- var styles_module_default5 = {
3508
+ var styles_module_default6 = {
3149
3509
  annotations: "styles_module_annotations",
3150
3510
  annotationItem: "styles_module_annotationItem",
3151
3511
  annotationItemSelected: "styles_module_annotationItemSelected"
@@ -3208,7 +3568,7 @@ var AnnotationSidebar_default = ({
3208
3568
  children: annotations.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3209
3569
  antd.List,
3210
3570
  {
3211
- className: classNames2__default.default(styles_module_default5.annotations, "height-full", "scroll-fade-in"),
3571
+ className: classNames2__default.default(styles_module_default6.annotations, "height-full", "scroll-fade-in"),
3212
3572
  dataSource: annotations,
3213
3573
  renderItem: (annotation) => /* @__PURE__ */ jsxRuntime.jsx(
3214
3574
  antd.List.Item,
@@ -3216,14 +3576,14 @@ var AnnotationSidebar_default = ({
3216
3576
  ref: (el) => {
3217
3577
  itemRefs.current[annotation[ANNOTATION_ATTRS[0]]] = el;
3218
3578
  },
3219
- className: classNames2__default.default(styles_module_default5.annotationItem, {
3220
- [styles_module_default5.annotationItemSelected]: annotation[ANNOTATION_ATTRS[0]] === selectedAnnotationId
3579
+ className: classNames2__default.default(styles_module_default6.annotationItem, {
3580
+ [styles_module_default6.annotationItemSelected]: annotation[ANNOTATION_ATTRS[0]] === selectedAnnotationId
3221
3581
  }),
3222
3582
  onClick: () => {
3223
3583
  handleSelectAnnotation(annotation[ANNOTATION_ATTRS[0]]);
3224
3584
  },
3225
3585
  children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, gap: 8, flex: 1, children: [
3226
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "space-between", className: styles_module_default5.annotationMeta, children: [
3586
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "space-between", className: styles_module_default6.annotationMeta, children: [
3227
3587
  /* @__PURE__ */ jsxRuntime.jsx(Text, { strong: true, type: "secondary", children: annotation["user-name"] }),
3228
3588
  /* @__PURE__ */ jsxRuntime.jsx(Text, { type: "secondary", children: formatDate(annotation["update-time"]) })
3229
3589
  ] }),
@@ -3284,7 +3644,7 @@ var AnnotationSidebar_default = ({
3284
3644
  }
3285
3645
  return reactDom.createPortal(sidebarContent, container);
3286
3646
  };
3287
- var createHtmlMark = (markName, ATTRS, classNames7) => {
3647
+ var createHtmlMark = (markName, ATTRS, classNames8) => {
3288
3648
  return core.Mark.create({
3289
3649
  name: markName,
3290
3650
  priority: 1e3,
@@ -3313,7 +3673,7 @@ var createHtmlMark = (markName, ATTRS, classNames7) => {
3313
3673
  return [
3314
3674
  "div",
3315
3675
  core.mergeAttributes(attrs, {
3316
- class: classNames7
3676
+ class: classNames8
3317
3677
  }),
3318
3678
  0
3319
3679
  ];
@@ -3827,7 +4187,7 @@ var CollectionPlugin = core.Extension.create({
3827
4187
  });
3828
4188
 
3829
4189
  // src/components/MarkdownEditor/collection/styles.module.less
3830
- var styles_module_default6 = {
4190
+ var styles_module_default7 = {
3831
4191
  collections: "styles_module_collections",
3832
4192
  collectionItem: "styles_module_collectionItem",
3833
4193
  collectionItemSelected: "styles_module_collectionItemSelected"
@@ -3873,7 +4233,7 @@ var collectionSidebar_default = ({
3873
4233
  children: collections.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3874
4234
  antd.List,
3875
4235
  {
3876
- className: classNames2__default.default(styles_module_default6.collections, "height-full", "scroll-fade-in"),
4236
+ className: classNames2__default.default(styles_module_default7.collections, "height-full", "scroll-fade-in"),
3877
4237
  dataSource: collections,
3878
4238
  renderItem: (collection) => {
3879
4239
  if (collectionConfig?.renderItem) {
@@ -3890,14 +4250,14 @@ var collectionSidebar_default = ({
3890
4250
  ref: (el) => {
3891
4251
  itemRefs.current[collection[COLLECTION_ATTRS[0]]] = el;
3892
4252
  },
3893
- className: classNames2__default.default(styles_module_default6.collectionItem, {
3894
- [styles_module_default6.collectionItemSelected]: collection[COLLECTION_ATTRS[0]] === selectedCollectionId
4253
+ className: classNames2__default.default(styles_module_default7.collectionItem, {
4254
+ [styles_module_default7.collectionItemSelected]: collection[COLLECTION_ATTRS[0]] === selectedCollectionId
3895
4255
  }),
3896
4256
  onClick: () => {
3897
4257
  handleSelectCollection?.(collection[COLLECTION_ATTRS[0]]);
3898
4258
  },
3899
4259
  children: /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { vertical: true, gap: 8, flex: 1, children: [
3900
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "space-between", className: styles_module_default6.collectionMeta, children: [
4260
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, justify: "space-between", className: styles_module_default7.collectionMeta, children: [
3901
4261
  /* @__PURE__ */ jsxRuntime.jsx(Text2, { strong: true, type: "secondary", children: collection["user-name"] }),
3902
4262
  /* @__PURE__ */ jsxRuntime.jsx(Text2, { type: "secondary", children: formatDate(collection["update-time"]) })
3903
4263
  ] }),
@@ -8610,274 +8970,296 @@ var usePageNo = (pageNoConfig) => {
8610
8970
  onPageChange
8611
8971
  };
8612
8972
  };
8613
- var MarkdownEditor_default = ({
8614
- value = ``,
8615
- onChange,
8616
- searchValue,
8617
- disabled,
8618
- extraNav,
8619
- fixedToolbar = true,
8620
- floatToolbar = true,
8621
- onQuote,
8622
- onDownloadFile,
8623
- annotationConfig,
8624
- collectionConfig,
8625
- pageNoConfig
8626
- }) => {
8627
- const isMobile = useIsBreakpoint();
8628
- const lastContentRef = React.useRef("");
8629
- const { setPageNoEditor, onPageChange } = usePageNo(pageNoConfig);
8630
- const {
8631
- setAnnotationEditor,
8632
- annotations,
8633
- setAnnotations,
8634
- selectedAnnotationId,
8635
- handleSelectAnnotation,
8636
- showAnnotationModal,
8637
- showAnnotation,
8638
- onCreateAnnotation,
8639
- closeAnnotationCreateModal,
8640
- onCreateAnnotationConfirm,
8641
- handleDeleteAnnotation,
8642
- handleEditAnnotation,
8643
- setShowAnnotation
8644
- } = useAnnotations(annotationConfig);
8645
- const {
8646
- setCollectionEditor,
8647
- collections,
8648
- setCollections,
8649
- selectedCollectionId,
8650
- handleSelectCollection,
8651
- showCollection,
8652
- setShowCollection,
8653
- onCreateCollection,
8654
- handleDeleteCollection
8655
- } = useCollections(collectionConfig);
8656
- const editor = react.useEditor({
8657
- immediatelyRender: false,
8658
- editorProps: {
8659
- attributes: {
8660
- autocomplete: "off",
8661
- autocorrect: "off",
8662
- autocapitalize: "off",
8663
- "aria-label": "\u4E3B\u5185\u5BB9\u533A\u57DF\uFF0C\u5F00\u59CB\u8F93\u5165\u6587\u672C..."
8664
- }
8665
- },
8666
- extensions: [
8667
- markdown.Markdown,
8668
- extensionMathematics.Mathematics.configure({
8669
- // 可选:KaTeX 自定义配置
8670
- katexOptions: {
8671
- throwOnError: false
8672
- }
8673
- // 可选:内联公式点击回调
8674
- // inlineOptions: {
8675
- // onClick: (node, pos) => {
8676
- // const newLaTeX = prompt('编辑公式 LaTeX:', node.attrs.latex)
8677
- // if (newLaTeX) {
8678
- // editor?.chain().setNodeSelection(pos).updateInlineMath({ latex: newLaTeX }).run()
8679
- // }
8680
- // }
8681
- // }
8682
- }),
8683
- starterKit.StarterKit.configure({
8684
- horizontalRule: false,
8685
- link: {
8686
- openOnClick: false,
8687
- enableClickSelection: true
8973
+ var MarkdownEditor_default = React.forwardRef(
8974
+ ({
8975
+ value = ``,
8976
+ onChange,
8977
+ searchValue,
8978
+ disabled,
8979
+ extraNav,
8980
+ fixedToolbar = true,
8981
+ floatToolbar = true,
8982
+ onQuote,
8983
+ onDownloadFile,
8984
+ annotationConfig,
8985
+ collectionConfig,
8986
+ pageNoConfig
8987
+ }, ref) => {
8988
+ const isMobile = useIsBreakpoint();
8989
+ const lastContentRef = React.useRef("");
8990
+ const { setPageNoEditor, onPageChange } = usePageNo(pageNoConfig);
8991
+ const {
8992
+ setAnnotationEditor,
8993
+ annotations,
8994
+ setAnnotations,
8995
+ selectedAnnotationId,
8996
+ handleSelectAnnotation,
8997
+ showAnnotationModal,
8998
+ showAnnotation,
8999
+ onCreateAnnotation,
9000
+ closeAnnotationCreateModal,
9001
+ onCreateAnnotationConfirm,
9002
+ handleDeleteAnnotation,
9003
+ handleEditAnnotation,
9004
+ setShowAnnotation
9005
+ } = useAnnotations(annotationConfig);
9006
+ const {
9007
+ setCollectionEditor,
9008
+ collections,
9009
+ setCollections,
9010
+ selectedCollectionId,
9011
+ handleSelectCollection,
9012
+ showCollection,
9013
+ setShowCollection,
9014
+ onCreateCollection,
9015
+ handleDeleteCollection
9016
+ } = useCollections(collectionConfig);
9017
+ const editor = react.useEditor({
9018
+ immediatelyRender: false,
9019
+ editorProps: {
9020
+ attributes: {
9021
+ autocomplete: "off",
9022
+ autocorrect: "off",
9023
+ autocapitalize: "off",
9024
+ "aria-label": "\u4E3B\u5185\u5BB9\u533A\u57DF\uFF0C\u5F00\u59CB\u8F93\u5165\u6587\u672C..."
8688
9025
  }
8689
- }),
8690
- HorizontalRule,
8691
- extensionTextAlign.TextAlign.configure({ types: ["heading", "paragraph"] }),
8692
- extensionList.TaskList,
8693
- extensionList.TaskItem.configure({ nested: true }),
8694
- extensionHighlight.Highlight.configure({ multicolor: true }),
8695
- extensionImage.Image,
8696
- extensionTypography.Typography,
8697
- extensionSuperscript.Superscript,
8698
- extensionSubscript.Subscript,
8699
- extensions.Selection,
8700
- extensionTable.Table.configure({
8701
- resizable: true
8702
- // 可选,允许调整表格大小
8703
- }),
8704
- extensionTable.TableHeader,
8705
- extensionTable.TableRow,
8706
- extensionTable.TableCell,
8707
- // ImageUploadNode.configure({
8708
- // accept: 'image/*',
8709
- // maxSize: MAX_FILE_SIZE,
8710
- // limit: 3,
8711
- // upload: handleImageUpload,
8712
- // onError: (error) => console.error('上传失败:', error)
8713
- // }),
8714
- ...pageNoConfig?.enabled ? [
8715
- pageNoMark_default,
8716
- PageNoExtension.configure({
8717
- onPageChange,
8718
- containerSelector: "#contentWrapper"
8719
- })
8720
- ] : [],
8721
- searchAndReplace_default.configure({
8722
- searchResultClass: "cube-hl",
8723
- // class to give to found items. default 'cube-hl'
8724
- disableRegex: false
8725
- // also no need to explain
8726
- }),
8727
- ...annotationConfig?.enabled ? [
8728
- AnnotationMark,
8729
- AnnotationPlugin.configure({
8730
- onAnnotationsChange: setAnnotations,
8731
- onSelectAnnotation: (annotation) => {
8732
- handleSelectAnnotation(annotation?.[ANNOTATION_ATTRS[0]]);
9026
+ },
9027
+ extensions: [
9028
+ markdown.Markdown,
9029
+ extensionMathematics.Mathematics.configure({
9030
+ // 可选:KaTeX 自定义配置
9031
+ katexOptions: {
9032
+ throwOnError: false
8733
9033
  }
8734
- })
8735
- ] : [],
8736
- // 摘录功能扩展
8737
- ...collectionConfig?.enabled ? [
8738
- CollectionMark,
8739
- CollectionPlugin.configure({
8740
- onCollectionsChange: setCollections,
8741
- onSelectCollection: (collection) => {
8742
- handleSelectCollection(collection?.[COLLECTION_ATTRS[0]]);
9034
+ // 可选:内联公式点击回调
9035
+ // inlineOptions: {
9036
+ // onClick: (node, pos) => {
9037
+ // const newLaTeX = prompt('编辑公式 LaTeX:', node.attrs.latex)
9038
+ // if (newLaTeX) {
9039
+ // editor?.chain().setNodeSelection(pos).updateInlineMath({ latex: newLaTeX }).run()
9040
+ // }
9041
+ // }
9042
+ // }
9043
+ }),
9044
+ starterKit.StarterKit.configure({
9045
+ horizontalRule: false,
9046
+ link: {
9047
+ openOnClick: false,
9048
+ enableClickSelection: true
8743
9049
  }
8744
- })
8745
- ] : []
8746
- ],
8747
- content: value,
8748
- contentType: "markdown",
8749
- onUpdate: () => {
8750
- const markdownOutput = getMarkdown();
8751
- if (markdownOutput === lastContentRef.current) return;
8752
- lastContentRef.current = markdownOutput;
8753
- onChange?.(markdownOutput);
8754
- }
8755
- });
8756
- const getMarkdown = () => {
8757
- if (!editor) return "";
8758
- if (editor.isEmpty) return "";
8759
- return editor.getMarkdown();
8760
- };
8761
- React.useEffect(() => {
8762
- if (!editor) return;
8763
- setAnnotationEditor(editor);
8764
- setCollectionEditor(editor);
8765
- setPageNoEditor(editor);
8766
- }, [editor]);
8767
- React.useEffect(() => {
8768
- if (!editor) return;
8769
- if (lastContentRef.current === value) return;
8770
- editor?.commands.setContent(value, { contentType: "markdown" });
8771
- editor?.commands.focus("start");
8772
- lastContentRef.current = value;
8773
- }, [value, editor]);
8774
- React.useEffect(() => {
8775
- editor?.commands.setSearchTerm(searchValue || "");
8776
- }, [searchValue, value, editor]);
8777
- React.useEffect(() => {
8778
- editor?.setEditable(!disabled);
8779
- }, [disabled, editor]);
8780
- const downloadFile2 = () => {
8781
- onDownloadFile?.(getMarkdown(), "docx");
8782
- };
8783
- const fixedTools = React.useMemo(() => isArray(fixedToolbar) ? fixedToolbar : void 0, [fixedToolbar]);
8784
- const floatTools = React.useMemo(() => isArray(floatToolbar) ? floatToolbar : void 0, [floatToolbar]);
8785
- return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { className: "height-full width-full", children: [
8786
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames2__default.default("height-full", "flex-1", styles_module_default4.editorParent), children: /* @__PURE__ */ jsxRuntime.jsxs(react.EditorContext.Provider, { value: { editor }, children: [
8787
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8788
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "end", align: "center", children: [
8789
- fixedToolbar !== false && /* @__PURE__ */ jsxRuntime.jsx(
9050
+ }),
9051
+ HorizontalRule,
9052
+ extensionTextAlign.TextAlign.configure({ types: ["heading", "paragraph"] }),
9053
+ extensionList.TaskList,
9054
+ extensionList.TaskItem.configure({ nested: true }),
9055
+ extensionHighlight.Highlight.configure({ multicolor: true }),
9056
+ extensionImage.Image,
9057
+ extensionTypography.Typography,
9058
+ extensionSuperscript.Superscript,
9059
+ extensionSubscript.Subscript,
9060
+ extensions.Selection,
9061
+ extensionTable.Table.configure({
9062
+ resizable: true
9063
+ // 可选,允许调整表格大小
9064
+ }),
9065
+ extensionTable.TableHeader,
9066
+ extensionTable.TableRow,
9067
+ extensionTable.TableCell,
9068
+ // ImageUploadNode.configure({
9069
+ // accept: 'image/*',
9070
+ // maxSize: MAX_FILE_SIZE,
9071
+ // limit: 3,
9072
+ // upload: handleImageUpload,
9073
+ // onError: (error) => console.error('上传失败:', error)
9074
+ // }),
9075
+ ...pageNoConfig?.enabled ? [
9076
+ pageNoMark_default,
9077
+ PageNoExtension.configure({
9078
+ onPageChange,
9079
+ containerSelector: "#contentWrapper"
9080
+ })
9081
+ ] : [],
9082
+ searchAndReplace_default.configure({
9083
+ searchResultClass: "cube-hl",
9084
+ // class to give to found items. default 'cube-hl'
9085
+ disableRegex: false
9086
+ // also no need to explain
9087
+ }),
9088
+ ...annotationConfig?.enabled ? [
9089
+ AnnotationMark,
9090
+ AnnotationPlugin.configure({
9091
+ onAnnotationsChange: setAnnotations,
9092
+ onSelectAnnotation: (annotation) => {
9093
+ handleSelectAnnotation(annotation?.[ANNOTATION_ATTRS[0]]);
9094
+ }
9095
+ })
9096
+ ] : [],
9097
+ // 摘录功能扩展
9098
+ ...collectionConfig?.enabled ? [
9099
+ CollectionMark,
9100
+ CollectionPlugin.configure({
9101
+ onCollectionsChange: setCollections,
9102
+ onSelectCollection: (collection) => {
9103
+ handleSelectCollection(collection?.[COLLECTION_ATTRS[0]]);
9104
+ }
9105
+ })
9106
+ ] : []
9107
+ ],
9108
+ content: value,
9109
+ contentType: "markdown",
9110
+ onUpdate: () => {
9111
+ const markdownOutput = getMarkdown();
9112
+ if (markdownOutput === lastContentRef.current) return;
9113
+ lastContentRef.current = markdownOutput;
9114
+ onChange?.(markdownOutput);
9115
+ }
9116
+ });
9117
+ const getMarkdown = () => {
9118
+ if (!editor) return "";
9119
+ if (editor.isEmpty) return "";
9120
+ return editor.getMarkdown();
9121
+ };
9122
+ React.useImperativeHandle(
9123
+ ref,
9124
+ () => ({
9125
+ getEditor: () => editor,
9126
+ getMarkdown,
9127
+ focus: (pos) => {
9128
+ if (!editor) return;
9129
+ editor.commands.focus(pos);
9130
+ },
9131
+ insertContent: (value2, options) => {
9132
+ if (!editor) return;
9133
+ editor.chain().focus().insertContent(value2, options).run();
9134
+ },
9135
+ insertContentAt: (position, value2, options) => {
9136
+ if (!editor) return;
9137
+ editor.chain().focus().insertContentAt(position, value2, options).run();
9138
+ }
9139
+ }),
9140
+ [editor]
9141
+ );
9142
+ React.useEffect(() => {
9143
+ if (!editor) return;
9144
+ setAnnotationEditor(editor);
9145
+ setCollectionEditor(editor);
9146
+ setPageNoEditor(editor);
9147
+ }, [editor]);
9148
+ React.useEffect(() => {
9149
+ if (!editor) return;
9150
+ if (lastContentRef.current === value) return;
9151
+ editor?.commands.setContent(value, { contentType: "markdown" });
9152
+ editor?.commands.focus("start");
9153
+ lastContentRef.current = value;
9154
+ }, [value, editor]);
9155
+ React.useEffect(() => {
9156
+ editor?.commands.setSearchTerm(searchValue || "");
9157
+ }, [searchValue, value, editor]);
9158
+ React.useEffect(() => {
9159
+ editor?.setEditable(!disabled);
9160
+ }, [disabled, editor]);
9161
+ const downloadFile2 = () => {
9162
+ onDownloadFile?.(getMarkdown(), "docx");
9163
+ };
9164
+ const fixedTools = React.useMemo(() => isArray(fixedToolbar) ? fixedToolbar : void 0, [fixedToolbar]);
9165
+ const floatTools = React.useMemo(() => isArray(floatToolbar) ? floatToolbar : void 0, [floatToolbar]);
9166
+ return /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { className: "height-full width-full", children: [
9167
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames2__default.default("height-full", "flex-1", styles_module_default5.editorParent), children: /* @__PURE__ */ jsxRuntime.jsxs(react.EditorContext.Provider, { value: { editor }, children: [
9168
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9169
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { justify: "end", align: "center", children: [
9170
+ fixedToolbar !== false && /* @__PURE__ */ jsxRuntime.jsx(
9171
+ EditorToolbar,
9172
+ {
9173
+ isBubble: false,
9174
+ onQuote,
9175
+ onCreateAnnotation: annotationConfig?.enabled ? onCreateAnnotation : void 0,
9176
+ onCreateCollection: collectionConfig?.enabled ? onCreateCollection : void 0,
9177
+ tools: fixedTools
9178
+ }
9179
+ ),
9180
+ /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", className: classNames2__default.default(styles_module_default5.extraToolbar), children: [
9181
+ annotationConfig?.enabled && annotationConfig?.showListButton !== false && /* @__PURE__ */ jsxRuntime.jsx(
9182
+ antd.Button,
9183
+ {
9184
+ size: "small",
9185
+ title: "\u6279\u6CE8\u5217\u8868",
9186
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.MessageOutlined, {}),
9187
+ color: "primary",
9188
+ variant: "text",
9189
+ onClick: () => setShowAnnotation(!showAnnotation)
9190
+ }
9191
+ ),
9192
+ collectionConfig?.enabled && collectionConfig?.showListButton !== false && /* @__PURE__ */ jsxRuntime.jsx(
9193
+ antd.Button,
9194
+ {
9195
+ style: { gap: "2px" },
9196
+ size: "small",
9197
+ title: "\u6458\u5F55\u5217\u8868",
9198
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.BookOutlined, {}),
9199
+ color: "primary",
9200
+ variant: "text",
9201
+ onClick: () => setShowCollection(!showCollection),
9202
+ children: "\u6458\u5F55"
9203
+ }
9204
+ ),
9205
+ onDownloadFile && /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { size: "small", color: "primary", variant: "text", onClick: downloadFile2, children: "\u4E0B\u8F7D" }),
9206
+ extraNav
9207
+ ] })
9208
+ ] }),
9209
+ !isMobile && floatToolbar !== false && /* @__PURE__ */ jsxRuntime.jsx(FloatingElement, { editor, zIndex: 188, resetTextSelectionOnClose: false, className: styles_module_default5.editorFloatingToolbar, children: /* @__PURE__ */ jsxRuntime.jsx(
8790
9210
  EditorToolbar,
8791
9211
  {
8792
- isBubble: false,
9212
+ isBubble: true,
8793
9213
  onQuote,
8794
9214
  onCreateAnnotation: annotationConfig?.enabled ? onCreateAnnotation : void 0,
8795
9215
  onCreateCollection: collectionConfig?.enabled ? onCreateCollection : void 0,
8796
- tools: fixedTools
9216
+ tools: floatTools
8797
9217
  }
8798
- ),
8799
- /* @__PURE__ */ jsxRuntime.jsxs(antd.Flex, { gap: 8, align: "center", className: classNames2__default.default(styles_module_default4.extraToolbar), children: [
8800
- annotationConfig?.enabled && annotationConfig?.showListButton !== false && /* @__PURE__ */ jsxRuntime.jsx(
8801
- antd.Button,
8802
- {
8803
- size: "small",
8804
- title: "\u6279\u6CE8\u5217\u8868",
8805
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.MessageOutlined, {}),
8806
- color: "primary",
8807
- variant: "text",
8808
- onClick: () => setShowAnnotation(!showAnnotation)
8809
- }
8810
- ),
8811
- collectionConfig?.enabled && collectionConfig?.showListButton !== false && /* @__PURE__ */ jsxRuntime.jsx(
8812
- antd.Button,
8813
- {
8814
- style: { gap: "2px" },
8815
- size: "small",
8816
- title: "\u6458\u5F55\u5217\u8868",
8817
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.BookOutlined, {}),
8818
- color: "primary",
8819
- variant: "text",
8820
- onClick: () => setShowCollection(!showCollection),
8821
- children: "\u6458\u5F55"
8822
- }
8823
- ),
8824
- onDownloadFile && /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { size: "small", color: "primary", variant: "text", onClick: downloadFile2, children: "\u4E0B\u8F7D" }),
8825
- extraNav
8826
- ] })
9218
+ ) })
8827
9219
  ] }),
8828
- !isMobile && floatToolbar !== false && /* @__PURE__ */ jsxRuntime.jsx(FloatingElement, { editor, zIndex: 188, resetTextSelectionOnClose: false, className: styles_module_default4.editorFloatingToolbar, children: /* @__PURE__ */ jsxRuntime.jsx(
8829
- EditorToolbar,
9220
+ /* @__PURE__ */ jsxRuntime.jsx("div", { id: "contentWrapper", className: classNames2__default.default(styles_module_default5.contentWrapper, "scroll-fade-in"), children: /* @__PURE__ */ jsxRuntime.jsx(
9221
+ react.EditorContent,
8830
9222
  {
8831
- isBubble: true,
8832
- onQuote,
8833
- onCreateAnnotation: annotationConfig?.enabled ? onCreateAnnotation : void 0,
8834
- onCreateCollection: collectionConfig?.enabled ? onCreateCollection : void 0,
8835
- tools: floatTools
9223
+ editor,
9224
+ role: "presentation",
9225
+ className: classNames2__default.default(styles_module_default5.simpleEditorContent, "ns-markdown", { [styles_module_default5.noToolbar]: fixedToolbar === false })
8836
9226
  }
8837
9227
  ) })
9228
+ ] }) }),
9229
+ annotationConfig?.enabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9230
+ showAnnotation && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames2__default.default("height-full", styles_module_default5.extraSidebarParent), children: /* @__PURE__ */ jsxRuntime.jsx(
9231
+ AnnotationSidebar_default,
9232
+ {
9233
+ disabled,
9234
+ annotations,
9235
+ selectedAnnotationId,
9236
+ handleSelectAnnotation: (id) => handleSelectAnnotation(id, "sidebar"),
9237
+ onEditAnnotation: handleEditAnnotation,
9238
+ onDeleteAnnotation: handleDeleteAnnotation,
9239
+ annotationConfig,
9240
+ onClose: () => setShowAnnotation(false)
9241
+ }
9242
+ ) }),
9243
+ showAnnotationModal && /* @__PURE__ */ jsxRuntime.jsx(AnnotationModal_default, { visible: showAnnotationModal, onCancel: closeAnnotationCreateModal, onConfirm: onCreateAnnotationConfirm })
8838
9244
  ] }),
8839
- /* @__PURE__ */ jsxRuntime.jsx("div", { id: "contentWrapper", className: classNames2__default.default(styles_module_default4.contentWrapper, "scroll-fade-in"), children: /* @__PURE__ */ jsxRuntime.jsx(
8840
- react.EditorContent,
8841
- {
8842
- editor,
8843
- role: "presentation",
8844
- className: classNames2__default.default(styles_module_default4.simpleEditorContent, "ns-markdown", { [styles_module_default4.noToolbar]: fixedToolbar === false })
8845
- }
8846
- ) })
8847
- ] }) }),
8848
- annotationConfig?.enabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8849
- showAnnotation && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames2__default.default("height-full", styles_module_default4.extraSidebarParent), children: /* @__PURE__ */ jsxRuntime.jsx(
8850
- AnnotationSidebar_default,
9245
+ collectionConfig?.enabled && showCollection && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames2__default.default("height-full", styles_module_default5.extraSidebarParent), children: /* @__PURE__ */ jsxRuntime.jsx(
9246
+ collectionSidebar_default,
8851
9247
  {
8852
9248
  disabled,
8853
- annotations,
8854
- selectedAnnotationId,
8855
- handleSelectAnnotation: (id) => handleSelectAnnotation(id, "sidebar"),
8856
- onEditAnnotation: handleEditAnnotation,
8857
- onDeleteAnnotation: handleDeleteAnnotation,
8858
- annotationConfig,
8859
- onClose: () => setShowAnnotation(false)
9249
+ collections,
9250
+ selectedCollectionId,
9251
+ handleSelectCollection: (id) => handleSelectCollection(id, "sidebar"),
9252
+ onDeleteCollection: handleDeleteCollection,
9253
+ collectionConfig,
9254
+ onClose: () => setShowCollection(false)
8860
9255
  }
8861
- ) }),
8862
- showAnnotationModal && /* @__PURE__ */ jsxRuntime.jsx(AnnotationModal_default, { visible: showAnnotationModal, onCancel: closeAnnotationCreateModal, onConfirm: onCreateAnnotationConfirm })
8863
- ] }),
8864
- collectionConfig?.enabled && showCollection && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames2__default.default("height-full", styles_module_default4.extraSidebarParent), children: /* @__PURE__ */ jsxRuntime.jsx(
8865
- collectionSidebar_default,
8866
- {
8867
- disabled,
8868
- collections,
8869
- selectedCollectionId,
8870
- handleSelectCollection: (id) => handleSelectCollection(id, "sidebar"),
8871
- onDeleteCollection: handleDeleteCollection,
8872
- collectionConfig,
8873
- onClose: () => setShowCollection(false)
8874
- }
8875
- ) })
8876
- ] });
8877
- };
9256
+ ) })
9257
+ ] });
9258
+ }
9259
+ );
8878
9260
 
8879
9261
  // src/components/MarkDrawing/styles.module.less
8880
- var styles_module_default7 = {
9262
+ var styles_module_default8 = {
8881
9263
  container: "styles_module_container",
8882
9264
  rect: "styles_module_rect",
8883
9265
  score: "styles_module_score"
@@ -8901,7 +9283,7 @@ var MarkDrawing_default = ({ children, detections, originalSize, scopeRender })
8901
9283
  }, []);
8902
9284
  const scaleX = containerSize.width / originalSize.width;
8903
9285
  const scaleY = containerSize.height / originalSize.height;
8904
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: styles_module_default7.container, children: [
9286
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: styles_module_default8.container, children: [
8905
9287
  children,
8906
9288
  detections?.map((det, idx) => {
8907
9289
  const [x1, y1, x2, y2] = det.bbox;
@@ -8913,7 +9295,7 @@ var MarkDrawing_default = ({ children, detections, originalSize, scopeRender })
8913
9295
  /* @__PURE__ */ jsxRuntime.jsx(
8914
9296
  "div",
8915
9297
  {
8916
- className: styles_module_default7.rect,
9298
+ className: styles_module_default8.rect,
8917
9299
  style: {
8918
9300
  left,
8919
9301
  top,
@@ -8925,7 +9307,7 @@ var MarkDrawing_default = ({ children, detections, originalSize, scopeRender })
8925
9307
  /* @__PURE__ */ jsxRuntime.jsx(
8926
9308
  "div",
8927
9309
  {
8928
- className: styles_module_default7.score,
9310
+ className: styles_module_default8.score,
8929
9311
  style: {
8930
9312
  left,
8931
9313
  top: Math.max(top - 20, 0)
@@ -8993,6 +9375,9 @@ exports.LazyComponent = LazyComponent_default;
8993
9375
  exports.MarkDrawing = MarkDrawing_default;
8994
9376
  exports.MarkdownEditor = MarkdownEditor_default;
8995
9377
  exports.MarkdownPreview = MarkdownPreview_default;
9378
+ exports.MicroApp = MicroApp_default;
9379
+ exports.MicroAppDrawer = Drawer_default;
9380
+ exports.MicroAppWindow = Window_default;
8996
9381
  exports.MultiEmailValidator = MultiEmailValidator;
8997
9382
  exports.PdfImagePreview = PdfImagePreview_default;
8998
9383
  exports.PdfPreview = PdfPreview_default;