@sumicom/quicksave 0.1.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 (58) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai/commitSummary.d.ts +26 -0
  3. package/dist/ai/commitSummary.d.ts.map +1 -0
  4. package/dist/ai/commitSummary.js +145 -0
  5. package/dist/ai/commitSummary.js.map +1 -0
  6. package/dist/config.d.ts +22 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +76 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/connection/connection.d.ts +54 -0
  11. package/dist/connection/connection.d.ts.map +1 -0
  12. package/dist/connection/connection.js +171 -0
  13. package/dist/connection/connection.js.map +1 -0
  14. package/dist/connection/signaling.d.ts +31 -0
  15. package/dist/connection/signaling.d.ts.map +1 -0
  16. package/dist/connection/signaling.js +144 -0
  17. package/dist/connection/signaling.js.map +1 -0
  18. package/dist/git/operations.d.ts +104 -0
  19. package/dist/git/operations.d.ts.map +1 -0
  20. package/dist/git/operations.js +383 -0
  21. package/dist/git/operations.js.map +1 -0
  22. package/dist/git/operations.test.d.ts +2 -0
  23. package/dist/git/operations.test.d.ts.map +1 -0
  24. package/dist/git/operations.test.js +232 -0
  25. package/dist/git/operations.test.js.map +1 -0
  26. package/dist/handlers/messageHandler.d.ts +33 -0
  27. package/dist/handlers/messageHandler.d.ts.map +1 -0
  28. package/dist/handlers/messageHandler.js +463 -0
  29. package/dist/handlers/messageHandler.js.map +1 -0
  30. package/dist/handlers/messageHandler.test.d.ts +2 -0
  31. package/dist/handlers/messageHandler.test.d.ts.map +1 -0
  32. package/dist/handlers/messageHandler.test.js +233 -0
  33. package/dist/handlers/messageHandler.test.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +127 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/webrtc/connection.d.ts +52 -0
  39. package/dist/webrtc/connection.d.ts.map +1 -0
  40. package/dist/webrtc/connection.js +255 -0
  41. package/dist/webrtc/connection.js.map +1 -0
  42. package/dist/webrtc/signaling.d.ts +41 -0
  43. package/dist/webrtc/signaling.d.ts.map +1 -0
  44. package/dist/webrtc/signaling.js +152 -0
  45. package/dist/webrtc/signaling.js.map +1 -0
  46. package/package.json +36 -0
  47. package/src/ai/commitSummary.ts +199 -0
  48. package/src/config.ts +97 -0
  49. package/src/connection/connection.ts +223 -0
  50. package/src/connection/signaling.ts +172 -0
  51. package/src/git/operations.test.ts +305 -0
  52. package/src/git/operations.ts +443 -0
  53. package/src/handlers/messageHandler.test.ts +294 -0
  54. package/src/handlers/messageHandler.ts +550 -0
  55. package/src/index.ts +151 -0
  56. package/src/types/webrtc.d.ts +38 -0
  57. package/tsconfig.json +13 -0
  58. package/vitest.config.ts +9 -0
