pushwork 1.0.4 → 1.0.5

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 (67) hide show
  1. package/README.md +8 -1
  2. package/bench/filesystem.bench.ts +78 -0
  3. package/bench/hashing.bench.ts +60 -0
  4. package/bench/move-detection.bench.ts +130 -0
  5. package/bench/runner.ts +49 -0
  6. package/dist/cli/commands.d.ts +15 -25
  7. package/dist/cli/commands.d.ts.map +1 -1
  8. package/dist/cli/commands.js +409 -519
  9. package/dist/cli/commands.js.map +1 -1
  10. package/dist/cli/output.d.ts +75 -0
  11. package/dist/cli/output.d.ts.map +1 -0
  12. package/dist/cli/output.js +182 -0
  13. package/dist/cli/output.js.map +1 -0
  14. package/dist/cli.js +116 -50
  15. package/dist/cli.js.map +1 -1
  16. package/dist/config/remote-manager.d.ts +65 -0
  17. package/dist/config/remote-manager.d.ts.map +1 -0
  18. package/dist/config/remote-manager.js +243 -0
  19. package/dist/config/remote-manager.js.map +1 -0
  20. package/dist/core/change-detection.d.ts +8 -0
  21. package/dist/core/change-detection.d.ts.map +1 -1
  22. package/dist/core/change-detection.js +63 -0
  23. package/dist/core/change-detection.js.map +1 -1
  24. package/dist/core/move-detection.d.ts +9 -48
  25. package/dist/core/move-detection.d.ts.map +1 -1
  26. package/dist/core/move-detection.js +53 -135
  27. package/dist/core/move-detection.js.map +1 -1
  28. package/dist/core/sync-engine.d.ts.map +1 -1
  29. package/dist/core/sync-engine.js +17 -62
  30. package/dist/core/sync-engine.js.map +1 -1
  31. package/dist/types/config.d.ts +45 -5
  32. package/dist/types/config.d.ts.map +1 -1
  33. package/dist/types/documents.d.ts +0 -1
  34. package/dist/types/documents.d.ts.map +1 -1
  35. package/dist/types/snapshot.d.ts +3 -0
  36. package/dist/types/snapshot.d.ts.map +1 -1
  37. package/dist/types/snapshot.js.map +1 -1
  38. package/dist/utils/fs.d.ts.map +1 -1
  39. package/dist/utils/fs.js +9 -33
  40. package/dist/utils/fs.js.map +1 -1
  41. package/dist/utils/index.d.ts +0 -1
  42. package/dist/utils/index.d.ts.map +1 -1
  43. package/dist/utils/index.js +0 -1
  44. package/dist/utils/index.js.map +1 -1
  45. package/dist/utils/repo-factory.d.ts.map +1 -1
  46. package/dist/utils/repo-factory.js +18 -9
  47. package/dist/utils/repo-factory.js.map +1 -1
  48. package/dist/utils/string-similarity.d.ts +14 -0
  49. package/dist/utils/string-similarity.d.ts.map +1 -0
  50. package/dist/utils/string-similarity.js +43 -0
  51. package/dist/utils/string-similarity.js.map +1 -0
  52. package/package.json +10 -5
  53. package/src/cli/commands.ts +520 -697
  54. package/src/cli/output.ts +244 -0
  55. package/src/cli.ts +178 -72
  56. package/src/core/change-detection.ts +95 -0
  57. package/src/core/move-detection.ts +69 -177
  58. package/src/core/sync-engine.ts +17 -78
  59. package/src/types/config.ts +50 -7
  60. package/src/types/documents.ts +0 -1
  61. package/src/types/snapshot.ts +1 -0
  62. package/src/utils/fs.ts +9 -33
  63. package/src/utils/index.ts +0 -1
  64. package/src/utils/repo-factory.ts +21 -8
  65. package/src/utils/string-similarity.ts +54 -0
  66. package/src/utils/content-similarity.ts +0 -194
  67. package/test/unit/content-similarity.test.ts +0 -236
package/README.md CHANGED
@@ -29,7 +29,14 @@ pnpm run build
29
29
  pnpm link --global
