@appboxo/web-sdk 1.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/constants.d.ts +60 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +65 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/handlers/customEventHandler.d.ts +16 -0
  8. package/dist/handlers/customEventHandler.d.ts.map +1 -0
  9. package/dist/handlers/customEventHandler.js +27 -0
  10. package/dist/handlers/customEventHandler.js.map +1 -0
  11. package/dist/handlers/initDataHandler.d.ts +16 -0
  12. package/dist/handlers/initDataHandler.d.ts.map +1 -0
  13. package/dist/handlers/initDataHandler.js +29 -0
  14. package/dist/handlers/initDataHandler.js.map +1 -0
  15. package/dist/handlers/loginHandler.d.ts +25 -0
  16. package/dist/handlers/loginHandler.d.ts.map +1 -0
  17. package/dist/handlers/loginHandler.js +50 -0
  18. package/dist/handlers/loginHandler.js.map +1 -0
  19. package/dist/handlers/paymentHandler.d.ts +15 -0
  20. package/dist/handlers/paymentHandler.d.ts.map +1 -0
  21. package/dist/handlers/paymentHandler.js +34 -0
  22. package/dist/handlers/paymentHandler.js.map +1 -0
  23. package/dist/index.d.ts +104 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +252 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/types.d.ts +138 -0
  28. package/dist/types.d.ts.map +1 -0
  29. package/dist/types.js +18 -0
  30. package/dist/types.js.map +1 -0
  31. package/dist/utils/authHelper.d.ts +30 -0
  32. package/dist/utils/authHelper.d.ts.map +1 -0
  33. package/dist/utils/authHelper.js +83 -0
  34. package/dist/utils/authHelper.js.map +1 -0
  35. package/dist/utils/index.d.ts +20 -0
  36. package/dist/utils/index.d.ts.map +1 -0
  37. package/dist/utils/index.js +20 -0
  38. package/dist/utils/index.js.map +1 -0
  39. package/dist/utils/messageHelpers.d.ts +34 -0
  40. package/dist/utils/messageHelpers.d.ts.map +1 -0
  41. package/dist/utils/messageHelpers.js +62 -0
  42. package/dist/utils/messageHelpers.js.map +1 -0
  43. package/dist/utils/networkService.d.ts +35 -0
  44. package/dist/utils/networkService.d.ts.map +1 -0
  45. package/dist/utils/networkService.js +106 -0
  46. package/dist/utils/networkService.js.map +1 -0
  47. package/dist/utils/paymentHelper.d.ts +13 -0
  48. package/dist/utils/paymentHelper.d.ts.map +1 -0
  49. package/dist/utils/paymentHelper.js +31 -0
  50. package/dist/utils/paymentHelper.js.map +1 -0
  51. package/dist/utils/validationHelpers.d.ts +33 -0
  52. package/dist/utils/validationHelpers.d.ts.map +1 -0
  53. package/dist/utils/validationHelpers.js +54 -0
  54. package/dist/utils/validationHelpers.js.map +1 -0
  55. package/package.json +50 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Finom pte. ltd.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # Appboxo Web SDK
