koishi-plugin-chat-patch 5.5.1 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/client/vue/index.vue +8 -1
  2. package/client/web/dist/assets/{Chat-DTEsebnY.css → Chat-BXVWj5Bd.css} +1 -1
  3. package/client/web/dist/assets/{Chat-B5Jdrz_2.js → Chat-m4-U5uHa.js} +4 -4
  4. package/client/web/dist/assets/{MsgBody-tPnKSZOs.js → MsgBody-CzrxyiFO.js} +1 -1
  5. package/client/web/dist/assets/MsgBody.vue_vue_type_script_setup_true_lang-BBF1uxm6.js +67 -0
  6. package/client/web/dist/assets/{index-CSGfOsfr.js → index-EJ2CcODr.js} +70 -76
  7. package/client/web/dist/assets/index-X9hFOAza.css +1 -0
  8. package/client/web/dist/index.html +2 -2
  9. package/client/web/src/App.vue +7 -0
  10. package/client/web/src/assets/css/chat.css +6 -4
  11. package/client/web/src/assets/l10n/zh-CN.po +0 -6
  12. package/client/web/src/components/History.vue +27 -0
  13. package/client/web/src/components/MsgBody.vue +18 -9
  14. package/client/web/src/function/connect.ts +208 -46
  15. package/client/web/src/function/msg.ts +7 -5
  16. package/client/web/src/function/option.ts +1 -1
  17. package/client/web/src/function/satori.ts +64 -0
  18. package/client/web/src/pages/Chat.vue +0 -4
  19. package/client/web/src/pages/Friends.vue +7 -9
  20. package/client/web/src/pages/Messages.vue +2 -2
  21. package/client/web/src/pages/options/OptDev.vue +1 -25
  22. package/client/web/src/pages/options/OptFunction.vue +23 -0
  23. package/client/web/tsconfig.tsbuildinfo +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/style.css +1 -1
  26. package/lib/bootstrap.d.ts +6 -0
  27. package/lib/database.d.ts +5 -2
  28. package/lib/gateway.d.ts +46 -0
  29. package/lib/index.js +1468 -131
  30. package/lib/recorder.d.ts +3 -5
  31. package/lib/satori.d.ts +3 -0
  32. package/lib/types.d.ts +17 -0
  33. package/package.json +4 -1
  34. package/src/bootstrap.ts +5 -10
  35. package/src/database.ts +745 -662
  36. package/src/gateway.ts +259 -0
  37. package/src/index.ts +63 -53
  38. package/src/recorder.ts +97 -77
  39. package/src/satori.ts +19 -0
  40. package/src/server.d.ts +26 -26
  41. package/src/types.ts +19 -0
  42. package/client/web/dist/assets/MsgBody.vue_vue_type_script_setup_true_lang-ClDybRo_.js +0 -67
  43. package/client/web/dist/assets/index-B71pPwae.css +0 -1
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{defineComponent as _,ref as l,onMounted as b,onUnmounted as x,openBlock as w,createElementBlock as k,createElementVNode as i,h as f,resolveComponent as M}from"vue";import{send as m,icons as B}from"@koishijs/client";const E={class:"chat-patch-frame"},L=["src"],$=_({__name:"index",setup(r){const o=l(null),c=l("");function s(t){return typeof t=="object"&&t!==null?t:{}}function a(t){return typeof t=="string"?t:""}function p(t){var e,n;(n=(e=o.value)==null?void 0:e.contentWindow)==null||n.postMessage(t,"*")}function g(){m("chat-patch/bootstrap").then(t=>{const e=s(t),n=a(e.basePath)||"/chat-patch";c.value=`${n}/web/`,p({source:"chat-patch-bootstrap",payload:e})})}async function h(t){const e=s(t.data),n=a(e.source);if(n==="chat-patch-ready"){g();return}if(n!=="chat-patch-request")return;const u=a(e.id),C=a(e.method),y=s(e.params);try{const d=await m(`chat-patch/${C}`,y);p({source:"chat-patch-response",id:u,ok:true,payload:d})}catch(d){p({source:"chat-patch-response",id:u,ok:false,error:String(d)})}}return b(()=>{window.addEventListener("message",h),c.value="/chat-patch/web/"}),x(()=>{window.removeEventListener("message",h)}),(t,e)=>(w(),k("div",E,[i("iframe",{ref_key:"frameRef",ref:o,src:c.value,class:"chat-patch-iframe",allow:"clipboard-read; clipboard-write; microphone"},null,8,L)]))}}),v=(r,o)=>{const c=r.__vccOpts||r;for(const[s,a]of o)c[s]=a;return c},S=v($,[["__scopeId","data-v-26256bbc"]]),j={},H={class:"k-icon",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none"};function O(r,o){return w(),k("svg",H,[...o[0]||(o[0]=[i("path",{d:"M8 10.5H16",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),i("path",{d:"M8 14H13.5",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),i("path",{d:"M17 3.33782C15.5291 2.48697 13.8214 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22C17.5228 22 22 17.5228 22 12C22 10.1786 21.513 8.47087 20.6622 7",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1)])])}const P=v(j,[["render",O]]);B.register("activity:chat",P);const A=r=>{r.page({name:"聊天室",path:"/chat-patch",desc:"",authority:4,icon:"activity:chat",component:_({setup(){return()=>f(M("k-layout"),{},{default:()=>f(S)})}})})};export{A as default};
1
+ import{defineComponent as w,ref as m,onMounted as M,onUnmounted as L,openBlock as k,createElementBlock as C,createElementVNode as h,h as _,resolveComponent as $}from"vue";import{useContext as B,send as v,icons as E}from"@koishijs/client";const S={class:"chat-patch-frame"},j=["src"],H=w({__name:"index",setup(r){const o=m(null),a=m(""),d=B();let n;function s(t){return typeof t=="object"&&t!==null?t:{}}function i(t){return typeof t=="string"?t:""}function p(t){var e,c;(c=(e=o.value)==null?void 0:e.contentWindow)==null||c.postMessage(t,"*")}function y(){v("chat-patch/bootstrap").then(t=>{const e=s(t),c=i(e.basePath)||"/chat-patch";a.value=`${c}/web/`,p({source:"chat-patch-bootstrap",payload:e})})}async function l(t){const e=s(t.data),c=i(e.source);if(c==="chat-patch-ready"){y();return}if(c!=="chat-patch-request")return;const f=i(e.id),b=i(e.method),x=s(e.params);try{const u=await v(`chat-patch/${b}`,x);p({source:"chat-patch-response",id:f,ok:true,payload:u})}catch(u){p({source:"chat-patch-response",id:f,ok:false,error:String(u)})}}return M(()=>{window.addEventListener("message",l),n=d.on("chat-patch/event",t=>{p({source:"chat-patch-event",payload:s(t)})}),a.value="/chat-patch/web/"}),L(()=>{n==null||n(),n=void 0,window.removeEventListener("message",l)}),(t,e)=>(k(),C("div",S,[h("iframe",{ref_key:"frameRef",ref:o,src:a.value,class:"chat-patch-iframe",allow:"clipboard-read; clipboard-write; microphone"},null,8,j)]))}}),g=(r,o)=>{const a=r.__vccOpts||r;for(const[d,n]of o)a[d]=n;return a},O=g(H,[["__scopeId","data-v-2e62322e"]]),P={},R={class:"k-icon",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none"};function q(r,o){return k(),C("svg",R,[...o[0]||(o[0]=[h("path",{d:"M8 10.5H16",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),h("path",{d:"M8 14H13.5",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1),h("path",{d:"M17 3.33782C15.5291 2.48697 13.8214 2 12 2C6.47715 2 2 6.47715 2 12C2 13.5997 2.37562 15.1116 3.04346 16.4525C3.22094 16.8088 3.28001 17.2161 3.17712 17.6006L2.58151 19.8267C2.32295 20.793 3.20701 21.677 4.17335 21.4185L6.39939 20.8229C6.78393 20.72 7.19121 20.7791 7.54753 20.9565C8.88837 21.6244 10.4003 22 12 22C17.5228 22 22 17.5228 22 12C22 10.1786 21.513 8.47087 20.6622 7",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"},null,-1)])])}const A=g(P,[["render",q]]);E.register("activity:chat",A);const U=r=>{r.page({name:"聊天室",path:"/chat-patch",desc:"",authority:4,icon:"activity:chat",component:w({setup(){return()=>_($("k-layout"),{},{default:()=>_(O)})}})})};export{U as default};
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";.chat-patch-frame[data-v-26256bbc]{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;overflow:hidden;background:#f7f9fa}.chat-patch-iframe[data-v-26256bbc]{width:100%;height:100%;border:none}.\!container{width:100%!important}.container{width:100%}@media (min-width: 640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width: 768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width: 1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width: 1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width: 1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border-width:0!important}.visible{visibility:visible!important}.static{position:static!important}.fixed{position:fixed!important}.absolute{position:absolute!important}.relative{position:relative!important}.block{display:block!important}.flex{display:flex!important}.table{display:table!important}.grid{display:grid!important}.\!hidden,.hidden{display:none!important}.flex-shrink{flex-shrink:1!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.cursor-crosshair{cursor:crosshair!important}.cursor-grab{cursor:grab!important}.cursor-grabbing{cursor:grabbing!important}.cursor-not-allowed{cursor:not-allowed!important}.resize{resize:both!important}.flex-wrap{flex-wrap:wrap!important}.text-wrap{text-wrap:wrap!important}.border{border-width:1px!important}.uppercase{text-transform:uppercase!important}.italic{font-style:italic!important}.ordinal{--tw-ordinal: ordinal !important;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)!important}.underline{text-decoration-line:underline!important}.outline{outline-style:solid!important}.blur{--tw-blur: blur(8px) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}:root{--chat-bg: var(--k-page-bg);--chat-panel-bg: var(--k-card-bg);--chat-border: var(--k-border-color);--chat-text: var(--k-text-color);--chat-text-sub: var(--k-text-color-secondary)}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__bar{display:none!important;opacity:0!important;width:0!important;height:0!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__thumb{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap{overflow-x:hidden!important;scrollbar-width:none!important;-ms-overflow-style:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;background:transparent!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-track{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-thumb{display:none!important}.chat-patch-wrapper{color:var(--chat-text);background-color:var(--chat-bg)}.chat-patch-wrapper .el-aside,.chat-patch-wrapper .el-main,.chat-patch-wrapper .el-header,.chat-patch-wrapper .el-footer{background-color:transparent!important;color:inherit!important}.chat-patch-wrapper .el-scrollbar{background-color:transparent!important}.chat-patch-wrapper .el-input__wrapper,.chat-patch-wrapper .el-textarea__inner{background-color:var(--k-input-bg)!important;color:var(--chat-text)!important;box-shadow:0 0 0 1px var(--chat-border) inset!important}.chat-patch-wrapper .el-empty{background-color:transparent!important}.layout-iframe{width:100%;height:100%;border:none}.message-highlight{animation:highlight-fade 1.5s ease-in-out;border-radius:8px}@keyframes highlight-fade{0%{background-color:transparent}10%{background-color:#409eff66;filter:brightness(1.2)}30%{background-color:#409eff66;filter:brightness(1.2)}to{background-color:transparent}}
1
+ @charset "UTF-8";.chat-patch-frame[data-v-2e62322e]{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;overflow:hidden;background:#f7f9fa}.chat-patch-iframe[data-v-2e62322e]{width:100%;height:100%;border:none}.\!container{width:100%!important}.container{width:100%}@media (min-width: 640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width: 768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width: 1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width: 1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width: 1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border-width:0!important}.visible{visibility:visible!important}.static{position:static!important}.fixed{position:fixed!important}.absolute{position:absolute!important}.relative{position:relative!important}.block{display:block!important}.flex{display:flex!important}.table{display:table!important}.grid{display:grid!important}.\!hidden,.hidden{display:none!important}.flex-shrink{flex-shrink:1!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.cursor-crosshair{cursor:crosshair!important}.cursor-grab{cursor:grab!important}.cursor-grabbing{cursor:grabbing!important}.cursor-not-allowed{cursor:not-allowed!important}.resize{resize:both!important}.flex-wrap{flex-wrap:wrap!important}.text-wrap{text-wrap:wrap!important}.border{border-width:1px!important}.uppercase{text-transform:uppercase!important}.italic{font-style:italic!important}.ordinal{--tw-ordinal: ordinal !important;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)!important}.underline{text-decoration-line:underline!important}.outline{outline-style:solid!important}.blur{--tw-blur: blur(8px) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}:root{--chat-bg: var(--k-page-bg);--chat-panel-bg: var(--k-card-bg);--chat-border: var(--k-border-color);--chat-text: var(--k-text-color);--chat-text-sub: var(--k-text-color-secondary)}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__bar{display:none!important;opacity:0!important;width:0!important;height:0!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__thumb{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap{overflow-x:hidden!important;scrollbar-width:none!important;-ms-overflow-style:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;background:transparent!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-track{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-thumb{display:none!important}.chat-patch-wrapper{color:var(--chat-text);background-color:var(--chat-bg)}.chat-patch-wrapper .el-aside,.chat-patch-wrapper .el-main,.chat-patch-wrapper .el-header,.chat-patch-wrapper .el-footer{background-color:transparent!important;color:inherit!important}.chat-patch-wrapper .el-scrollbar{background-color:transparent!important}.chat-patch-wrapper .el-input__wrapper,.chat-patch-wrapper .el-textarea__inner{background-color:var(--k-input-bg)!important;color:var(--chat-text)!important;box-shadow:0 0 0 1px var(--chat-border) inset!important}.chat-patch-wrapper .el-empty{background-color:transparent!important}.layout-iframe{width:100%;height:100%;border:none}.message-highlight{animation:highlight-fade 1.5s ease-in-out;border-radius:8px}@keyframes highlight-fade{0%{background-color:transparent}10%{background-color:#409eff66;filter:brightness(1.2)}30%{background-color:#409eff66;filter:brightness(1.2)}to{background-color:transparent}}
@@ -0,0 +1,6 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from './config';
3
+ import { ChatDatabase } from './database';
4
+ import { PluginLogger } from './logger';
5
+ import { SatoriBootstrap } from './types';
6
+ export declare function registerBootstrap(ctx: Context, config: Config, database: ChatDatabase, logger: PluginLogger, getLogins: () => SatoriBootstrap['logins']): void;
package/lib/database.d.ts CHANGED
@@ -6,11 +6,14 @@ export declare class ChatDatabase {
6
6
  private ctx;
7
7
  private config;
8
8
  private logger;
9
- private db;
10
- private opened;
9
+ private readonly dir;
10
+ private shared?;
11
11
  constructor(ctx: Context, config: Config, logger: PluginLogger);
12
+ private get db();
12
13
  initialize(): Promise<void>;
13
14
  dispose(): Promise<void>;
15
+ private ensureOpen;
16
+ private releaseShared;
14
17
  clearAll(): Promise<void>;
15
18
  appendMessage(record: MessageRecord): Promise<void>;
16
19
  upsertSelfMessage(record: SelfMessageRecord): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from './config';
3
+ import { ChatDatabase } from './database';
4
+ import { PluginLogger } from './logger';
5
+ import { Recorder } from './recorder';
6
+ import { SatoriEventPayload, SatoriLoginInfo } from './types';
7
+ export type SatoriGatewayPayload = {
8
+ kind: 'ready';
9
+ logins: SatoriLoginInfo[];
10
+ } | {
11
+ kind: 'event';
12
+ event: SatoriEventPayload;
13
+ } | {
14
+ kind: 'status';
15
+ online: boolean;
16
+ };
17
+ type SatoriGatewayHandler = (payload: SatoriGatewayPayload) => void;
18
+ export declare class SatoriGateway {
19
+ private ctx;
20
+ private config;
21
+ private database;
22
+ private recorder;
23
+ private logger;
24
+ private onPayload;
25
+ private socket?;
26
+ private pingDispose?;
27
+ private reconnectDispose?;
28
+ private stopped;
29
+ private retry;
30
+ private sequence;
31
+ private logins;
32
+ private online;
33
+ constructor(ctx: Context, config: Config, database: ChatDatabase, recorder: Recorder, logger: PluginLogger, onPayload: SatoriGatewayHandler);
34
+ start(): Promise<void>;
35
+ dispose(): void;
36
+ getLogins(): SatoriLoginInfo[];
37
+ private loadSequence;
38
+ private connect;
39
+ private get token();
40
+ private scheduleReconnect;
41
+ private handleMessage;
42
+ private normalizeLogins;
43
+ private isBlocked;
44
+ private setOnline;
45
+ }
46
+ export {};