30
30
  ```
31
31
 
32
- Note: you can also run this from NPX, I think.
32
+ Make sure that pnpm is in your PATH. E.g. in your .zshrc or .bashrc, add:
33
+
34
+ ```bash
35
+ export PNPM_HOME="/Users/username/Library/pnpm" # wherever you have pnpm installed
36
+ export PATH="$PATH:$PNPM_HOME"
37
+ ```
38
+
39
+ Note: you can also run this from NPX.
33
40
 
34
41
  ### Basic Usage
35
42
 
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Benchmarks for file system operations
3
+ * These are critical for sync performance
4
+ */
5
+
6
+ import { Bench } from "tinybench";
7
+ import { tmpdir } from "os";
8
+ import { join } from "path";
9
+ import { mkdirSync, writeFileSync, rmSync, existsSync } from "fs";
10
+ import {
11
+ readFileContent,
12
+ pathExists,
13
+ listDirectory,
14
+ isTextFile,
15
+ } from "../src/utils/fs";
16
+
17
+ const bench = new Bench({ time: 1000 });
18
+
19
+ // Setup test directory
20
+ const testDir = join(tmpdir(), "pushwork-bench-fs-" + Date.now());
21
+ mkdirSync(testDir, { recursive: true });
22
+
23
+ // Create test files of realistic sizes
24
+ const smallFile = join(testDir, "small.txt");
25
+ const mediumFile = join(testDir, "medium.ts");
26
+ const largeFile = join(testDir, "large.json");
27
+ const binaryFile = join(testDir, "image.bin");
28
+
29
+ writeFileSync(smallFile, "Hello, World!"); // 13 bytes
30
+ writeFileSync(
31
+ mediumFile,
32
+ "export const data = " + JSON.stringify({ data: "a".repeat(5000) })
33
+ ); // ~5KB
34
+ writeFileSync(largeFile, JSON.stringify({ data: "a".repeat(50000) })); // ~50KB
35
+ writeFileSync(binaryFile, Buffer.alloc(10240)); // 10KB binary
36
+
37
+ // Create nested directory structure
38
+ const nestedDir = join(testDir, "nested");
39
+ mkdirSync(join(nestedDir, "a", "b", "c"), { recursive: true });
40
+ for (let i = 0; i < 20; i++) {
41
+ writeFileSync(join(nestedDir, `file${i}.txt`), `content ${i}`.repeat(100));
42
+ writeFileSync(
43
+ join(nestedDir, "a", `file${i}.txt`),
44
+ `content ${i}`.repeat(100)
45
+ );
46
+ }
47
+
48
+ // Realistic filesystem operations
49
+ bench
50
+ .add("read small file (13 bytes)", async () => {
51
+ await readFileContent(smallFile);
52
+ })
53
+ .add("read medium file (5KB)", async () => {
54
+ await readFileContent(mediumFile);
55
+ })
56
+ .add("read large file (50KB)", async () => {
57
+ await readFileContent(largeFile);
58
+ })
59
+ .add("detect text vs binary (text)", async () => {
60
+ await isTextFile(smallFile);
61
+ })
62
+ .add("detect text vs binary (binary)", async () => {
63
+ await isTextFile(binaryFile);
64
+ })
65
+ .add("list directory recursive (40 files)", async () => {
66
+ await listDirectory(nestedDir, true);
67
+ });
68
+
69
+ export default (async () => {
70
+ await bench.warmup();
71
+ await bench.run();
72
+ console.table(bench.table());
73
+
74
+ // Cleanup
75
+ if (existsSync(testDir)) {
76
+ rmSync(testDir, { recursive: true, force: true });
77
+ }
78
+ })();
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Benchmarks for content hashing
3
+ * Used in change detection and move detection
4
+ */
5
+
6
+ import { Bench } from "tinybench";
7
+ import { calculateContentHash } from "../src/utils/fs";
8
+
9
+ const bench = new Bench({ time: 1000 });
10
+
11
+ // Generate test data of various sizes
12
+ const tiny = "Hello, World!";
13
+ const small = "a".repeat(1024); // 1KB
14
+ const medium = "a".repeat(10240); // 10KB
15
+ const large = "a".repeat(102400); // 100KB
16
+ const huge = "a".repeat(1024000); // 1MB
17
+
18
+ // String content
19
+ bench
20
+ .add("hash tiny string (13 bytes)", async () => {
21
+ await calculateContentHash(tiny);
22
+ })
23
+ .add("hash small string (1KB)", async () => {
24
+ await calculateContentHash(small);
25
+ })
26
+ .add("hash medium string (10KB)", async () => {
27
+ await calculateContentHash(medium);
28
+ })
29
+ .add("hash large string (100KB)", async () => {
30
+ await calculateContentHash(large);
31
+ })
32
+ .add("hash huge string (1MB)", async () => {
33
+ await calculateContentHash(huge);
34
+ });
35
+
36
+ // Binary content
37
+ const tinyBinary = new Uint8Array(13);
38
+ const smallBinary = new Uint8Array(1024);
39
+ const mediumBinary = new Uint8Array(10240);
40
+ const largeBinary = new Uint8Array(102400);
41
+
42
+ bench
43
+ .add("hash tiny binary (13 bytes)", async () => {
44
+ await calculateContentHash(tinyBinary);
45
+ })
46
+ .add("hash small binary (1KB)", async () => {
47
+ await calculateContentHash(smallBinary);
48
+ })
49
+ .add("hash medium binary (10KB)", async () => {
50
+ await calculateContentHash(mediumBinary);
51
+ })
52
+ .add("hash large binary (100KB)", async () => {
53
+ await calculateContentHash(largeBinary);
54
+ });
55
+
56
+ export default (async () => {
57
+ await bench.warmup();
58
+ await bench.run();
59
+ console.table(bench.table());
60
+ })();
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Benchmarks for move detection algorithm
3
+ * This is expensive because it combines similarity checking with pattern matching
4
+ */
5
+
6
+ import { Bench } from "tinybench";
7
+ import { MoveDetector } from "../src/core/move-detection";
8
+ import { DetectedChange, ChangeType } from "../src/core/change-detection";
9
+ import { FileType } from "../src/types";
10
+
11
+ const bench = new Bench({ time: 1000 });
12
+
13
+ const detector = new MoveDetector();
14
+
15
+ // Create mock snapshot
16
+ const mockSnapshot: any = {
17
+ timestamp: Date.now(),
18
+ rootPath: "/test",
19
+ files: new Map([
20
+ ["old1.txt", { url: "url1" as any, head: [], path: "/test/old1.txt" }],
21
+ ["old2.txt", { url: "url2" as any, head: [], path: "/test/old2.txt" }],
22
+ ]),
23
+ directories: new Map(),
24
+ };
25
+
26
+ // Realistic file content sizes
27
+ const smallContent = "const x = 1;".repeat(10); // ~120 bytes
28
+ const mediumContent = "export const data = { value: true };".repeat(30); // ~1KB
29
+ const largeContent = "// Comment\nfunction foo() { return 42; }\n".repeat(250); // ~10KB
30
+
31
+ // Scenario 1: Small file move (config files)
32
+ const smallFileMove: DetectedChange[] = [
33
+ {
34
+ path: "old1.txt",
35
+ changeType: ChangeType.LOCAL_ONLY,
36
+ fileType: FileType.TEXT,
37
+ localContent: null,
38
+ remoteContent: smallContent,
39
+ },
40
+ {
41
+ path: "new1.txt",
42
+ changeType: ChangeType.LOCAL_ONLY,
43
+ fileType: FileType.TEXT,
44
+ localContent: smallContent + " // modified",
45
+ remoteContent: null,
46
+ },
47
+ ];
48
+
49
+ // Scenario 2: Medium file move (source files)
50
+ const mediumFileMove: DetectedChange[] = [
51
+ {
52
+ path: "old2.txt",
53
+ changeType: ChangeType.LOCAL_ONLY,
54
+ fileType: FileType.TEXT,
55
+ localContent: null,
56
+ remoteContent: mediumContent,
57
+ },
58
+ {
59
+ path: "new2.txt",
60
+ changeType: ChangeType.LOCAL_ONLY,
61
+ fileType: FileType.TEXT,
62
+ localContent: mediumContent.slice(0, -50) + "modified".repeat(10),
63
+ remoteContent: null,
64
+ },
65
+ ];
66
+
67
+ // Scenario 3: Multiple candidates (ambiguous moves)
68
+ const multipleCandidates: DetectedChange[] = [
69
+ // 3 deleted files
70
+ {
71
+ path: "deleted1.txt",
72
+ changeType: ChangeType.LOCAL_ONLY,
73
+ fileType: FileType.TEXT,
74
+ localContent: null,
75
+ remoteContent: smallContent,
76
+ },
77
+ {
78
+ path: "deleted2.txt",
79
+ changeType: ChangeType.LOCAL_ONLY,
80
+ fileType: FileType.TEXT,
81
+ localContent: null,
82
+ remoteContent: mediumContent,
83
+ },
84
+ {
85
+ path: "deleted3.txt",
86
+ changeType: ChangeType.LOCAL_ONLY,
87
+ fileType: FileType.TEXT,
88
+ localContent: null,
89
+ remoteContent: largeContent,
90
+ },
91
+ // 3 created files (need to find best matches)
92
+ {
93
+ path: "created1.txt",
94
+ changeType: ChangeType.LOCAL_ONLY,
95
+ fileType: FileType.TEXT,
96
+ localContent: smallContent + "!",
97
+ remoteContent: null,
98
+ },
99
+ {
100
+ path: "created2.txt",
101
+ changeType: ChangeType.LOCAL_ONLY,
102
+ fileType: FileType.TEXT,
103
+ localContent: mediumContent + "?",
104
+ remoteContent: null,
105
+ },
106
+ {
107
+ path: "created3.txt",
108
+ changeType: ChangeType.LOCAL_ONLY,
109
+ fileType: FileType.TEXT,
110
+ localContent: largeContent.slice(0, -100),
111
+ remoteContent: null,
112
+ },
113
+ ];
114
+
115
+ bench
116
+ .add("detect move: 2 small files (~120 bytes)", async () => {
117
+ await detector.detectMoves(smallFileMove, mockSnapshot, "/test");
118
+ })
119
+ .add("detect move: 2 medium files (~1KB)", async () => {
120
+ await detector.detectMoves(mediumFileMove, mockSnapshot, "/test");
121
+ })
122
+ .add("detect move: 6 files, 3 candidates each", async () => {
123
+ await detector.detectMoves(multipleCandidates, mockSnapshot, "/test");
124
+ });
125
+
126
+ export default (async () => {
127
+ await bench.warmup();
128
+ await bench.run();
129
+ console.table(bench.table());
130
+ })();
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Benchmark runner for Pushwork performance tests
4
+ *
5
+ * Run with: pnpm bench
6
+ */
7
+
8
+ import { readdirSync } from 'fs';
9
+ import { join } from 'path';
10
+
11
+ async function main() {
12
+ console.log('🏃 Running Pushwork Performance Benchmarks\n');
13
+ console.log('=' .repeat(80));
14
+ console.log();
15
+
16
+ const benchDir = __dirname;
17
+ const benchFiles = readdirSync(benchDir)
18
+ .filter(f => f.endsWith('.bench.ts'))
19
+ .sort();
20
+
21
+ if (benchFiles.length === 0) {
22
+ console.log('No benchmark files found');
23
+ return;
24
+ }
25
+
26
+ for (const file of benchFiles) {
27
+ const benchPath = join(benchDir, file);
28
+ console.log(`📊 ${file.replace('.bench.ts', '')}`);
29
+ console.log('-'.repeat(80));
30
+
31
+ try {
32
+ const module = await import(benchPath);
33
+ // Wait for the default export promise to complete
34
+ if (module.default) {
35
+ await module.default;
36
+ }
37
+ console.log();
38
+ } catch (error) {
39
+ console.error(`❌ Failed to run ${file}:`, error);
40
+ console.log();
41
+ }
42
+ }
43
+
44
+ console.log('=' .repeat(80));
45
+ console.log('✅ All benchmarks completed\n');
46
+ }
47
+
48
+ main().catch(console.error);
49
+
@@ -1,5 +1,5 @@
1
1
  import { Repo } from "@automerge/automerge-repo";
2
- import { CloneOptions, SyncOptions, DiffOptions, LogOptions, CheckoutOptions, DirectoryConfig } from "../types";
2
+ import { CloneOptions, SyncOptions, DiffOptions, LogOptions, CheckoutOptions, InitOptions, CommitOptions, StatusOptions, UrlOptions, ListOptions, ConfigOptions, DebugOptions, DirectoryConfig } from "../types";
3
3
  import { SyncEngine } from "../core";
4
4
  /**
5
5
  * Shared context that commands can use
@@ -19,30 +19,14 @@ export declare function setupCommandContext(workingDir?: string, customSyncServe
19
19
  * Safely shutdown a repository with proper error handling
20
20
  */
21
21
  export declare function safeRepoShutdown(repo: Repo, context?: string): Promise<void>;
22
- /**
23
- * Common progress message helpers
24
- */
25
- export declare const ProgressMessages: {
26
- directoryFound: () => void;
27
- configLoaded: () => void;
28
- repoConnected: () => void;
29
- syncServer: (server: string) => void;
30
- storageId: (id: string) => void;
31
- rootUrl: (url: string) => void;
32
- changesWritten: () => void;
33
- syncCompleted: (duration: number) => void;
34
- directoryStructureCreated: () => void;
35
- configSaved: () => void;
36
- repoCreated: () => void;
37
- };
38
22
  /**
39
23
  * Initialize sync in a directory
40
24
  */
41
- export declare function init(targetPath: string, syncServer?: string, syncServerStorageId?: string): Promise<void>;
25
+ export declare function init(targetPath: string, options?: InitOptions): Promise<void>;
42
26
  /**
43
27
  * Run bidirectional sync
44
28
  */
45
- export declare function sync(options: SyncOptions): Promise<void>;
29
+ export declare function sync(targetPath: string | undefined, options: SyncOptions): Promise<void>;
46
30
  /**
47
31
  * Show differences between local and remote
48
32
  */
@@ -50,7 +34,7 @@ export declare function diff(targetPath: string | undefined, options: DiffOption
50
34
  /**
51
35
  * Show sync status
52
36
  */
53
- export declare function status(): Promise<void>;
37
+ export declare function status(targetPath?: string, options?: StatusOptions): Promise<void>;
54
38
  /**
55
39
  * Show sync history
56
40
  */
@@ -66,12 +50,18 @@ export declare function clone(rootUrl: string, targetPath: string, options: Clon
66
50
  /**
67
51
  * Get the root URL for the current pushwork repository
68
52
  */
69
- export declare function url(targetPath?: string): Promise<void>;
70
- export declare function commit(targetPath: string, dryRun?: boolean): Promise<void>;
53
+ export declare function url(targetPath?: string, options?: UrlOptions): Promise<void>;
54
+ export declare function commit(targetPath: string, options?: CommitOptions): Promise<void>;
71
55
  /**
72
56
  * Debug command to inspect internal document state
73
57
  */
74
- export declare function debug(targetPath?: string, options?: {
75
- verbose?: boolean;
76
- }): Promise<void>;
58
+ export declare function debug(targetPath?: string, options?: DebugOptions): Promise<void>;
59
+ /**
60
+ * List tracked files
61
+ */
62
+ export declare function ls(targetPath?: string, options?: ListOptions): Promise<void>;
63
+ /**
64
+ * View or edit configuration
65
+ */
66
+ export declare function config(targetPath?: string, options?: ConfigOptions): Promise<void>;
77
67
  //# sourceMappingURL=commands.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAA2B,MAAM,2BAA2B,CAAC;AAI1E,OAAO,EAEL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,EAEhB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAMrC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,GAAE,MAAsB,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,GAAE,OAAc,GAC5B,OAAO,CAAC,cAAc,CAAC,CAqCzB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;yBAON,MAAM;oBAEX,MAAM;mBACP,MAAM;;8BAKK,MAAM;;;;CAOjC,CAAC;AA+DF;;GAEG;AACH,wBAAsB,IAAI,CACxB,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,IAAI,CAAC,CA6Hf;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgM9D;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,UAAU,oBAAM,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA6Df;AAED;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CA0J5C;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,UAAU,oBAAM,EAChB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Cf;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,oBAAM,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CA6Hf;AAED;;GAEG;AACH,wBAAsB,GAAG,CAAC,UAAU,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCzD;AAED,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAgEf;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,UAAU,SAAM,EAChB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,OAAO,CAAC,IAAI,CAAC,CA8Gf"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAgB,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EACL,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,aAAa,EACb,YAAY,EACZ,eAAe,EAEhB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAqCrC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyBD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,GAAE,MAAsB,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,GAAE,OAAc,GAC5B,OAAO,CAAC,cAAc,CAAC,CAqCzB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA2Gf;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,UAAU,oBAAM,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAiIf;AAED;;GAEG;AACH,wBAAsB,IAAI,CACxB,UAAU,oBAAM,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAgHf;AAED;;GAEG;AACH,wBAAsB,MAAM,CAC1B,UAAU,GAAE,MAAY,EACxB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA0Cf;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,UAAU,oBAAM,EAChB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,oBAAM,EAChB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CA+Ff;AAED;;GAEG;AACH,wBAAsB,GAAG,CACvB,UAAU,GAAE,MAAY,EACxB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CAgCf;AAED,wBAAsB,MAAM,CAC1B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAwCf;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,UAAU,GAAE,MAAY,EACxB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAkEf;AAED;;GAEG;AACH,wBAAsB,EAAE,CACtB,UAAU,GAAE,MAAY,EACxB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;GAEG;AACH,wBAAsB,MAAM,CAC1B,UAAU,GAAE,MAAY,EACxB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkDf"}