@@ -0,0 +1,233 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { MessageHandler } from './messageHandler.js';
3
+ import { createMessage } from '@sumicom/quicksave-shared';
4
+ import { mkdir, writeFile, rm } from 'fs/promises';
5
+ import { join } from 'path';
6
+ import { tmpdir } from 'os';
7
+ import { simpleGit } from 'simple-git';
8
+ describe('MessageHandler', () => {
9
+ let testRepoPath;
10
+ let handler;
11
+ let defaultBranch;
12
+ beforeEach(async () => {
13
+ // Create temporary test repo
14
+ testRepoPath = join(tmpdir(), `quicksave-handler-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
15
+ await mkdir(testRepoPath, { recursive: true });
16
+ // Initialize git repo
17
+ const git = simpleGit(testRepoPath);
18
+ await git.init();
19
+ await git.addConfig('user.email', 'test@test.com');
20
+ await git.addConfig('user.name', 'Test User');
21
+ // Create initial commit
22
+ await writeFile(join(testRepoPath, 'README.md'), '# Test Repo\n');
23
+ await git.add('README.md');
24
+ await git.commit('Initial commit');
25
+ // Get the default branch name (could be 'main' or 'master' depending on git config)
26
+ const status = await git.status();
27
+ defaultBranch = status.current || 'main';
28
+ handler = new MessageHandler([{ path: testRepoPath, name: 'test-repo' }]);
29
+ });
30
+ afterEach(async () => {
31
+ try {
32
+ await rm(testRepoPath, { recursive: true, force: true });
33
+ }
34
+ catch {
35
+ // Ignore cleanup errors
36
+ }
37
+ });
38
+ describe('handleMessage - ping/pong', () => {
39
+ it('should respond to ping with pong', async () => {
40
+ const message = createMessage('ping', { timestamp: Date.now() });
41
+ const response = await handler.handleMessage(message);
42
+ expect(response.type).toBe('pong');
43
+ expect(response.payload).toHaveProperty('timestamp');
44
+ });
45
+ });
46
+ describe('handleMessage - handshake', () => {
47
+ it('should respond to handshake with ack', async () => {
48
+ const message = createMessage('handshake', { publicKey: 'test-key' });
49
+ const response = await handler.handleMessage(message);
50
+ expect(response.type).toBe('handshake:ack');
51
+ expect(response.id).toBe(message.id);
52
+ expect(response.payload.success).toBe(true);
53
+ expect(response.payload.agentVersion).toBe('0.1.0');
54
+ expect(response.payload.repoPath).toBe(testRepoPath);
55
+ });
56
+ });
57
+ describe('handleMessage - git:status', () => {
58
+ it('should return git status', async () => {
59
+ const message = createMessage('git:status', {});
60
+ const response = await handler.handleMessage(message);
61
+ expect(response.type).toBe('git:status:response');
62
+ expect(response.id).toBe(message.id);
63
+ const payload = response.payload;
64
+ expect(payload.branch).toBe(defaultBranch);
65
+ expect(Array.isArray(payload.staged)).toBe(true);
66
+ expect(Array.isArray(payload.unstaged)).toBe(true);
67
+ expect(Array.isArray(payload.untracked)).toBe(true);
68
+ });
69
+ it('should detect changes in status', async () => {
70
+ await writeFile(join(testRepoPath, 'newfile.txt'), 'content');
71
+ const message = createMessage('git:status', {});
72
+ const response = await handler.handleMessage(message);
73
+ const payload = response.payload;
74
+ expect(payload.untracked).toContain('newfile.txt');
75
+ });
76
+ });
77
+ describe('handleMessage - git:diff', () => {
78
+ it('should return diff for modified file', async () => {
79
+ await writeFile(join(testRepoPath, 'README.md'), '# Modified\n');
80
+ const message = createMessage('git:diff', { path: 'README.md', staged: false });
81
+ const response = await handler.handleMessage(message);
82
+ expect(response.type).toBe('git:diff:response');
83
+ expect(response.id).toBe(message.id);
84
+ const payload = response.payload;
85
+ expect(payload.path).toBe('README.md');
86
+ expect(payload.hunks.length).toBeGreaterThan(0);
87
+ });
88
+ });
89
+ describe('handleMessage - git:stage', () => {
90
+ it('should stage files successfully', async () => {
91
+ await writeFile(join(testRepoPath, 'newfile.txt'), 'content');
92
+ const message = createMessage('git:stage', { paths: ['newfile.txt'] });
93
+ const response = await handler.handleMessage(message);
94
+ expect(response.type).toBe('git:stage:response');
95
+ expect(response.payload.success).toBe(true);
96
+ // Verify file was staged
97
+ const statusMsg = createMessage('git:status', {});
98
+ const statusResp = await handler.handleMessage(statusMsg);
99
+ const status = statusResp.payload;
100
+ expect(status.staged.some((f) => f.path === 'newfile.txt')).toBe(true);
101
+ });
102
+ it('should return error for invalid path', async () => {
103
+ const message = createMessage('git:stage', { paths: ['nonexistent.txt'] });
104
+ const response = await handler.handleMessage(message);
105
+ expect(response.type).toBe('git:stage:response');
106
+ expect(response.payload.success).toBe(false);
107
+ expect(response.payload.error).toBeDefined();
108
+ });
109
+ });
110
+ describe('handleMessage - git:unstage', () => {
111
+ it('should unstage files successfully', async () => {
112
+ await writeFile(join(testRepoPath, 'newfile.txt'), 'content');
113
+ await simpleGit(testRepoPath).add('newfile.txt');
114
+ const message = createMessage('git:unstage', { paths: ['newfile.txt'] });
115
+ const response = await handler.handleMessage(message);
116
+ expect(response.type).toBe('git:unstage:response');
117
+ expect(response.payload.success).toBe(true);
118
+ });
119
+ });
120
+ describe('handleMessage - git:commit', () => {
121
+ it('should create commit successfully', async () => {
122
+ await writeFile(join(testRepoPath, 'newfile.txt'), 'content');
123
+ await simpleGit(testRepoPath).add('newfile.txt');
124
+ const message = createMessage('git:commit', { message: 'Test commit' });
125
+ const response = await handler.handleMessage(message);
126
+ expect(response.type).toBe('git:commit:response');
127
+ expect(response.payload.success).toBe(true);
128
+ expect(response.payload.hash).toBeDefined();
129
+ });
130
+ it('should create commit with description', async () => {
131
+ await writeFile(join(testRepoPath, 'newfile.txt'), 'content');
132
+ await simpleGit(testRepoPath).add('newfile.txt');
133
+ const message = createMessage('git:commit', {
134
+ message: 'Title',
135
+ description: 'Extended description',
136
+ });
137
+ const response = await handler.handleMessage(message);
138
+ expect(response.type).toBe('git:commit:response');
139
+ expect(response.payload.success).toBe(true);
140
+ });
141
+ it('should handle empty commit gracefully', async () => {
142
+ const message = createMessage('git:commit', { message: 'Empty commit' });
143
+ const response = await handler.handleMessage(message);
144
+ // The behavior depends on git - it might succeed with empty commit or fail
145
+ // We just verify it returns a proper response
146
+ expect(response.type).toBe('git:commit:response');
147
+ });
148
+ });
149
+ describe('handleMessage - git:log', () => {
150
+ it('should return commit log', async () => {
151
+ const message = createMessage('git:log', { limit: 10 });
152
+ const response = await handler.handleMessage(message);
153
+ expect(response.type).toBe('git:log:response');
154
+ expect(response.id).toBe(message.id);
155
+ const payload = response.payload;
156
+ expect(Array.isArray(payload.commits)).toBe(true);
157
+ expect(payload.commits.length).toBeGreaterThan(0);
158
+ expect(payload.commits[0].message).toBe('Initial commit');
159
+ });
160
+ it('should use default limit when not specified', async () => {
161
+ const message = createMessage('git:log', {});
162
+ const response = await handler.handleMessage(message);
163
+ expect(response.type).toBe('git:log:response');
164
+ });
165
+ });
166
+ describe('handleMessage - git:branches', () => {
167
+ it('should return branches', async () => {
168
+ const message = createMessage('git:branches', {});
169
+ const response = await handler.handleMessage(message);
170
+ expect(response.type).toBe('git:branches:response');
171
+ const payload = response.payload;
172
+ expect(Array.isArray(payload.branches)).toBe(true);
173
+ expect(payload.current).toBe(defaultBranch);
174
+ });
175
+ });
176
+ describe('handleMessage - git:checkout', () => {
177
+ it('should checkout existing branch', async () => {
178
+ await simpleGit(testRepoPath).checkoutLocalBranch('feature');
179
+ const message = createMessage('git:checkout', { branch: defaultBranch });
180
+ const response = await handler.handleMessage(message);
181
+ expect(response.type).toBe('git:checkout:response');
182
+ expect(response.payload.success).toBe(true);
183
+ });
184
+ it('should create and checkout new branch', async () => {
185
+ const message = createMessage('git:checkout', { branch: 'new-feature', create: true });
186
+ const response = await handler.handleMessage(message);
187
+ expect(response.type).toBe('git:checkout:response');
188
+ expect(response.payload.success).toBe(true);
189
+ // Verify branch was created
190
+ const branchMsg = createMessage('git:branches', {});
191
+ const branchResp = await handler.handleMessage(branchMsg);
192
+ expect(branchResp.payload.current).toBe('new-feature');
193
+ });
194
+ it('should fail for non-existent branch', async () => {
195
+ const message = createMessage('git:checkout', { branch: 'nonexistent' });
196
+ const response = await handler.handleMessage(message);
197
+ expect(response.type).toBe('git:checkout:response');
198
+ expect(response.payload.success).toBe(false);
199
+ });
200
+ });
201
+ describe('handleMessage - git:discard', () => {
202
+ it('should discard changes', async () => {
203
+ await writeFile(join(testRepoPath, 'README.md'), '# Modified\n');
204
+ const message = createMessage('git:discard', { paths: ['README.md'] });
205
+ const response = await handler.handleMessage(message);
206
+ expect(response.type).toBe('git:discard:response');
207
+ expect(response.payload.success).toBe(true);
208
+ // Verify changes were discarded
209
+ const statusMsg = createMessage('git:status', {});
210
+ const statusResp = await handler.handleMessage(statusMsg);
211
+ expect(statusResp.payload.unstaged).toHaveLength(0);
212
+ });
213
+ });
214
+ describe('handleMessage - unknown type', () => {
215
+ it('should return error for unknown message type', async () => {
216
+ const message = createMessage('unknown:type', {});
217
+ const response = await handler.handleMessage(message);
218
+ expect(response.type).toBe('error');
219
+ expect(response.payload.code).toBe('UNKNOWN_MESSAGE_TYPE');
220
+ });
221
+ });
222
+ describe('handleMessage - error handling', () => {
223
+ it('should preserve message ID in responses', async () => {
224
+ const message = createMessage('ping', {});
225
+ message.id = 'custom-id-123';
226
+ const response = await handler.handleMessage(message);
227
+ // pong doesn't preserve ID in current implementation
228
+ // but status and other git ops should
229
+ expect(response).toBeDefined();
230
+ });
231
+ });
232
+ });
233
+ //# sourceMappingURL=messageHandler.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messageHandler.test.js","sourceRoot":"","sources":["../../src/handlers/messageHandler.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ // @ts-ignore - no types for qrcode-terminal
4
+ import qrcode from 'qrcode-terminal';
5
+ import { resolve, basename } from 'path';
6
+ import { WebRTCConnection } from './connection/connection.js';
7
+ import { MessageHandler } from './handlers/messageHandler.js';
8
+ import { GitOperations } from './git/operations.js';
9
+ import { getOrCreateConfig, getConfigPath } from './config.js';
10
+ const DEFAULT_SIGNALING_SERVER = process.env.QUICKSAVE_SIGNALING_URL || 'wss://signal.quicksave.dev';
11
+ const program = new Command();
12
+ function collectRepos(value, previous) {
13
+ return previous.concat([value]);
14
+ }
15
+ program
16
+ .name('quicksave-agent')
17
+ .description('Quicksave desktop agent for remote git control')
18
+ .version('0.1.0')
19
+ .option('-r, --repo <path>', 'Path to git repository (can specify multiple)', collectRepos, [])
20
+ .option('-s, --signaling <url>', 'Signaling server URL', DEFAULT_SIGNALING_SERVER)
21
+ .option('--no-qr', 'Disable QR code display')
22
+ .action(async (options) => {
23
+ // Default to current directory if no repos specified
24
+ const repoPaths = options.repo.length > 0 ? options.repo : ['.'];
25
+ const resolvedPaths = repoPaths.map((p) => resolve(p));
26
+ const signalingServer = options.signaling;
27
+ console.log('Quicksave Agent v0.1.0');
28
+ console.log('='.repeat(50));
29
+ // Verify all git repositories
30
+ const validRepos = [];
31
+ for (const repoPath of resolvedPaths) {
32
+ const git = new GitOperations(repoPath);
33
+ const isValid = await git.isValidRepo();
34
+ if (!isValid) {
35
+ console.error(`Warning: ${repoPath} is not a valid git repository, skipping`);
36
+ continue;
37
+ }
38
+ const { current: currentBranch } = await git.getBranches();
39
+ validRepos.push({
40
+ path: repoPath,
41
+ name: basename(repoPath),
42
+ currentBranch,
43
+ });
44
+ }
45
+ if (validRepos.length === 0) {
46
+ console.error('Error: No valid git repositories found');
47
+ process.exit(1);
48
+ }
49
+ console.log(`Repositories (${validRepos.length}):`);
50
+ for (const repo of validRepos) {
51
+ console.log(` - ${repo.name} (${repo.path}) [${repo.currentBranch}]`);
52
+ }
53
+ // Load or create config
54
+ const config = getOrCreateConfig(signalingServer);
55
+ console.log(`Config: ${getConfigPath()}`);
56
+ console.log(`Signaling: ${signalingServer}`);
57
+ console.log('');
58
+ // Create connection
59
+ const connection = new WebRTCConnection({
60
+ signalingServer,
61
+ agentId: config.agentId,
62
+ keyPair: config.keyPair,
63
+ });
64
+ // Create message handler with all valid repos
65
+ const messageHandler = new MessageHandler(validRepos, config.license);
66
+ // Handle incoming messages
67
+ connection.on('message', async (message) => {
68
+ const response = await messageHandler.handleMessage(message);
69
+ connection.send(response);
70
+ });
71
+ connection.on('connected', () => {
72
+ console.log('\n✓ PWA connected! Ready for git operations.');
73
+ });
74
+ connection.on('disconnected', () => {
75
+ console.log('\n✗ PWA disconnected. Waiting for reconnection...');
76
+ displayConnectionInfo(config.agentId, config.keyPair.publicKey, options.qr);
77
+ });
78
+ connection.on('error', (error) => {
79
+ console.error('Connection error:', error.message);
80
+ });
81
+ // Start connection
82
+ try {
83
+ await connection.start();
84
+ displayConnectionInfo(config.agentId, config.keyPair.publicKey, options.qr);
85
+ }
86
+ catch (error) {
87
+ console.error('Failed to start agent:', error);
88
+ process.exit(1);
89
+ }
90
+ // Handle shutdown
91
+ process.on('SIGINT', () => {
92
+ console.log('\nShutting down...');
93
+ connection.disconnect();
94
+ process.exit(0);
95
+ });
96
+ process.on('SIGTERM', () => {
97
+ connection.disconnect();
98
+ process.exit(0);
99
+ });
100
+ });
101
+ function displayConnectionInfo(agentId, publicKey, showQr) {
102
+ console.log('');
103
+ console.log('='.repeat(50));
104
+ console.log('Connection Info');
105
+ console.log('='.repeat(50));
106
+ console.log('');
107
+ console.log('Agent ID:');
108
+ console.log(` ${agentId}`);
109
+ console.log('');
110
+ console.log('Public Key:');
111
+ console.log(` ${publicKey}`);
112
+ console.log('');
113
+ // Create connection URL for PWA
114
+ const connectionUrl = `https://quicksave.dev/connect?id=${agentId}&pk=${encodeURIComponent(publicKey)}`;
115
+ console.log('Connection URL:');
116
+ console.log(` ${connectionUrl}`);
117
+ console.log('');
118
+ if (showQr) {
119
+ console.log('Scan QR code to connect:');
120
+ console.log('');
121
+ qrcode.generate(connectionUrl, { small: true });
122
+ }
123
+ console.log('');
124
+ console.log('Waiting for PWA connection...');
125
+ }
126
+ program.parse();
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { EventEmitter } from 'events';
2
+ import { type Message } from '@sumicom/quicksave-shared';
3
+ export interface ConnectionConfig {
4
+ signalingServer: string;
5
+ agentId: string;
6
+ keyPair: {
7
+ publicKey: string;
8
+ secretKey: string;
9
+ };
10
+ iceServers?: Array<{
11
+ urls: string;
12
+ }>;
13
+ }
14
+ export interface WebRTCConnectionEvents {
15
+ connected: () => void;
16
+ disconnected: () => void;
17
+ message: (message: Message) => void;
18
+ error: (error: Error) => void;
19
+ }
20
+ export declare class WebRTCConnection extends EventEmitter {
21
+ private config;
22
+ private signaling;
23
+ private peerConnection;
24
+ private dataChannel;
25
+ private keyPair;
26
+ private peerPublicKey;
27
+ private sharedSecret;
28
+ private isConnected;
29
+ private relayMode;
30
+ constructor(config: ConnectionConfig);
31
+ private setupSignalingHandlers;
32
+ private enableRelayMode;
33
+ start(): Promise<void>;
34
+ private handleOffer;
35
+ private handleIceCandidate;
36
+ private setupDataChannel;
37
+ private handleDataChannelMessage;
38
+ send(message: Message): void;
39
+ private sendRaw;
40
+ private handlePeerDisconnected;
41
+ disconnect(): void;
42
+ getPublicKey(): string;
43
+ getAgentId(): string;
44
+ }
45
+ /**
46
+ * Generate and encode a new key pair for the agent
47
+ */
48
+ export declare function generateAgentKeyPair(): {
49
+ publicKey: string;
50
+ secretKey: string;
51
+ };
52
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/webrtc/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,OAAO,EAWL,KAAK,OAAO,EAEb,MAAM,mBAAmB,CAAC;AAM3B,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,WAAW,CAAmE;IACtF,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,gBAAgB;IAQpC,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,eAAe;IAkBjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAQd,WAAW;YAgDX,kBAAkB;IAMhC,OAAO,CAAC,gBAAgB;YAiBV,wBAAwB;IA+DtC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAyB5B,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,sBAAsB;IAoB9B,UAAU,IAAI,IAAI;IAOlB,YAAY,IAAI,MAAM;IAItB,UAAU,IAAI,MAAM;CAGrB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAE/E"}