@vybit/oauth2-sdk 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -6,6 +6,12 @@ OAuth 2.0 authentication SDK for Vybit.
6
6
 
7
7
  Complete OAuth2 implementation for Vybit authentication, including authorization URL generation, token exchange, and authenticated API calls.
8
8
 
9
+ ## Setup
10
+
11
+ 1. Create a [Vybit developer account](https://developer.vybit.net)
12
+ 2. Navigate to OAUTH CONFIGURATION and specify a service name
13
+ 3. Store your VYBIT_CLIENT_ID and VYBIT_CLIENT_SECRET (use environment variables)
14
+
9
15
  ## Installation
10
16
 
11
17
  ```bash
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@vybit/oauth2-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "OAuth 2.0 SDK for Vybit authentication and authorization",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
- "build": "tsc",
9
- "clean": "rm -rf dist",
8
+ "build": "tsc -b",
9
+ "clean": "rm -rf dist *.tsbuildinfo",
10
10
  "dev": "tsc --watch",
11
- "test": "jest --config ../../jest.config.js --rootDir ../.."
11
+ "test": "jest --config ../../jest.config.js --rootDir ../..",
12
+ "lint": "echo 'Run lint from root: npm run lint'"
12
13
  },
13
14
  "keywords": [
14
15
  "vybit",
@@ -16,7 +17,7 @@
16
17
  "authentication",
17
18
  "sdk"
18
19
  ],
19
- "author": "Vybit Team",
20
+ "author": "Flatirontek LLC",
20
21
  "license": "MIT",
21
22
  "repository": {
22
23
  "type": "git",
@@ -38,7 +39,7 @@
38
39
  "node": ">=16.0.0"
39
40
  },
40
41
  "dependencies": {
41
- "@vybit/core": "^1.0.1"
42
+ "@vybit/core": "^1.1.0"
42
43
  },
43
44
  "peerDependencies": {
44
45
  "node-fetch": "^3.0.0"
@@ -48,4 +49,4 @@
48
49
  "optional": true
49
50
  }
50
51
  }
51
- }
52
+ }
@@ -1,8 +0,0 @@
1
- /**
2
- * OAuth2 Client Tests
3
- *
4
- * These tests mirror the exact functionality tested in the developer portal,
5
- * covering all 6 steps of the OAuth flow.
6
- */
7
- export {};
8
- //# sourceMappingURL=oauth2-client.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth2-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/oauth2-client.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1,267 +0,0 @@
1
- "use strict";
2
- /**
3
- * OAuth2 Client Tests
4
- *
5
- * These tests mirror the exact functionality tested in the developer portal,
6
- * covering all 6 steps of the OAuth flow.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const oauth2_client_1 = require("../oauth2-client");
10
- const core_1 = require("@vybit/core");
11
- // Mock fetch globally
12
- const mockFetch = jest.fn();
13
- global.fetch = mockFetch;
14
- describe('VybitOAuth2Client', () => {
15
- let client;
16
- const validConfig = {
17
- clientId: 'test-client-id',
18
- clientSecret: 'test-client-secret',
19
- redirectUri: 'https://example.com/callback'
20
- };
21
- beforeEach(() => {
22
- client = new oauth2_client_1.VybitOAuth2Client(validConfig);
23
- mockFetch.mockClear();
24
- });
25
- describe('Configuration Validation', () => {
26
- it('should validate required configuration', () => {
27
- expect(() => new oauth2_client_1.VybitOAuth2Client({
28
- ...validConfig,
29
- clientId: ''
30
- })).toThrow(core_1.VybitValidationError);
31
- expect(() => new oauth2_client_1.VybitOAuth2Client({
32
- ...validConfig,
33
- clientSecret: ''
34
- })).toThrow(core_1.VybitValidationError);
35
- expect(() => new oauth2_client_1.VybitOAuth2Client({
36
- ...validConfig,
37
- redirectUri: ''
38
- })).toThrow(core_1.VybitValidationError);
39
- });
40
- it('should validate redirect URI format', () => {
41
- expect(() => new oauth2_client_1.VybitOAuth2Client({
42
- ...validConfig,
43
- redirectUri: 'invalid-url'
44
- })).toThrow(core_1.VybitValidationError);
45
- });
46
- it('should accept valid configuration', () => {
47
- expect(() => new oauth2_client_1.VybitOAuth2Client(validConfig)).not.toThrow();
48
- });
49
- });
50
- describe('Step 1: Authorization URL Generation', () => {
51
- it('should generate correct authorization URL', () => {
52
- const authUrl = client.getAuthorizationUrl();
53
- expect(authUrl).toContain('https://app.vybit.net');
54
- expect(authUrl).toContain('client_id=test-client-id');
55
- expect(authUrl).toContain('redirect_uri=https%3A%2F%2Fexample.com%2Fcallback');
56
- expect(authUrl).toContain('response_type=code');
57
- expect(authUrl).toContain('state=');
58
- });
59
- it('should use custom state when provided', () => {
60
- const customState = 'custom-state-123';
61
- const authUrl = client.getAuthorizationUrl({ state: customState });
62
- expect(authUrl).toContain(`state=${customState}`);
63
- });
64
- it('should include scope when provided', () => {
65
- const authUrl = client.getAuthorizationUrl({ scope: 'read' });
66
- expect(authUrl).toContain('scope=read');
67
- });
68
- it('should always use production domain', () => {
69
- const authUrl = client.getAuthorizationUrl();
70
- expect(authUrl).toContain('https://app.vybit.net');
71
- });
72
- });
73
- describe('Step 3: Token Exchange', () => {
74
- it('should successfully exchange code for token', async () => {
75
- const mockTokenResponse = {
76
- access_token: 'test-access-token',
77
- token_type: 'Bearer'
78
- };
79
- mockFetch.mockResolvedValueOnce({
80
- ok: true,
81
- json: () => Promise.resolve(mockTokenResponse)
82
- });
83
- const result = await client.exchangeCodeForToken('test-auth-code');
84
- expect(result).toEqual(mockTokenResponse);
85
- expect(client.getAccessToken()).toBe('test-access-token');
86
- // Verify correct API call
87
- expect(mockFetch).toHaveBeenCalledWith('https://app.vybit.net/service/token', expect.objectContaining({
88
- method: 'POST',
89
- headers: {
90
- 'Content-Type': 'application/x-www-form-urlencoded'
91
- },
92
- body: expect.any(URLSearchParams)
93
- }));
94
- });
95
- it('should handle token exchange errors', async () => {
96
- mockFetch.mockResolvedValueOnce({
97
- ok: false,
98
- status: 400,
99
- statusText: 'Bad Request'
100
- });
101
- await expect(client.exchangeCodeForToken('invalid-code')).rejects.toThrow(core_1.VybitAPIError);
102
- });
103
- it('should handle auth errors in response', async () => {
104
- mockFetch.mockResolvedValueOnce({
105
- ok: true,
106
- json: () => Promise.resolve({ error: 'invalid_client' })
107
- });
108
- await expect(client.exchangeCodeForToken('test-code')).rejects.toThrow(core_1.VybitAuthError);
109
- });
110
- });
111
- describe('Step 4: Token Verification', () => {
112
- beforeEach(() => {
113
- client.setAccessToken('test-token');
114
- });
115
- it('should verify valid token', async () => {
116
- mockFetch.mockResolvedValueOnce({
117
- ok: true,
118
- json: () => Promise.resolve({ status: 'ok' })
119
- });
120
- const isValid = await client.verifyToken();
121
- expect(isValid).toBe(true);
122
- expect(mockFetch).toHaveBeenCalledWith('https://vybit.net/service/test', {
123
- headers: {
124
- Authorization: 'Bearer test-token'
125
- }
126
- });
127
- });
128
- it('should handle invalid token', async () => {
129
- mockFetch.mockResolvedValueOnce({
130
- ok: false,
131
- status: 401
132
- });
133
- const isValid = await client.verifyToken();
134
- expect(isValid).toBe(false);
135
- });
136
- it('should handle network errors gracefully', async () => {
137
- mockFetch.mockRejectedValueOnce(new Error('Network error'));
138
- const isValid = await client.verifyToken();
139
- expect(isValid).toBe(false);
140
- });
141
- it('should require access token', async () => {
142
- const clientWithoutToken = new oauth2_client_1.VybitOAuth2Client(validConfig);
143
- await expect(clientWithoutToken.verifyToken()).rejects.toThrow(core_1.VybitAuthError);
144
- });
145
- });
146
- describe('Step 5: Get Vybit List', () => {
147
- beforeEach(() => {
148
- client.setAccessToken('test-token');
149
- });
150
- it('should fetch vybit list successfully', async () => {
151
- const mockVybitResponse = {
152
- '0': { name: 'My Alert', triggerKey: 'abc123def456' },
153
- '1': { name: 'Notification Sound', triggerKey: 'def456ghi789' },
154
- '2': { name: 'Status Update', triggerKey: 'ghi789jkl012' }
155
- };
156
- mockFetch.mockResolvedValueOnce({
157
- ok: true,
158
- json: () => Promise.resolve(mockVybitResponse)
159
- });
160
- const vybits = await client.getVybitList();
161
- expect(vybits).toHaveLength(3);
162
- expect(vybits[0]).toEqual({ name: 'My Alert', triggerKey: 'abc123def456' });
163
- expect(vybits[1]).toEqual({ name: 'Notification Sound', triggerKey: 'def456ghi789' });
164
- expect(vybits[2]).toEqual({ name: 'Status Update', triggerKey: 'ghi789jkl012' });
165
- expect(mockFetch).toHaveBeenCalledWith('https://vybit.net/rest/vybit_list', {
166
- headers: {
167
- Authorization: 'Bearer test-token'
168
- }
169
- });
170
- });
171
- it('should handle API errors', async () => {
172
- mockFetch.mockResolvedValueOnce({
173
- ok: false,
174
- status: 403,
175
- statusText: 'Forbidden'
176
- });
177
- await expect(client.getVybitList()).rejects.toThrow(core_1.VybitAPIError);
178
- });
179
- it('should require access token', async () => {
180
- const clientWithoutToken = new oauth2_client_1.VybitOAuth2Client(validConfig);
181
- await expect(clientWithoutToken.getVybitList()).rejects.toThrow(core_1.VybitAuthError);
182
- });
183
- });
184
- describe('Step 6: Send Vybit Notification', () => {
185
- beforeEach(() => {
186
- client.setAccessToken('test-token');
187
- });
188
- it('should send notification with all optional parameters', async () => {
189
- const mockResponse = {
190
- result: 1,
191
- plk: 'bbxope6xhryminef'
192
- };
193
- mockFetch.mockResolvedValueOnce({
194
- ok: true,
195
- json: () => Promise.resolve(mockResponse)
196
- });
197
- const triggerOptions = {
198
- message: 'Test notification',
199
- imageUrl: 'https://example.com/image.jpg',
200
- linkUrl: 'https://example.com/redirect',
201
- log: 'Test log entry <a href="https://example.com">link</a>'
202
- };
203
- const result = await client.sendVybitNotification('test-trigger-key', triggerOptions);
204
- expect(result).toEqual(mockResponse);
205
- // Verify the API call
206
- const [url, options] = mockFetch.mock.calls[0];
207
- expect(url).toBe('https://vybit.net/fire/test-trigger-key');
208
- expect(options.method).toBe('POST');
209
- expect(options.headers['Authorization']).toBe('Bearer test-token');
210
- expect(options.headers['Content-Type']).toBe('application/json');
211
- const body = JSON.parse(options.body);
212
- expect(body).toEqual(triggerOptions);
213
- });
214
- it('should send notification with minimal parameters', async () => {
215
- const mockResponse = { result: 1, plk: 'test-plk' };
216
- mockFetch.mockResolvedValueOnce({
217
- ok: true,
218
- json: () => Promise.resolve(mockResponse)
219
- });
220
- const result = await client.sendVybitNotification('test-trigger-key');
221
- expect(result).toEqual(mockResponse);
222
- const body = JSON.parse(mockFetch.mock.calls[0][1].body);
223
- expect(body).toEqual({});
224
- });
225
- it('should validate URL parameters', async () => {
226
- await expect(client.sendVybitNotification('test-key', {
227
- imageUrl: 'invalid-url'
228
- })).rejects.toThrow(core_1.VybitValidationError);
229
- await expect(client.sendVybitNotification('test-key', {
230
- linkUrl: 'also-invalid'
231
- })).rejects.toThrow(core_1.VybitValidationError);
232
- });
233
- it('should handle API errors', async () => {
234
- mockFetch.mockResolvedValueOnce({
235
- ok: false,
236
- status: 404,
237
- statusText: 'Not Found'
238
- });
239
- await expect(client.sendVybitNotification('invalid-key')).rejects.toThrow(core_1.VybitAPIError);
240
- });
241
- it('should require access token', async () => {
242
- const clientWithoutToken = new oauth2_client_1.VybitOAuth2Client(validConfig);
243
- await expect(clientWithoutToken.sendVybitNotification('test-key')).rejects.toThrow(core_1.VybitAuthError);
244
- });
245
- });
246
- describe('Token Management', () => {
247
- it('should set and get access token', () => {
248
- expect(client.getAccessToken()).toBeUndefined();
249
- client.setAccessToken('new-token');
250
- expect(client.getAccessToken()).toBe('new-token');
251
- });
252
- it('should allow overriding token in API calls', async () => {
253
- client.setAccessToken('default-token');
254
- mockFetch.mockResolvedValueOnce({
255
- ok: true,
256
- json: () => Promise.resolve({ status: 'ok' })
257
- });
258
- await client.verifyToken('override-token');
259
- expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
260
- headers: expect.objectContaining({
261
- Authorization: 'Bearer override-token'
262
- })
263
- }));
264
- });
265
- });
266
- });
267
- //# sourceMappingURL=oauth2-client.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth2-client.test.js","sourceRoot":"","sources":["../../src/__tests__/oauth2-client.test.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAEH,oDAAqD;AACrD,sCAAkF;AAElF,sBAAsB;AACtB,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,MAAM,CAAC,KAAK,GAAG,SAAgB,CAAC;AAEhC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAI,MAAyB,CAAC;IAE9B,MAAM,WAAW,GAAG;QAClB,QAAQ,EAAE,gBAAgB;QAC1B,YAAY,EAAE,oBAAoB;QAClC,WAAW,EAAE,8BAA8B;KAC5C,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,IAAI,iCAAiB,CAAC,WAAW,CAAC,CAAC;QAC5C,SAAS,CAAC,SAAS,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,iCAAiB,CAAC;gBACjC,GAAG,WAAW;gBACd,QAAQ,EAAE,EAAE;aACb,CAAC,CAAC,CAAC,OAAO,CAAC,2BAAoB,CAAC,CAAC;YAElC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,iCAAiB,CAAC;gBACjC,GAAG,WAAW;gBACd,YAAY,EAAE,EAAE;aACjB,CAAC,CAAC,CAAC,OAAO,CAAC,2BAAoB,CAAC,CAAC;YAElC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,iCAAiB,CAAC;gBACjC,GAAG,WAAW;gBACd,WAAW,EAAE,EAAE;aAChB,CAAC,CAAC,CAAC,OAAO,CAAC,2BAAoB,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,iCAAiB,CAAC;gBACjC,GAAG,WAAW;gBACd,WAAW,EAAE,aAAa;aAC3B,CAAC,CAAC,CAAC,OAAO,CAAC,2BAAoB,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,iCAAiB,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;QACpD,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAE7C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACnD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YACtD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,mDAAmD,CAAC,CAAC;YAC/E,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,WAAW,GAAG,kBAAkB,CAAC;YACvC,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;YAEnE,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAE9D,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,iBAAiB,GAAG;gBACxB,YAAY,EAAE,mBAAmB;gBACjC,UAAU,EAAE,QAAQ;aACrB,CAAC;YAEF,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;aAC/C,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;YAEnE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAE1D,0BAA0B;YAC1B,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,qCAAqC,EACrC,MAAM,CAAC,gBAAgB,CAAC;gBACtB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,mCAAmC;iBACpD;gBACD,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;aAClC,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACnD,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,UAAU,EAAE,aAAa;aAC1B,CAAC,CAAC;YAEH,MAAM,MAAM,CACV,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAC5C,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAa,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACrD,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;aACzD,CAAC,CAAC;YAEH,MAAM,MAAM,CACV,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,CACzC,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAc,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;YACzC,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE3B,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,gCAAgC,EAChC;gBACE,OAAO,EAAE;oBACP,aAAa,EAAE,mBAAmB;iBACnC;aACF,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;aACZ,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,SAAS,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;YAE5D,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,kBAAkB,GAAG,IAAI,iCAAiB,CAAC,WAAW,CAAC,CAAC;YAE9D,MAAM,MAAM,CACV,kBAAkB,CAAC,WAAW,EAAE,CACjC,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAc,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,iBAAiB,GAAG;gBACxB,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE;gBACrD,GAAG,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE;gBAC/D,GAAG,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE;aAC3D,CAAC;YAEF,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;aAC/C,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;YAE3C,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;YAC5E,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;YACtF,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;YAEjF,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,mCAAmC,EACnC;gBACE,OAAO,EAAE;oBACP,aAAa,EAAE,mBAAmB;iBACnC;aACF,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,UAAU,EAAE,WAAW;aACxB,CAAC,CAAC;YAEH,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAa,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,kBAAkB,GAAG,IAAI,iCAAiB,CAAC,WAAW,CAAC,CAAC;YAE9D,MAAM,MAAM,CACV,kBAAkB,CAAC,YAAY,EAAE,CAClC,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAc,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC/C,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,YAAY,GAAG;gBACnB,MAAM,EAAE,CAAC;gBACT,GAAG,EAAE,kBAAkB;aACxB,CAAC;YAEF,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC;aAC1C,CAAC,CAAC;YAEH,MAAM,cAAc,GAAG;gBACrB,OAAO,EAAE,mBAAmB;gBAC5B,QAAQ,EAAE,+BAA+B;gBACzC,OAAO,EAAE,8BAA8B;gBACvC,GAAG,EAAE,uDAAuD;aAC7D,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAEtF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAErC,sBAAsB;YACtB,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;YAC5D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACnE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAEjE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;YAEpD,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC;aAC1C,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;YAEtE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAErC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,MAAM,CACV,MAAM,CAAC,qBAAqB,CAAC,UAAU,EAAE;gBACvC,QAAQ,EAAE,aAAa;aACxB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,2BAAoB,CAAC,CAAC;YAExC,MAAM,MAAM,CACV,MAAM,CAAC,qBAAqB,CAAC,UAAU,EAAE;gBACvC,OAAO,EAAE,cAAc;aACxB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,2BAAoB,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACxC,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,UAAU,EAAE,WAAW;aACxB,CAAC,CAAC;YAEH,MAAM,MAAM,CACV,MAAM,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAC5C,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAa,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;YAC3C,MAAM,kBAAkB,GAAG,IAAI,iCAAiB,CAAC,WAAW,CAAC,CAAC;YAE9D,MAAM,MAAM,CACV,kBAAkB,CAAC,qBAAqB,CAAC,UAAU,CAAC,CACrD,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAc,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC;YAEhD,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YACnC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YAEvC,SAAS,CAAC,qBAAqB,CAAC;gBAC9B,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,MAAM,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;YAE3C,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAClB,MAAM,CAAC,gBAAgB,CAAC;gBACtB,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC;oBAC/B,aAAa,EAAE,uBAAuB;iBACvC,CAAC;aACH,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}