@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.
- package/LICENSE +21 -0
- package/dist/ai/commitSummary.d.ts +26 -0
- package/dist/ai/commitSummary.d.ts.map +1 -0
- package/dist/ai/commitSummary.js +145 -0
- package/dist/ai/commitSummary.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +76 -0
- package/dist/config.js.map +1 -0
- package/dist/connection/connection.d.ts +54 -0
- package/dist/connection/connection.d.ts.map +1 -0
- package/dist/connection/connection.js +171 -0
- package/dist/connection/connection.js.map +1 -0
- package/dist/connection/signaling.d.ts +31 -0
- package/dist/connection/signaling.d.ts.map +1 -0
- package/dist/connection/signaling.js +144 -0
- package/dist/connection/signaling.js.map +1 -0
- package/dist/git/operations.d.ts +104 -0
- package/dist/git/operations.d.ts.map +1 -0
- package/dist/git/operations.js +383 -0
- package/dist/git/operations.js.map +1 -0
- package/dist/git/operations.test.d.ts +2 -0
- package/dist/git/operations.test.d.ts.map +1 -0
- package/dist/git/operations.test.js +232 -0
- package/dist/git/operations.test.js.map +1 -0
- package/dist/handlers/messageHandler.d.ts +33 -0
- package/dist/handlers/messageHandler.d.ts.map +1 -0
- package/dist/handlers/messageHandler.js +463 -0
- package/dist/handlers/messageHandler.js.map +1 -0
- package/dist/handlers/messageHandler.test.d.ts +2 -0
- package/dist/handlers/messageHandler.test.d.ts.map +1 -0
- package/dist/handlers/messageHandler.test.js +233 -0
- package/dist/handlers/messageHandler.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +127 -0
- package/dist/index.js.map +1 -0
- package/dist/webrtc/connection.d.ts +52 -0
- package/dist/webrtc/connection.d.ts.map +1 -0
- package/dist/webrtc/connection.js +255 -0
- package/dist/webrtc/connection.js.map +1 -0
- package/dist/webrtc/signaling.d.ts +41 -0
- package/dist/webrtc/signaling.d.ts.map +1 -0
- package/dist/webrtc/signaling.js +152 -0
- package/dist/webrtc/signaling.js.map +1 -0
- package/package.json +36 -0
- package/src/ai/commitSummary.ts +199 -0
- package/src/config.ts +97 -0
- package/src/connection/connection.ts +223 -0
- package/src/connection/signaling.ts +172 -0
- package/src/git/operations.test.ts +305 -0
- package/src/git/operations.ts +443 -0
- package/src/handlers/messageHandler.test.ts +294 -0
- package/src/handlers/messageHandler.ts +550 -0
- package/src/index.ts +151 -0
- package/src/types/webrtc.d.ts +38 -0
- package/tsconfig.json +13 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { gzip, gunzip } from 'zlib';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
const gzipAsync = promisify(gzip);
|
|
6
|
+
const gunzipAsync = promisify(gunzip);
|
|
7
|
+
export class SignalingClient extends EventEmitter {
|
|
8
|
+
ws = null;
|
|
9
|
+
url;
|
|
10
|
+
agentId;
|
|
11
|
+
reconnectAttempts = 0;
|
|
12
|
+
maxReconnectAttempts = 5;
|
|
13
|
+
reconnectDelay = 1000;
|
|
14
|
+
isConnected = false;
|
|
15
|
+
constructor(signalingServer, agentId) {
|
|
16
|
+
super();
|
|
17
|
+
this.url = `${signalingServer}/agent/${agentId}`;
|
|
18
|
+
this.agentId = agentId;
|
|
19
|
+
}
|
|
20
|
+
connect() {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
try {
|
|
23
|
+
this.ws = new WebSocket(this.url);
|
|
24
|
+
this.ws.on('open', () => {
|
|
25
|
+
this.isConnected = true;
|
|
26
|
+
this.reconnectAttempts = 0;
|
|
27
|
+
this.emit('connected');
|
|
28
|
+
resolve();
|
|
29
|
+
});
|
|
30
|
+
this.ws.on('message', async (data) => {
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(data.toString());
|
|
33
|
+
// Handle compressed signaling messages (z = zipped)
|
|
34
|
+
if (parsed.z) {
|
|
35
|
+
const message = JSON.parse(await this.decompress(parsed.z));
|
|
36
|
+
this.handleMessage(message);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Handle signaling messages (only specific types from signaling server)
|
|
40
|
+
const signalingTypes = ['peer-connected', 'peer-offline', 'data', 'bye', 'error'];
|
|
41
|
+
if (parsed.type && signalingTypes.includes(parsed.type)) {
|
|
42
|
+
this.handleMessage(parsed);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Other JSON messages (like key-exchange) are data messages
|
|
46
|
+
this.emit('data', data.toString());
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Not JSON, treat as raw data message
|
|
50
|
+
this.emit('data', data.toString());
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
this.ws.on('close', () => {
|
|
54
|
+
this.isConnected = false;
|
|
55
|
+
this.emit('disconnected');
|
|
56
|
+
this.attemptReconnect();
|
|
57
|
+
});
|
|
58
|
+
this.ws.on('error', (error) => {
|
|
59
|
+
this.emit('error', error);
|
|
60
|
+
if (!this.isConnected) {
|
|
61
|
+
reject(error);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
reject(error);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
handleMessage(message) {
|
|
71
|
+
switch (message.type) {
|
|
72
|
+
case 'peer-connected':
|
|
73
|
+
this.emit('peer-connected');
|
|
74
|
+
break;
|
|
75
|
+
case 'peer-offline':
|
|
76
|
+
this.emit('peer-disconnected');
|
|
77
|
+
break;
|
|
78
|
+
case 'data':
|
|
79
|
+
if (typeof message.payload === 'string') {
|
|
80
|
+
this.emit('data', message.payload);
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case 'bye':
|
|
84
|
+
this.emit('peer-disconnected');
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
sendBye() {
|
|
89
|
+
this.send({ type: 'bye' });
|
|
90
|
+
}
|
|
91
|
+
sendData(data) {
|
|
92
|
+
// Send raw data to peer through signaling server
|
|
93
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
94
|
+
this.ws.send(data);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Gzip compression helpers
|
|
98
|
+
async compress(data) {
|
|
99
|
+
const buffer = await gzipAsync(Buffer.from(data));
|
|
100
|
+
return buffer.toString('base64');
|
|
101
|
+
}
|
|
102
|
+
async decompress(base64) {
|
|
103
|
+
const buffer = Buffer.from(base64, 'base64');
|
|
104
|
+
const decompressed = await gunzipAsync(buffer);
|
|
105
|
+
return decompressed.toString('utf-8');
|
|
106
|
+
}
|
|
107
|
+
send(message) {
|
|
108
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
109
|
+
// Send compressed
|
|
110
|
+
this.compress(JSON.stringify(message)).then((compressed) => {
|
|
111
|
+
this.ws?.send(JSON.stringify({ z: compressed }));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
attemptReconnect() {
|
|
116
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
117
|
+
console.error('Max reconnect attempts reached');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.reconnectAttempts++;
|
|
121
|
+
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
|
122
|
+
console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
this.connect().catch((error) => {
|
|
125
|
+
console.error('Reconnect failed:', error);
|
|
126
|
+
});
|
|
127
|
+
}, delay);
|
|
128
|
+
}
|
|
129
|
+
disconnect() {
|
|
130
|
+
this.maxReconnectAttempts = 0; // Prevent reconnection
|
|
131
|
+
if (this.ws) {
|
|
132
|
+
this.sendBye();
|
|
133
|
+
this.ws.close();
|
|
134
|
+
this.ws = null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
getAgentId() {
|
|
138
|
+
return this.agentId;
|
|
139
|
+
}
|
|
140
|
+
getConnectionUrl() {
|
|
141
|
+
return this.url;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=signaling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signaling.js","sourceRoot":"","sources":["../../src/connection/signaling.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAGjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAClC,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAWtC,MAAM,OAAO,eAAgB,SAAQ,YAAY;IACvC,EAAE,GAAqB,IAAI,CAAC;IAC5B,GAAG,CAAS;IACZ,OAAO,CAAS;IAChB,iBAAiB,GAAG,CAAC,CAAC;IACtB,oBAAoB,GAAG,CAAC,CAAC;IACzB,cAAc,GAAG,IAAI,CAAC;IACtB,WAAW,GAAG,KAAK,CAAC;IAE5B,YAAY,eAAuB,EAAE,OAAe;QAClD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,GAAG,GAAG,eAAe,UAAU,OAAO,EAAE,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAElC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;oBACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;oBACxB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;oBAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACvB,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;oBACnC,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;wBAC3C,oDAAoD;wBACpD,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC;4BACb,MAAM,OAAO,GAAqB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC9E,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;4BAC5B,OAAO;wBACT,CAAC;wBACD,wEAAwE;wBACxE,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;wBAClF,IAAI,MAAM,CAAC,IAAI,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;4BACxD,IAAI,CAAC,aAAa,CAAC,MAA0B,CAAC,CAAC;4BAC/C,OAAO;wBACT,CAAC;wBACD,4DAA4D;wBAC5D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACrC,CAAC;oBAAC,MAAM,CAAC;wBACP,sCAAsC;wBACtC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACrC,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;oBACvB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;oBAC1B,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1B,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBAC1B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;wBACtB,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChB,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,OAAyB;QAC7C,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,gBAAgB;gBACnB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAC5B,MAAM;YACR,KAAK,cAAc;gBACjB,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC/B,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;gBACrC,CAAC;gBACD,MAAM;YACR,KAAK,KAAK;gBACR,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAC/B,MAAM;QACV,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,iDAAiD;QACjD,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACrD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,2BAA2B;IACnB,KAAK,CAAC,QAAQ,CAAC,IAAY;QACjC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,MAAc;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAEO,IAAI,CAAC,OAAyB;QACpC,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACrD,kBAAkB;YAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE;gBACzD,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC;QAE5E,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,eAAe,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAE9E,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC7B,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAED,UAAU;QACR,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC,uBAAuB;QACtD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { GitStatus, FileDiff, Commit, Branch } from '@sumicom/quicksave-shared';
|
|
2
|
+
export interface GitOperationsOptions {
|
|
3
|
+
maxDiffFileSizeKB?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class GitOperations {
|
|
6
|
+
private git;
|
|
7
|
+
private gitRoot;
|
|
8
|
+
private initialized;
|
|
9
|
+
private maxDiffFileSizeKB;
|
|
10
|
+
constructor(repoPath: string, options?: GitOperationsOptions);
|
|
11
|
+
/**
|
|
12
|
+
* Initialize git to run from the git root directory
|
|
13
|
+
* This ensures relative paths work correctly
|
|
14
|
+
*/
|
|
15
|
+
private ensureInitialized;
|
|
16
|
+
/**
|
|
17
|
+
* Get the actual git repository root path
|
|
18
|
+
*/
|
|
19
|
+
private getGitRoot;
|
|
20
|
+
/**
|
|
21
|
+
* Get the current git status
|
|
22
|
+
*/
|
|
23
|
+
getStatus(): Promise<GitStatus>;
|
|
24
|
+
/**
|
|
25
|
+
* Get diff for a specific file
|
|
26
|
+
*/
|
|
27
|
+
getDiff(path: string, staged?: boolean): Promise<FileDiff>;
|
|
28
|
+
/**
|
|
29
|
+
* Get file size in KB
|
|
30
|
+
*/
|
|
31
|
+
private getFileSizeKB;
|
|
32
|
+
/**
|
|
33
|
+
* Get diff for a staged new file by reading content from the git index
|
|
34
|
+
*/
|
|
35
|
+
private getStagedNewFileDiff;
|
|
36
|
+
/**
|
|
37
|
+
* Get diff representation for a new/untracked file (shows all content as additions)
|
|
38
|
+
*/
|
|
39
|
+
private getNewFileDiff;
|
|
40
|
+
/**
|
|
41
|
+
* Create a synthetic diff showing all content as additions
|
|
42
|
+
*/
|
|
43
|
+
private createSyntheticDiff;
|
|
44
|
+
/**
|
|
45
|
+
* Simple binary content detection
|
|
46
|
+
*/
|
|
47
|
+
private isBinaryContent;
|
|
48
|
+
/**
|
|
49
|
+
* Stage files
|
|
50
|
+
*/
|
|
51
|
+
stage(paths: string[]): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Unstage files
|
|
54
|
+
*/
|
|
55
|
+
unstage(paths: string[]): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Stage a patch (for line-level staging)
|
|
58
|
+
*/
|
|
59
|
+
stagePatch(patch: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Unstage a patch (for line-level unstaging)
|
|
62
|
+
*/
|
|
63
|
+
unstagePatch(patch: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Write a patch to a temporary file
|
|
66
|
+
*/
|
|
67
|
+
private writeTempPatch;
|
|
68
|
+
/**
|
|
69
|
+
* Clean up a temporary file
|
|
70
|
+
*/
|
|
71
|
+
private cleanupTempFile;
|
|
72
|
+
/**
|
|
73
|
+
* Create a commit
|
|
74
|
+
*/
|
|
75
|
+
commit(message: string, description?: string): Promise<string>;
|
|
76
|
+
/**
|
|
77
|
+
* Get commit history
|
|
78
|
+
*/
|
|
79
|
+
getLog(limit?: number): Promise<Commit[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Get all branches
|
|
82
|
+
*/
|
|
83
|
+
getBranches(): Promise<{
|
|
84
|
+
branches: Branch[];
|
|
85
|
+
current: string;
|
|
86
|
+
}>;
|
|
87
|
+
/**
|
|
88
|
+
* Checkout a branch
|
|
89
|
+
*/
|
|
90
|
+
checkout(branch: string, create?: boolean): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Discard changes in files
|
|
93
|
+
*/
|
|
94
|
+
discard(paths: string[]): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Check if path is a valid git repository
|
|
97
|
+
*/
|
|
98
|
+
isValidRepo(): Promise<boolean>;
|
|
99
|
+
private getBranchTracking;
|
|
100
|
+
private parseFileChanges;
|
|
101
|
+
private getFileStatus;
|
|
102
|
+
private parseDiff;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/git/operations.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,SAAS,EAET,QAAQ,EAER,MAAM,EACN,MAAM,EAEP,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB;IAO5D;;;OAGG;YACW,iBAAiB;IAQ/B;;OAEG;YACW,UAAU;IAQxB;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC;IAerC;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAkDvE;;OAEG;YACW,aAAa;IAW3B;;OAEG;YACW,oBAAoB;IAelC;;OAEG;YACW,cAAc;IAkB5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhD;;OAEG;YACW,cAAc;IAO5B;;OAEG;YACW,eAAe;IAQ7B;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMpE;;OAEG;IACG,MAAM,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAanD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAiBrE;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;YAavB,iBAAiB;IAY/B,OAAO,CAAC,gBAAgB;IA6BxB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,SAAS;CAsClB"}
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { simpleGit } from 'simple-git';
|
|
2
|
+
import { readFile, writeFile, unlink, stat } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { randomBytes } from 'crypto';
|
|
6
|
+
export class GitOperations {
|
|
7
|
+
git;
|
|
8
|
+
gitRoot = null;
|
|
9
|
+
initialized = false;
|
|
10
|
+
maxDiffFileSizeKB;
|
|
11
|
+
constructor(repoPath, options) {
|
|
12
|
+
this.git = simpleGit(repoPath);
|
|
13
|
+
this.maxDiffFileSizeKB =
|
|
14
|
+
options?.maxDiffFileSizeKB ??
|
|
15
|
+
parseInt(process.env.QUICKSAVE_MAX_DIFF_SIZE_KB || '100', 10);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initialize git to run from the git root directory
|
|
19
|
+
* This ensures relative paths work correctly
|
|
20
|
+
*/
|
|
21
|
+
async ensureInitialized() {
|
|
22
|
+
if (this.initialized)
|
|
23
|
+
return;
|
|
24
|
+
const gitRoot = await this.getGitRoot();
|
|
25
|
+
this.git = simpleGit(gitRoot);
|
|
26
|
+
this.initialized = true;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the actual git repository root path
|
|
30
|
+
*/
|
|
31
|
+
async getGitRoot() {
|
|
32
|
+
if (this.gitRoot) {
|
|
33
|
+
return this.gitRoot;
|
|
34
|
+
}
|
|
35
|
+
this.gitRoot = (await this.git.revparse(['--show-toplevel'])).trim();
|
|
36
|
+
return this.gitRoot;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the current git status
|
|
40
|
+
*/
|
|
41
|
+
async getStatus() {
|
|
42
|
+
await this.ensureInitialized();
|
|
43
|
+
const status = await this.git.status();
|
|
44
|
+
const branchInfo = await this.getBranchTracking();
|
|
45
|
+
return {
|
|
46
|
+
branch: status.current || 'HEAD',
|
|
47
|
+
ahead: branchInfo.ahead,
|
|
48
|
+
behind: branchInfo.behind,
|
|
49
|
+
staged: this.parseFileChanges(status, 'staged'),
|
|
50
|
+
unstaged: this.parseFileChanges(status, 'unstaged'),
|
|
51
|
+
untracked: status.not_added,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get diff for a specific file
|
|
56
|
+
*/
|
|
57
|
+
async getDiff(path, staged = false) {
|
|
58
|
+
await this.ensureInitialized();
|
|
59
|
+
// Check file size before generating diff
|
|
60
|
+
const fileSizeKB = await this.getFileSizeKB(path);
|
|
61
|
+
if (fileSizeKB > this.maxDiffFileSizeKB) {
|
|
62
|
+
return {
|
|
63
|
+
path,
|
|
64
|
+
hunks: [],
|
|
65
|
+
isBinary: false,
|
|
66
|
+
truncated: true,
|
|
67
|
+
truncatedReason: `File exceeds ${this.maxDiffFileSizeKB}KB limit (${fileSizeKB}KB)`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const status = await this.git.status();
|
|
71
|
+
const isUntracked = status.not_added.includes(path);
|
|
72
|
+
const isNewFile = status.created.includes(path);
|
|
73
|
+
console.log(`getDiff: path="${path}", isUntracked=${isUntracked}, isNewFile=${isNewFile}`);
|
|
74
|
+
console.log(`getDiff: not_added=[${status.not_added.join(', ')}]`);
|
|
75
|
+
// For untracked files, show the full content as additions
|
|
76
|
+
if (isUntracked) {
|
|
77
|
+
return this.getNewFileDiff(path);
|
|
78
|
+
}
|
|
79
|
+
// For new staged files, show the staged content from the index
|
|
80
|
+
if (staged && isNewFile) {
|
|
81
|
+
return this.getStagedNewFileDiff(path);
|
|
82
|
+
}
|
|
83
|
+
// Normal diff
|
|
84
|
+
const args = staged
|
|
85
|
+
? ['diff', '--cached', '--', path]
|
|
86
|
+
: ['diff', '--', path];
|
|
87
|
+
const diffOutput = await this.git.raw(args);
|
|
88
|
+
// If diff is empty, return empty diff
|
|
89
|
+
if (!diffOutput.trim()) {
|
|
90
|
+
return {
|
|
91
|
+
path,
|
|
92
|
+
hunks: [],
|
|
93
|
+
isBinary: false,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return this.parseDiff(path, diffOutput);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get file size in KB
|
|
100
|
+
*/
|
|
101
|
+
async getFileSizeKB(path) {
|
|
102
|
+
try {
|
|
103
|
+
const gitRoot = await this.getGitRoot();
|
|
104
|
+
const fullPath = join(gitRoot, path);
|
|
105
|
+
const stats = await stat(fullPath);
|
|
106
|
+
return Math.ceil(stats.size / 1024);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return 0; // File doesn't exist or can't be read
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get diff for a staged new file by reading content from the git index
|
|
114
|
+
*/
|
|
115
|
+
async getStagedNewFileDiff(path) {
|
|
116
|
+
try {
|
|
117
|
+
const content = await this.git.raw(['show', `:${path}`]);
|
|
118
|
+
if (this.isBinaryContent(content)) {
|
|
119
|
+
return { path, hunks: [], isBinary: true };
|
|
120
|
+
}
|
|
121
|
+
return this.createSyntheticDiff(path, content);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Fallback to reading from working tree
|
|
125
|
+
return this.getNewFileDiff(path);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get diff representation for a new/untracked file (shows all content as additions)
|
|
130
|
+
*/
|
|
131
|
+
async getNewFileDiff(path) {
|
|
132
|
+
const gitRoot = await this.getGitRoot();
|
|
133
|
+
const fullPath = join(gitRoot, path);
|
|
134
|
+
try {
|
|
135
|
+
const content = await readFile(fullPath, 'utf-8');
|
|
136
|
+
if (this.isBinaryContent(content)) {
|
|
137
|
+
return { path, hunks: [], isBinary: true };
|
|
138
|
+
}
|
|
139
|
+
return this.createSyntheticDiff(path, content);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.error(`Failed to read untracked file ${fullPath}:`, error);
|
|
143
|
+
return { path, hunks: [], isBinary: false };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Create a synthetic diff showing all content as additions
|
|
148
|
+
*/
|
|
149
|
+
createSyntheticDiff(path, content) {
|
|
150
|
+
const lines = content.split(/\r?\n/);
|
|
151
|
+
// Remove trailing empty line if content ends with newline
|
|
152
|
+
if (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
153
|
+
lines.pop();
|
|
154
|
+
}
|
|
155
|
+
if (lines.length === 0) {
|
|
156
|
+
return { path, hunks: [], isBinary: false };
|
|
157
|
+
}
|
|
158
|
+
const hunkContent = lines.map(line => `+${line}`).join('\n');
|
|
159
|
+
const hunk = {
|
|
160
|
+
oldStart: 0,
|
|
161
|
+
oldLines: 0,
|
|
162
|
+
newStart: 1,
|
|
163
|
+
newLines: lines.length,
|
|
164
|
+
content: `@@ -0,0 +1,${lines.length} @@\n${hunkContent}`,
|
|
165
|
+
};
|
|
166
|
+
return { path, hunks: [hunk], isBinary: false };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Simple binary content detection
|
|
170
|
+
*/
|
|
171
|
+
isBinaryContent(content) {
|
|
172
|
+
return content.includes('\0');
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Stage files
|
|
176
|
+
*/
|
|
177
|
+
async stage(paths) {
|
|
178
|
+
await this.ensureInitialized();
|
|
179
|
+
await this.git.add(paths);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Unstage files
|
|
183
|
+
*/
|
|
184
|
+
async unstage(paths) {
|
|
185
|
+
await this.ensureInitialized();
|
|
186
|
+
await this.git.reset(['HEAD', '--', ...paths]);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Stage a patch (for line-level staging)
|
|
190
|
+
*/
|
|
191
|
+
async stagePatch(patch) {
|
|
192
|
+
await this.ensureInitialized();
|
|
193
|
+
const tempFile = await this.writeTempPatch(patch);
|
|
194
|
+
try {
|
|
195
|
+
await this.git.raw(['apply', '--cached', tempFile]);
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
await this.cleanupTempFile(tempFile);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Unstage a patch (for line-level unstaging)
|
|
203
|
+
*/
|
|
204
|
+
async unstagePatch(patch) {
|
|
205
|
+
await this.ensureInitialized();
|
|
206
|
+
const tempFile = await this.writeTempPatch(patch);
|
|
207
|
+
try {
|
|
208
|
+
await this.git.raw(['apply', '--cached', '-R', tempFile]);
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
await this.cleanupTempFile(tempFile);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Write a patch to a temporary file
|
|
216
|
+
*/
|
|
217
|
+
async writeTempPatch(patch) {
|
|
218
|
+
const id = randomBytes(8).toString('hex');
|
|
219
|
+
const tempPath = join(tmpdir(), `quicksave-patch-${id}.patch`);
|
|
220
|
+
await writeFile(tempPath, patch, 'utf-8');
|
|
221
|
+
return tempPath;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Clean up a temporary file
|
|
225
|
+
*/
|
|
226
|
+
async cleanupTempFile(path) {
|
|
227
|
+
try {
|
|
228
|
+
await unlink(path);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// Ignore cleanup errors
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Create a commit
|
|
236
|
+
*/
|
|
237
|
+
async commit(message, description) {
|
|
238
|
+
const fullMessage = description ? `${message}\n\n${description}` : message;
|
|
239
|
+
const result = await this.git.commit(fullMessage);
|
|
240
|
+
return result.commit;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get commit history
|
|
244
|
+
*/
|
|
245
|
+
async getLog(limit = 50) {
|
|
246
|
+
const log = await this.git.log({ maxCount: limit });
|
|
247
|
+
return log.all.map((entry) => ({
|
|
248
|
+
hash: entry.hash,
|
|
249
|
+
shortHash: entry.hash.slice(0, 7),
|
|
250
|
+
message: entry.message,
|
|
251
|
+
author: entry.author_name,
|
|
252
|
+
email: entry.author_email,
|
|
253
|
+
date: entry.date,
|
|
254
|
+
}));
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get all branches
|
|
258
|
+
*/
|
|
259
|
+
async getBranches() {
|
|
260
|
+
const branchSummary = await this.git.branch(['-a']);
|
|
261
|
+
const branches = Object.entries(branchSummary.branches).map(([name, info]) => ({
|
|
262
|
+
name: info.name,
|
|
263
|
+
current: info.current,
|
|
264
|
+
remote: name.startsWith('remotes/') ? name.split('/')[1] : undefined,
|
|
265
|
+
}));
|
|
266
|
+
return {
|
|
267
|
+
branches,
|
|
268
|
+
current: branchSummary.current,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Checkout a branch
|
|
273
|
+
*/
|
|
274
|
+
async checkout(branch, create = false) {
|
|
275
|
+
if (create) {
|
|
276
|
+
await this.git.checkoutLocalBranch(branch);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
await this.git.checkout(branch);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Discard changes in files
|
|
284
|
+
*/
|
|
285
|
+
async discard(paths) {
|
|
286
|
+
await this.ensureInitialized();
|
|
287
|
+
await this.git.checkout(['--', ...paths]);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Check if path is a valid git repository
|
|
291
|
+
*/
|
|
292
|
+
async isValidRepo() {
|
|
293
|
+
try {
|
|
294
|
+
await this.git.status();
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// ============================================================================
|
|
302
|
+
// Private Helpers
|
|
303
|
+
// ============================================================================
|
|
304
|
+
async getBranchTracking() {
|
|
305
|
+
try {
|
|
306
|
+
const status = await this.git.status();
|
|
307
|
+
return {
|
|
308
|
+
ahead: status.ahead,
|
|
309
|
+
behind: status.behind,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
return { ahead: 0, behind: 0 };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
parseFileChanges(status, type) {
|
|
317
|
+
const changes = [];
|
|
318
|
+
if (type === 'staged') {
|
|
319
|
+
for (const file of status.staged) {
|
|
320
|
+
changes.push({
|
|
321
|
+
path: file,
|
|
322
|
+
status: this.getFileStatus(status, file),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
// Use files array for accurate unstaged detection
|
|
328
|
+
// working_dir indicates the status in the working directory (unstaged changes)
|
|
329
|
+
for (const file of status.files) {
|
|
330
|
+
const wd = file.working_dir;
|
|
331
|
+
if (wd === 'M') {
|
|
332
|
+
changes.push({ path: file.path, status: 'modified' });
|
|
333
|
+
}
|
|
334
|
+
else if (wd === 'D') {
|
|
335
|
+
changes.push({ path: file.path, status: 'deleted' });
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return changes;
|
|
340
|
+
}
|
|
341
|
+
getFileStatus(status, file) {
|
|
342
|
+
if (status.created.includes(file))
|
|
343
|
+
return 'added';
|
|
344
|
+
if (status.deleted.includes(file))
|
|
345
|
+
return 'deleted';
|
|
346
|
+
if (status.renamed.some((r) => r.to === file))
|
|
347
|
+
return 'renamed';
|
|
348
|
+
return 'modified';
|
|
349
|
+
}
|
|
350
|
+
parseDiff(path, diffOutput) {
|
|
351
|
+
const hunks = [];
|
|
352
|
+
const lines = diffOutput.split(/\r?\n/);
|
|
353
|
+
let currentHunk = null;
|
|
354
|
+
let hunkContent = [];
|
|
355
|
+
for (const line of lines) {
|
|
356
|
+
const hunkMatch = line.match(/^@@\s*-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s*@@/);
|
|
357
|
+
if (hunkMatch) {
|
|
358
|
+
if (currentHunk) {
|
|
359
|
+
currentHunk.content = hunkContent.join('\n');
|
|
360
|
+
hunks.push(currentHunk);
|
|
361
|
+
}
|
|
362
|
+
currentHunk = {
|
|
363
|
+
oldStart: parseInt(hunkMatch[1], 10),
|
|
364
|
+
oldLines: parseInt(hunkMatch[2] || '1', 10),
|
|
365
|
+
newStart: parseInt(hunkMatch[3], 10),
|
|
366
|
+
newLines: parseInt(hunkMatch[4] || '1', 10),
|
|
367
|
+
content: '',
|
|
368
|
+
};
|
|
369
|
+
hunkContent = [line];
|
|
370
|
+
}
|
|
371
|
+
else if (currentHunk && (line.startsWith('+') || line.startsWith('-') || line.startsWith(' '))) {
|
|
372
|
+
hunkContent.push(line);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (currentHunk) {
|
|
376
|
+
currentHunk.content = hunkContent.join('\n');
|
|
377
|
+
hunks.push(currentHunk);
|
|
378
|
+
}
|
|
379
|
+
const isBinary = diffOutput.includes('Binary files') || diffOutput.includes('GIT binary patch');
|
|
380
|
+
return { path, hunks, isBinary };
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/git/operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA2B,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAerC,MAAM,OAAO,aAAa;IAChB,GAAG,CAAY;IACf,OAAO,GAAkB,IAAI,CAAC;IAC9B,WAAW,GAAG,KAAK,CAAC;IACpB,iBAAiB,CAAS;IAElC,YAAY,QAAgB,EAAE,OAA8B;QAC1D,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC/B,IAAI,CAAC,iBAAiB;YACpB,OAAO,EAAE,iBAAiB;gBAC1B,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,iBAAiB;QAC7B,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU;QACtB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAElD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,OAAO,IAAI,MAAM;YAChC,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC;YAC/C,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC;YACnD,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,SAAkB,KAAK;QACjD,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE/B,yCAAyC;QACzC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACxC,OAAO;gBACL,IAAI;gBACJ,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,KAAK;gBACf,SAAS,EAAE,IAAI;gBACf,eAAe,EAAE,gBAAgB,IAAI,CAAC,iBAAiB,aAAa,UAAU,KAAK;aACpF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEhD,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,kBAAkB,WAAW,eAAe,SAAS,EAAE,CAAC,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnE,0DAA0D;QAC1D,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,+DAA+D;QAC/D,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,cAAc;QACd,MAAM,IAAI,GAAG,MAAM;YACjB,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC;YAClC,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACzB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE5C,sCAAsC;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,OAAO;gBACL,IAAI;gBACJ,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,KAAK;aAChB,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,IAAY;QACtC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,CAAC,sCAAsC;QAClD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAAC,IAAY;QAC7C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAEzD,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC7C,CAAC;YAED,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,wCAAwC;YACxC,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,IAAY;QACvC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAErC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC7C,CAAC;YAED,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,IAAY,EAAE,OAAe;QACvD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAErC,0DAA0D;QAC1D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACvD,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC9C,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAa;YACrB,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,CAAC;YACX,QAAQ,EAAE,KAAK,CAAC,MAAM;YACtB,OAAO,EAAE,cAAc,KAAK,CAAC,MAAM,QAAQ,WAAW,EAAE;SACzD,CAAC;QAEF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAAe;QACrC,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,KAAe;QACzB,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,KAAe;QAC3B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;QACtD,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,KAAa;QAC9B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5D,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,KAAa;QACxC,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;QAC/D,MAAM,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAAC,IAAY;QACxC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,WAAoB;QAChD,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAEpD,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YACjC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,WAAW;YACzB,KAAK,EAAE,KAAK,CAAC,YAAY;YACzB,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAa,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,GAAG,CACnE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;SACrE,CAAC,CACH,CAAC;QAEF,OAAO;YACL,QAAQ;YACR,OAAO,EAAE,aAAa,CAAC,OAAO;SAC/B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,SAAkB,KAAK;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,KAAe;QAC3B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,kBAAkB;IAClB,+EAA+E;IAEvE,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACvC,OAAO;gBACL,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAEO,gBAAgB,CACtB,MAAoB,EACpB,IAA2B;QAE3B,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC;iBACzC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kDAAkD;YAClD,+EAA+E;YAC/E,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAChC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;gBAC5B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;gBACxD,CAAC;qBAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,aAAa,CAAC,MAAoB,EAAE,IAAY;QACtD,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC;QAClD,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QACpD,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QAChE,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,SAAS,CAAC,IAAY,EAAE,UAAkB;QAChD,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAExC,IAAI,WAAW,GAAoB,IAAI,CAAC;QACxC,IAAI,WAAW,GAAa,EAAE,CAAC;QAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;YAElF,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC7C,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC1B,CAAC;gBAED,WAAW,GAAG;oBACZ,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACpC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;oBAC3C,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACpC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;oBAC3C,OAAO,EAAE,EAAE;iBACZ,CAAC;gBACF,WAAW,GAAG,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;iBAAM,IAAI,WAAW,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACjG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAEhG,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.test.d.ts","sourceRoot":"","sources":["../../src/git/operations.test.ts"],"names":[],"mappings":""}
|