2
+
3
+ Embed miniapps into your desktop application using iframe communication.
4
+
5
+ ## Quick Start
6
+
7
+ ```typescript
8
+ import { AppboxoWebSDK } from "boxo-desktop-host-sdk";
9
+
10
+ const sdk = new AppboxoWebSDK({
11
+ clientId: "your-client-id",
12
+ appId: "your-app-id"
13
+ });
14
+
15
+ // Get auth code from your backend
16
+ const authCode = await fetch('/api/auth-code').then(r => r.json());
17
+ sdk.setAuthCode(authCode);
18
+
19
+ // Mount miniapp
20
+ sdk.mount({
21
+ container: document.getElementById("miniapp"),
22
+ url: "https://your-miniapp.com"
23
+ });
24
+ ```
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install boxo-desktop-host-sdk
30
+ # or
31
+ pnpm install boxo-desktop-host-sdk
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ ```typescript
37
+ const sdk = new AppboxoWebSDK({
38
+ clientId: string; // Required
39
+ appId: string; // Required
40
+ userId?: string; // Optional, user reference identifier
41
+ baseUrl?: string; // Optional, default: "https://dashboard.appboxo.com/api/v1"
42
+ debug?: boolean; // Optional, default: false
43
+ onGetAuthCode?: () => Promise<string>; // Optional, for automatic auth code retrieval
44
+ });
45
+ ```
46
+
47
+ ### Authentication
48
+
49
+ Two approaches:
50
+
51
+ **1. Set auth code explicitly**
52
+
53
+ ```typescript
54
+ sdk.setAuthCode(authCode);
55
+ ```
56
+
57
+ **2. Provide callback**
58
+
59
+ ```typescript
60
+ const sdk = new AppboxoWebSDK({
61
+ clientId: "your-client-id",
62
+ appId: "your-app-id",
63
+ onGetAuthCode: async () => {
64
+ const res = await fetch('/api/generate-auth-code');
65
+ return (await res.json()).auth_code;
66
+ }
67
+ });
68
+ ```
69
+
70
+ The SDK will try these in order:
71
+
72
+ 1. Explicitly set auth code
73
+ 2. Callback function
74
+ 3. Mock auth code (fallback)
75
+
76
+ ## Methods
77
+
78
+ | Method | Description |
79
+ |--------|-------------|
80
+ | `setAuthCode(code)` | Set authentication code |
81
+ | `mount(config)` | Create iframe and initialize SDK |
82
+ | `setIframe(iframe)` | Set iframe element manually |
83
+ | `initialize()` | Start listening for events |
84
+ | `onEvent(type, handler)` | Register custom event handler |
85
+ | `onLoginComplete(callback)` | Login completion callback |
86
+ | `onPaymentComplete(callback)` | Payment completion callback |
87
+ | `destroy()` | Clean up resources |
88
+
89
+ ## Events
90
+
91
+ SDK handles these miniapp events:
92
+
93
+ - `AppBoxoWebAppLogin` - User authentication
94
+ - `AppBoxoWebAppPay` - Payment processing
95
+ - `AppBoxoWebAppGetInitData` - Initial data request
96
+ - `AppBoxoWebAppCustomEvent` - Custom events
97
+
98
+ ## Examples
99
+
100
+ ### React Example
101
+
102
+ ```tsx
103
+ function App() {
104
+ const iframeRef = useRef<HTMLIFrameElement>(null);
105
+ const [sdk, setSdk] = useState<AppboxoWebSDK | null>(null);
106
+
107
+ useEffect(() => {
108
+ const s = new AppboxoWebSDK({ clientId: "...", appId: "..." });
109
+ s.setAuthCode(authCode);
110
+ s.onLoginComplete((success) => {
111
+ console.log('Login:', success ? 'success' : 'failed');
112
+ });
113
+ setSdk(s);
114
+ return () => s.destroy();
115
+ }, []);
116
+
117
+ const handleLoad = () => {
118
+ if (sdk && iframeRef.current) {
119
+ sdk.setIframe(iframeRef.current);
120
+ sdk.initialize();
121
+ }
122
+ };
123
+
124
+ return <iframe ref={iframeRef} onLoad={handleLoad} src="..." />;
125
+ }
126
+ ```
127
+
128
+ ### Using mount helper
129
+
130
+ ```typescript
131
+ sdk.mount({
132
+ container: '#miniapp-container',
133
+ url: 'https://miniapp.com',
134
+ width: '100%',
135
+ height: '600px'
136
+ });
137
+ ```
138
+
139
+ ## License
140
+
141
+ Apache-2.0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Boxo pte. ltd.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Default SDK configuration
19
+ */
20
+ export declare const DEFAULT_CONFIG: {
21
+ readonly baseUrl: "https://dashboard.appboxo.com/api/v1";
22
+ readonly sandboxMode: false;
23
+ readonly debug: false;
24
+ };
25
+ /**
26
+ * Allowed origins for security validation
27
+ */
28
+ export declare const ALLOWED_ORIGINS: {
29
+ readonly production: readonly ["https://esim-finom-desktop.vercel.app", "https://staging.esim-finom-desktop.com"];
30
+ readonly development: readonly ["http://localhost:3000"];
31
+ };
32
+ /**
33
+ * SDK event types
34
+ */
35
+ export declare const EVENT_TYPES: {
36
+ readonly LOGIN: "AppBoxoWebAppLogin";
37
+ readonly PAYMENT: "AppBoxoWebAppPay";
38
+ readonly INIT_DATA: "AppBoxoWebAppGetInitData";
39
+ readonly CUSTOM: "AppBoxoWebAppCustomEvent";
40
+ };
41
+ /**
42
+ * SDK message type identifier
43
+ */
44
+ export declare const SDK_MESSAGE_TYPE = "appboxo-js-sdk";
45
+ /**
46
+ * SDK version
47
+ */
48
+ export declare const SDK_VERSION = "1.0.0";
49
+ /**
50
+ * Error codes
51
+ */
52
+ export declare const ERROR_CODES: {
53
+ readonly INVALID_ORIGIN: 400;
54
+ readonly MISSING_IFRAME: 400;
55
+ readonly AUTHENTICATION_FAILED: 401;
56
+ readonly PAYMENT_FAILED: 402;
57
+ readonly UNSUPPORTED_EVENT: 404;
58
+ readonly UNKNOWN: 500;
59
+ };
60
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;;;CAQlB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;CAKd,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD;;GAEG;AACH,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;CAOd,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Boxo pte. ltd.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Default SDK configuration
19
+ */
20
+ export const DEFAULT_CONFIG = {
21
+ baseUrl: 'https://dashboard.appboxo.com/api/v1',
22
+ sandboxMode: false,
23
+ debug: false,
24
+ };
25
+ /**
26
+ * Allowed origins for security validation
27
+ */
28
+ export const ALLOWED_ORIGINS = {
29
+ production: [
30
+ 'https://esim-finom-desktop.vercel.app',
31
+ 'https://staging.esim-finom-desktop.com',
32
+ ],
33
+ development: [
34
+ 'http://localhost:3000',
35
+ ],
36
+ };
37
+ /**
38
+ * SDK event types
39
+ */
40
+ export const EVENT_TYPES = {
41
+ LOGIN: 'AppBoxoWebAppLogin',
42
+ PAYMENT: 'AppBoxoWebAppPay',
43
+ INIT_DATA: 'AppBoxoWebAppGetInitData',
44
+ CUSTOM: 'AppBoxoWebAppCustomEvent',
45
+ };
46
+ /**
47
+ * SDK message type identifier
48
+ */
49
+ export const SDK_MESSAGE_TYPE = 'appboxo-js-sdk';
50
+ /**
51
+ * SDK version
52
+ */
53
+ export const SDK_VERSION = '1.0.0';
54
+ /**
55
+ * Error codes
56
+ */
57
+ export const ERROR_CODES = {
58
+ INVALID_ORIGIN: 400,
59
+ MISSING_IFRAME: 400,
60
+ AUTHENTICATION_FAILED: 401,
61
+ PAYMENT_FAILED: 402,
62
+ UNSUPPORTED_EVENT: 404,
63
+ UNKNOWN: 500,
64
+ };
65
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,sCAAsC;IAC/C,WAAW,EAAE,KAAK;IAClB,KAAK,EAAE,KAAK;CACJ,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV,uCAAuC;QACvC,wCAAwC;KACzC;IACD,WAAW,EAAE;QACX,uBAAuB;KACxB;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK,EAAE,oBAAoB;IAC3B,OAAO,EAAE,kBAAkB;IAC3B,SAAS,EAAE,0BAA0B;IACrC,MAAM,EAAE,0BAA0B;CAC1B,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc,EAAE,GAAG;IACnB,cAAc,EAAE,GAAG;IACnB,qBAAqB,EAAE,GAAG;IAC1B,cAAc,EAAE,GAAG;IACnB,iBAAiB,EAAE,GAAG;IACtB,OAAO,EAAE,GAAG;CACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Custom Event Handler
3
+ * Handles custom events from miniapp
4
+ */
5
+ import type { CustomEventHandler } from '../types';
6
+ export interface CustomEventHandlerConfig {
7
+ eventHandlers: Map<string, CustomEventHandler>;
8
+ log: (message: string, data?: any) => void;
9
+ sendResponseToMiniapp: (response: any) => void;
10
+ sendErrorResponse: (eventType: string, error: any, requestId?: string | number) => void;
11
+ }
12
+ /**
13
+ * Handle custom events
14
+ */
15
+ export declare function handleCustomEvent(params: any, requestId: string | number | undefined, config: CustomEventHandlerConfig): Promise<void>;
16
+ //# sourceMappingURL=customEventHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customEventHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/customEventHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC/C,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC3C,qBAAqB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/C,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;CACzF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,GAAG,EACX,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAuBf"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Custom Event Handler
3
+ * Handles custom events from miniapp
4
+ */
5
+ import { EVENT_TYPES } from '../constants';
6
+ import { createHostResponse } from '../utils/messageHelpers';
7
+ /**
8
+ * Handle custom events
9
+ */
10
+ export async function handleCustomEvent(params, requestId, config) {
11
+ try {
12
+ const { type, payload } = params;
13
+ const handler = config.eventHandlers.get(type);
14
+ if (!handler) {
15
+ throw new Error(`No handler registered for custom event: ${type}`);
16
+ }
17
+ const result = await handler(type, payload);
18
+ const response = createHostResponse(EVENT_TYPES.CUSTOM, result, requestId);
19
+ config.sendResponseToMiniapp(response);
20
+ config.log('Custom event handled', { type, result });
21
+ }
22
+ catch (error) {
23
+ config.log('Custom event failed', error);
24
+ config.sendErrorResponse('AppBoxoWebAppCustomEvent', error, requestId);
25
+ }
26
+ }
27
+ //# sourceMappingURL=customEventHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customEventHandler.js","sourceRoot":"","sources":["../../src/handlers/customEventHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAU7D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAW,EACX,SAAsC,EACtC,MAAgC;IAEhC,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,kBAAkB,CACjC,WAAW,CAAC,MAAM,EAClB,MAAM,EACN,SAAS,CACV,CAAC;QACF,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAEvC,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACzE,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Init Data Handler
3
+ * Handles init data events from miniapp
4
+ */
5
+ import type { InitDataRequest, SDKConfig } from '../types';
6
+ export interface InitDataHandlerConfig {
7
+ config: SDKConfig;
8
+ log: (message: string, data?: any) => void;
9
+ sendResponseToMiniapp: (response: any) => void;
10
+ sendErrorResponse: (eventType: string, error: any, requestId?: string | number) => void;
11
+ }
12
+ /**
13
+ * Handle init data events
14
+ */
15
+ export declare function handleInitDataEvent(params: InitDataRequest, requestId: string | number | undefined, config: InitDataHandlerConfig): Promise<void>;
16
+ //# sourceMappingURL=initDataHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initDataHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/initDataHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAoB,SAAS,EAAE,MAAM,UAAU,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC3C,qBAAqB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/C,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;CACzF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Init Data Handler
3
+ * Handles init data events from miniapp
4
+ */
5
+ import { EVENT_TYPES } from '../constants';
6
+ import { createHostResponse } from '../utils/messageHelpers';
7
+ /**
8
+ * Handle init data events
9
+ */
10
+ export async function handleInitDataEvent(params, requestId, config) {
11
+ try {
12
+ config.log('Handling init data event', params);
13
+ const initData = {
14
+ app_id: params.app_id,
15
+ client_id: params.client_id,
16
+ payload: params.payload,
17
+ data: params.data || {},
18
+ sandbox_mode: config.config.sandboxMode
19
+ };
20
+ const response = createHostResponse(EVENT_TYPES.INIT_DATA, initData, requestId);
21
+ config.sendResponseToMiniapp(response);
22
+ config.log('Init data sent', initData);
23
+ }
24
+ catch (error) {
25
+ config.log('Init data failed', error);
26
+ config.sendErrorResponse('AppBoxoWebAppGetInitData', error, requestId);
27
+ }
28
+ }
29
+ //# sourceMappingURL=initDataHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initDataHandler.js","sourceRoot":"","sources":["../../src/handlers/initDataHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAU7D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAuB,EACvB,SAAsC,EACtC,MAA6B;IAE7B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAqB;YACjC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;YACvB,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW;SACxC,CAAC;QAEF,MAAM,QAAQ,GAAG,kBAAkB,CACjC,WAAW,CAAC,SAAS,EACrB,QAAQ,EACR,SAAS,CACV,CAAC;QACF,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAEvC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACzE,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Login Handler
3
+ * Handles authentication events from miniapp
4
+ */
5
+ import type { LoginRequest, SDKConfig, LifecycleEventHandler } from '../types';
6
+ export interface LoginHandlerConfig {
7
+ config: SDKConfig;
8
+ authCode: string | null;
9
+ onGetAuthCode?: () => Promise<string>;
10
+ lifecycleHandlers: Map<string, LifecycleEventHandler>;
11
+ log: (message: string, data?: any) => void;
12
+ sendResponseToMiniapp: (response: any) => void;
13
+ sendErrorResponse: (eventType: string, error: any, requestId?: string | number) => void;
14
+ }
15
+ /**
16
+ * Handle login events
17
+ *
18
+ * Desktop SDK flow:
19
+ * 1. Miniapp calls appboxo.login()
20
+ * 2. Generate authCode from Desktop App session
21
+ * 3. Call Boxo Platform API to get auth_token
22
+ * 4. Return auth_token to miniapp
23
+ */
24
+ export declare function handleLoginEvent(params: LoginRequest, requestId: string | number | undefined, config: LoginHandlerConfig): Promise<void>;
25
+ //# sourceMappingURL=loginHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loginHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/loginHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,qBAAqB,EACtB,MAAM,UAAU,CAAC;AAGlB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACtD,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC3C,qBAAqB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/C,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;CACzF;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC,CAyCf"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Login Handler
3
+ * Handles authentication events from miniapp
4
+ */
5
+ import { EVENT_TYPES } from '../constants';
6
+ import { createHostResponse } from '../utils/messageHelpers';
7
+ import { generateAuthCode, exchangeAuthCodeForTokens } from '../utils/authHelper';
8
+ /**
9
+ * Handle login events
10
+ *
11
+ * Desktop SDK flow:
12
+ * 1. Miniapp calls appboxo.login()
13
+ * 2. Generate authCode from Desktop App session
14
+ * 3. Call Boxo Platform API to get auth_token
15
+ * 4. Return auth_token to miniapp
16
+ */
17
+ export async function handleLoginEvent(params, requestId, config) {
18
+ try {
19
+ config.log('Handling login event', params);
20
+ // Generate auth code
21
+ const authHelperConfig = {
22
+ config: config.config,
23
+ authCode: config.authCode,
24
+ onGetAuthCode: config.onGetAuthCode,
25
+ log: config.log
26
+ };
27
+ const authCode = await generateAuthCode(authHelperConfig);
28
+ // Exchange auth code for tokens
29
+ const { token, refresh_token } = await exchangeAuthCodeForTokens(authCode, authHelperConfig);
30
+ // Return token to miniapp
31
+ const response = createHostResponse(EVENT_TYPES.LOGIN, {
32
+ payload: {
33
+ token,
34
+ refresh_token
35
+ }
36
+ }, requestId);
37
+ config.log('Login response structure', JSON.stringify(response, null, 2));
38
+ config.sendResponseToMiniapp(response);
39
+ config.log('Login successful', { token, refresh_token });
40
+ // Call login complete callback if registered
41
+ const callback = config.lifecycleHandlers.get('login-complete');
42
+ if (callback)
43
+ callback(true, { token, refresh_token });
44
+ }
45
+ catch (error) {
46
+ config.log('Login failed', error);
47
+ config.sendErrorResponse('AppBoxoWebAppLogin', error, requestId);
48
+ }
49
+ }
50
+ //# sourceMappingURL=loginHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loginHandler.js","sourceRoot":"","sources":["../../src/handlers/loginHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAkBlF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAoB,EACpB,SAAsC,EACtC,MAA0B;IAE1B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;QAE3C,qBAAqB;QACrB,MAAM,gBAAgB,GAAqB;YACzC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,GAAG,EAAE,MAAM,CAAC,GAAG;SAChB,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;QAE1D,gCAAgC;QAChC,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,yBAAyB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAE7F,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,kBAAkB,CACjC,WAAW,CAAC,KAAK,EACjB;YACE,OAAO,EAAE;gBACP,KAAK;gBACL,aAAa;aACd;SACF,EACD,SAAS,CACV,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAEvC,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QAEzD,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAChE,IAAI,QAAQ;YAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,CAAC,iBAAiB,CAAC,oBAAoB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Payment Handler
3
+ * Handles payment events from miniapp
4
+ */
5
+ import type { PaymentRequest } from '../types';
6
+ export interface PaymentHandlerConfig {
7
+ log: (message: string, data?: any) => void;
8
+ sendResponseToMiniapp: (response: any) => void;
9
+ sendErrorResponse: (eventType: string, error: any, requestId?: string | number) => void;
10
+ }
11
+ /**
12
+ * Handle payment events
13
+ */
14
+ export declare function handlePaymentEvent(params: PaymentRequest, requestId: string | number | undefined, config: PaymentHandlerConfig): Promise<void>;
15
+ //# sourceMappingURL=paymentHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/paymentHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC3C,qBAAqB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/C,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;CACzF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Payment Handler
3
+ * Handles payment events from miniapp
4
+ */
5
+ import { EVENT_TYPES } from '../constants';
6
+ import { createHostResponse } from '../utils/messageHelpers';
7
+ import { processFinomPayment } from '../utils/paymentHelper';
8
+ /**
9
+ * Handle payment events
10
+ */
11
+ export async function handlePaymentEvent(params, requestId, config) {
12
+ try {
13
+ config.log('Handling payment event', params);
14
+ // Process payment through Finom
15
+ const paymentConfig = {
16
+ log: config.log
17
+ };
18
+ const result = await processFinomPayment(params, paymentConfig);
19
+ // Send success response
20
+ const response = createHostResponse(EVENT_TYPES.PAYMENT, {
21
+ status: result.status,
22
+ hostappOrderId: result.orderId,
23
+ transactionToken: params.transactionToken,
24
+ ...(result.transactionId && { transactionId: result.transactionId })
25
+ }, requestId);
26
+ config.sendResponseToMiniapp(response);
27
+ config.log('Payment processed', result);
28
+ }
29
+ catch (error) {
30
+ config.log('Payment failed', error);
31
+ config.sendErrorResponse('AppBoxoWebAppPay', error, requestId);
32
+ }
33
+ }
34
+ //# sourceMappingURL=paymentHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentHandler.js","sourceRoot":"","sources":["../../src/handlers/paymentHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAU7D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAsB,EACtB,SAAsC,EACtC,MAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;QAE7C,gCAAgC;QAChC,MAAM,aAAa,GAAwB;YACzC,GAAG,EAAE,MAAM,CAAC,GAAG;SAChB,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAEhE,wBAAwB;QACxB,MAAM,QAAQ,GAAG,kBAAkB,CACjC,WAAW,CAAC,OAAO,EACnB;YACE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,cAAc,EAAE,MAAM,CAAC,OAAO;YAC9B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC;SACrE,EACD,SAAS,CACV,CAAC;QACF,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAEvC,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Boxo pte. ltd.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { SDKConfig, CustomEventHandler } from './types';
18
+ /**
19
+ * Appboxo Web SDK for Desktop
20
+ * Handles communication between Desktop App and miniapps
21
+ */
22
+ declare class AppboxoWebSDK {
23
+ private config;
24
+ private iframeRef;
25
+ private eventHandlers;
26
+ private lifecycleHandlers;
27
+ private requestResolvers;
28
+ private baseUrl;
29
+ private isInitialized;
30
+ private authCode;
31
+ constructor(config: SDKConfig);
32
+ /**
33
+ * Initialize the SDK and start listening for events
34
+ */
35
+ initialize(): void;
36
+ /**
37
+ * Set the iframe reference for miniapp communication
38
+ */
39
+ setIframe(iframe: HTMLIFrameElement): void;
40
+ /**
41
+ * Mount miniapp to container (helper method)
42
+ * Creates iframe, sets reference, and initializes SDK
43
+ *
44
+ * @param config Configuration object with container, url, and optional styles
45
+ * @returns The created iframe element
46
+ */
47
+ mount(config: {
48
+ container: string | HTMLElement;
49
+ url: string;
50
+ width?: string;
51
+ height?: string;
52
+ className?: string;
53
+ }): HTMLIFrameElement;
54
+ /**
55
+ * Register custom event handler
56
+ */
57
+ onEvent(eventType: string, handler: CustomEventHandler): void;
58
+ /**
59
+ * Remove event handler
60
+ */
61
+ offEvent(eventType: string): void;
62
+ /**
63
+ * Register callback for when login completes
64
+ */
65
+ onLoginComplete(callback: (success: boolean, data?: any) => void): void;
66
+ /**
67
+ * Register callback for when payment completes
68
+ */
69
+ onPaymentComplete(callback: (success: boolean, data?: any) => void): void;
70
+ /**
71
+ * Set auth code explicitly (like React Native SDK pattern)
72
+ */
73
+ setAuthCode(authCode: string): void;
74
+ /**
75
+ * Setup event listeners for miniapp communication
76
+ */
77
+ private setupEventListeners;
78
+ /**
79
+ * Handle incoming events from miniapp
80
+ */
81
+ private handleMiniappEvent;
82
+ /**
83
+ * Send response back to miniapp
84
+ */
85
+ private sendResponseToMiniapp;
86
+ /**
87
+ * Send error response to miniapp
88
+ */
89
+ private sendErrorResponse;
90
+ /**
91
+ * Logging utility
92
+ */
93
+ private log;
94
+ /**
95
+ * Cleanup resources
96
+ */
97
+ destroy(): void;
98
+ }
99
+ export { AppboxoWebSDK };
100
+ export default AppboxoWebSDK;
101
+ export type { SDKConfig, MiniappEvent, HostAppResponse, LoginRequest, PaymentRequest, InitDataRequest, LoginResponse, PaymentResponse, InitDataResponse, CustomEventHandler, LifecycleEventHandler, FinomLoginCredentials, FinomAuthTokens, FinomPaymentResult, } from './types';
102
+ export * from './utils';
103
+ export * from './constants';
104
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,OAAO,KAAK,EACV,SAAS,EAST,kBAAkB,EAMnB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,iBAAiB,CAAiD;IAC1E,OAAO,CAAC,gBAAgB,CAAsD;IAC9E,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,MAAM,EAAE,SAAS;IAW7B;;OAEG;IACI,UAAU,IAAI,IAAI;IAWzB;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAKjD;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,EAAE;QACnB,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC;QAChC,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,iBAAiB;IA8BrB;;OAEG;IACI,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAKpE;;OAEG;IACI,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKxC;;OAEG;IACI,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAI9E;;OAEG;IACI,iBAAiB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAIhF;;OAEG;IACI,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK1C;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkE1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACI,OAAO,IAAI,IAAI;CASvB;AAGD,OAAO,EAAE,aAAa,EAAE,CAAC;AAGzB,eAAe,aAAa,CAAC;AAG7B,YAAY,EACV,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,cAAc,SAAS,CAAC;AAGxB,cAAc,aAAa,CAAC"}