opencode-multidevice-sync 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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +15 -0
  3. package/README.md +111 -0
  4. package/README.ru.md +57 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +460 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/render.d.ts +45 -0
  10. package/dist/cli/render.d.ts.map +1 -0
  11. package/dist/cli/render.js +167 -0
  12. package/dist/cli/render.js.map +1 -0
  13. package/dist/cli/theme.d.ts +45 -0
  14. package/dist/cli/theme.d.ts.map +1 -0
  15. package/dist/cli/theme.js +88 -0
  16. package/dist/cli/theme.js.map +1 -0
  17. package/dist/core/backup.d.ts +13 -0
  18. package/dist/core/backup.d.ts.map +1 -0
  19. package/dist/core/backup.js +102 -0
  20. package/dist/core/backup.js.map +1 -0
  21. package/dist/core/fsx.d.ts +81 -0
  22. package/dist/core/fsx.d.ts.map +1 -0
  23. package/dist/core/fsx.js +353 -0
  24. package/dist/core/fsx.js.map +1 -0
  25. package/dist/core/git.d.ts +62 -0
  26. package/dist/core/git.d.ts.map +1 -0
  27. package/dist/core/git.js +162 -0
  28. package/dist/core/git.js.map +1 -0
  29. package/dist/core/guard.d.ts +5 -0
  30. package/dist/core/guard.d.ts.map +1 -0
  31. package/dist/core/guard.js +97 -0
  32. package/dist/core/guard.js.map +1 -0
  33. package/dist/core/health.d.ts +18 -0
  34. package/dist/core/health.d.ts.map +1 -0
  35. package/dist/core/health.js +88 -0
  36. package/dist/core/health.js.map +1 -0
  37. package/dist/core/host.d.ts +20 -0
  38. package/dist/core/host.d.ts.map +1 -0
  39. package/dist/core/host.js +50 -0
  40. package/dist/core/host.js.map +1 -0
  41. package/dist/core/index.d.ts +18 -0
  42. package/dist/core/index.d.ts.map +1 -0
  43. package/dist/core/index.js +18 -0
  44. package/dist/core/index.js.map +1 -0
  45. package/dist/core/jsonc.d.ts +20 -0
  46. package/dist/core/jsonc.d.ts.map +1 -0
  47. package/dist/core/jsonc.js +115 -0
  48. package/dist/core/jsonc.js.map +1 -0
  49. package/dist/core/lock.d.ts +14 -0
  50. package/dist/core/lock.d.ts.map +1 -0
  51. package/dist/core/lock.js +111 -0
  52. package/dist/core/lock.js.map +1 -0
  53. package/dist/core/overrides.d.ts +43 -0
  54. package/dist/core/overrides.d.ts.map +1 -0
  55. package/dist/core/overrides.js +169 -0
  56. package/dist/core/overrides.js.map +1 -0
  57. package/dist/core/paths.d.ts +36 -0
  58. package/dist/core/paths.d.ts.map +1 -0
  59. package/dist/core/paths.js +55 -0
  60. package/dist/core/paths.js.map +1 -0
  61. package/dist/core/preview.d.ts +3 -0
  62. package/dist/core/preview.d.ts.map +1 -0
  63. package/dist/core/preview.js +56 -0
  64. package/dist/core/preview.js.map +1 -0
  65. package/dist/core/repo.d.ts +57 -0
  66. package/dist/core/repo.d.ts.map +1 -0
  67. package/dist/core/repo.js +196 -0
  68. package/dist/core/repo.js.map +1 -0
  69. package/dist/core/reporter.d.ts +50 -0
  70. package/dist/core/reporter.d.ts.map +1 -0
  71. package/dist/core/reporter.js +63 -0
  72. package/dist/core/reporter.js.map +1 -0
  73. package/dist/core/sessions.d.ts +83 -0
  74. package/dist/core/sessions.d.ts.map +1 -0
  75. package/dist/core/sessions.js +508 -0
  76. package/dist/core/sessions.js.map +1 -0
  77. package/dist/core/settings.d.ts +68 -0
  78. package/dist/core/settings.d.ts.map +1 -0
  79. package/dist/core/settings.js +126 -0
  80. package/dist/core/settings.js.map +1 -0
  81. package/dist/core/setup.d.ts +48 -0
  82. package/dist/core/setup.d.ts.map +1 -0
  83. package/dist/core/setup.js +186 -0
  84. package/dist/core/setup.js.map +1 -0
  85. package/dist/core/sqlite.d.ts +37 -0
  86. package/dist/core/sqlite.d.ts.map +1 -0
  87. package/dist/core/sqlite.js +108 -0
  88. package/dist/core/sqlite.js.map +1 -0
  89. package/dist/core/stage.d.ts +44 -0
  90. package/dist/core/stage.d.ts.map +1 -0
  91. package/dist/core/stage.js +304 -0
  92. package/dist/core/stage.js.map +1 -0
  93. package/dist/core/sync.d.ts +52 -0
  94. package/dist/core/sync.d.ts.map +1 -0
  95. package/dist/core/sync.js +423 -0
  96. package/dist/core/sync.js.map +1 -0
  97. package/dist/plugin/index.d.ts +29 -0
  98. package/dist/plugin/index.d.ts.map +1 -0
  99. package/dist/plugin/index.js +88 -0
  100. package/dist/plugin/index.js.map +1 -0
  101. package/docs/MIGRATION.md +29 -0
  102. package/docs/ROADMAP.md +29 -0
  103. package/docs/SAFETY.md +31 -0
  104. package/examples/home-laptop.jsonc +31 -0
  105. package/examples/opencode-sync.overrides.jsonc +4 -0
  106. package/examples/work-laptop.jsonc +26 -0
  107. package/package.json +81 -0
@@ -0,0 +1,304 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { copyDirRecursive, copyPath, ensureDir, mirrorFile, removeNestedGitDirs, removeRecursive, replaceDirAtomically, replaceFileAtomically, syncDirIncremental, writeIfDiffers, } from "./fsx.js";
5
+ import { git } from "./git.js";
6
+ import { parseJsonc } from "./jsonc.js";
7
+ import { configTextForRepo, findConfigFile } from "./overrides.js";
8
+ import { AGENTS_DIR, DATA_DIR, STATE_DIR, getRoots } from "./paths.js";
9
+ /**
10
+ * Move files between their real locations and the sync repository.
11
+ *
12
+ * The repository worktree *is* `~/.config/opencode`, so config files need no
13
+ * copying at all. Everything that lives outside that directory is mirrored into
14
+ * a prefixed folder:
15
+ *
16
+ * ~/.local/share/opencode -> _data/
17
+ * ~/.local/state/opencode -> _state/
18
+ * ~/.agents/skills -> _agents/
19
+ *
20
+ * Staging in (push) is *local-consistent*: a file deleted on this machine is
21
+ * deleted in the repository too. Staging out (pull) is conservative by default
22
+ * and only becomes destructive with `force`, so an interrupted pull cannot wipe
23
+ * a skill directory.
24
+ */
25
+ /** Credential-bearing files, only staged when the user opts in. */
26
+ const CREDENTIAL_FILES = ["auth.json", "account.json"];
27
+ /** Non-credential data files that are always safe to sync. */
28
+ const DATA_FILES = ["sync-state.json"];
29
+ /**
30
+ * Configuration metadata under the data root. `storage/project` is a directory
31
+ * and `storage/migration` is a one-byte file — `copyPath` resolves which.
32
+ */
33
+ const DATA_PATHS = ["storage/project", "storage/migration"];
34
+ /** State files that describe this machine's current UI, not its configuration. */
35
+ const MACHINE_STATE_FILES = new Set(["session.json"]);
36
+ const MACHINE_STATE_DIRS = new Set(["locks"]);
37
+ const SKILL_LOCK = ".skill-lock.json";
38
+ export function createStageContext(repoRoot, settings, reporter, force, roots = getRoots()) {
39
+ return { repoRoot, roots, settings, reporter, force };
40
+ }
41
+ function dataFilesFor(settings) {
42
+ return settings.includeCredentials ? [...DATA_FILES, ...CREDENTIAL_FILES] : DATA_FILES;
43
+ }
44
+ /** Copy everything from the machine into the repository worktree. */
45
+ export function stageIn(ctx) {
46
+ const { repoRoot, roots, settings } = ctx;
47
+ const repoData = path.join(repoRoot, DATA_DIR);
48
+ const repoState = path.join(repoRoot, STATE_DIR);
49
+ const repoAgents = path.join(repoRoot, AGENTS_DIR);
50
+ ensureDir(repoData);
51
+ for (const file of dataFilesFor(settings)) {
52
+ mirrorFile(path.join(roots.data, file), path.join(repoData, file));
53
+ }
54
+ // A credential file that was previously synced must disappear from the repo
55
+ // the moment the user turns the option off.
56
+ if (!settings.includeCredentials) {
57
+ for (const file of CREDENTIAL_FILES)
58
+ removeRecursive(path.join(repoData, file));
59
+ }
60
+ for (const rel of DATA_PATHS) {
61
+ copyPath(path.join(roots.data, rel), path.join(repoData, rel));
62
+ }
63
+ if (settings.includeState) {
64
+ if (fs.existsSync(roots.state)) {
65
+ removeRecursive(repoState);
66
+ copyDirRecursive(roots.state, repoState, {
67
+ excludeFiles: MACHINE_STATE_FILES,
68
+ excludeDirs: MACHINE_STATE_DIRS,
69
+ });
70
+ }
71
+ else {
72
+ removeRecursive(repoState);
73
+ }
74
+ }
75
+ if (settings.includeSkills) {
76
+ syncDirIncremental(roots.agents, repoAgents, {
77
+ excludeFiles: new Set([".git"]),
78
+ excludeDirs: new Set([".git"]),
79
+ });
80
+ // Nested repositories would be committed as unusable gitlinks. Only the
81
+ // staging copy is cleaned; the real skills directory is never touched.
82
+ removeRecursive(path.join(repoAgents, ".git"));
83
+ removeNestedGitDirs(repoAgents);
84
+ stageSkillLockIn(ctx, repoAgents);
85
+ }
86
+ stageExtraPathsIn(ctx);
87
+ stageConfigIn(ctx);
88
+ }
89
+ /**
90
+ * The skills lock file records which skills are installed and which update
91
+ * prompts were dismissed. Merging instead of overwriting means installing a
92
+ * skill on one machine never un-installs one from another.
93
+ */
94
+ function stageSkillLockIn(ctx, repoAgents) {
95
+ const localLock = path.join(path.dirname(ctx.roots.agents), SKILL_LOCK);
96
+ const repoLock = path.join(repoAgents, SKILL_LOCK);
97
+ if (ctx.force || !fs.existsSync(localLock) || !fs.existsSync(repoLock)) {
98
+ mirrorFile(localLock, repoLock);
99
+ return;
100
+ }
101
+ const merged = mergeSkillLocks(readJson(repoLock), readJson(localLock));
102
+ if (merged)
103
+ writeIfDiffers(repoLock, `${JSON.stringify(merged, null, 2)}\n`);
104
+ else
105
+ mirrorFile(localLock, repoLock);
106
+ }
107
+ function readJson(file) {
108
+ try {
109
+ return JSON.parse(fs.readFileSync(file, "utf8"));
110
+ }
111
+ catch {
112
+ return undefined;
113
+ }
114
+ }
115
+ function mergeSkillLocks(remote, local) {
116
+ if (!remote || !local)
117
+ return undefined;
118
+ return {
119
+ ...remote,
120
+ ...local,
121
+ skills: { ...(remote.skills ?? {}), ...(local.skills ?? {}) },
122
+ dismissed: { ...(remote.dismissed ?? {}), ...(local.dismissed ?? {}) },
123
+ };
124
+ }
125
+ /**
126
+ * Rewrite the repository's config file with override-owned keys removed.
127
+ *
128
+ * The baseline comes from `git show HEAD:<file>`, not from disk: the worktree
129
+ * and the config directory are the same place, so the file on disk already has
130
+ * this machine's overrides applied to it.
131
+ *
132
+ * Without overrides nothing happens at all, which keeps comments and formatting
133
+ * byte-identical for the majority of users.
134
+ *
135
+ * Returns true when the file on disk was changed.
136
+ */
137
+ export function normalizeConfigForRepo(ctx) {
138
+ const configFile = findConfigFile(ctx.roots.config);
139
+ if (!configFile)
140
+ return false;
141
+ const relative = path.relative(ctx.repoRoot, configFile).split(path.sep).join("/");
142
+ const head = git(["show", `HEAD:${relative}`], { cwd: ctx.repoRoot });
143
+ const text = configTextForRepo(ctx.roots.config, head.ok ? head.stdout : undefined);
144
+ if (!text)
145
+ return false;
146
+ return writeIfDiffers(configFile, text);
147
+ }
148
+ function stageConfigIn(ctx) {
149
+ if (normalizeConfigForRepo(ctx)) {
150
+ ctx.reporter.detail("Removed per-machine overrides from the committed config");
151
+ }
152
+ }
153
+ function extraPathEntries(ctx) {
154
+ return ctx.settings.extraPaths.map((entry) => {
155
+ const source = path.isAbsolute(entry) ? entry : path.join(homeDir(), entry);
156
+ const repo = path.join(ctx.repoRoot, "_extra", sanitizeRelative(entry));
157
+ return { source, repo };
158
+ });
159
+ }
160
+ function homeDir() {
161
+ return process.env.SYNC_HOME || os.homedir();
162
+ }
163
+ function sanitizeRelative(entry) {
164
+ return entry
165
+ .replace(/^[A-Za-z]:/, "")
166
+ .replace(/[\\/]+/g, "_")
167
+ .replace(/^[._]+/, "");
168
+ }
169
+ function stageExtraPathsIn(ctx) {
170
+ for (const { source, repo } of extraPathEntries(ctx)) {
171
+ if (!fs.existsSync(source)) {
172
+ removeRecursive(repo);
173
+ continue;
174
+ }
175
+ if (fs.statSync(source).isDirectory())
176
+ syncDirIncremental(source, repo);
177
+ else
178
+ mirrorFile(source, repo);
179
+ }
180
+ }
181
+ /** Copy everything from the repository worktree back onto the machine. */
182
+ export function stageOut(ctx) {
183
+ const { repoRoot, roots, settings, force } = ctx;
184
+ const repoData = path.join(repoRoot, DATA_DIR);
185
+ const repoState = path.join(repoRoot, STATE_DIR);
186
+ const repoAgents = path.join(repoRoot, AGENTS_DIR);
187
+ ensureDir(roots.data);
188
+ for (const file of dataFilesFor(settings)) {
189
+ // `preserveMissing` matters for credentials: a machine that syncs without
190
+ // them must keep its own auth.json rather than have it deleted.
191
+ replaceFileAtomically(path.join(repoData, file), path.join(roots.data, file), {
192
+ preserveMissing: true,
193
+ });
194
+ }
195
+ for (const rel of DATA_PATHS) {
196
+ const source = path.join(repoData, rel);
197
+ if (fs.existsSync(source))
198
+ copyPath(source, path.join(roots.data, rel));
199
+ }
200
+ if (settings.includeState && fs.existsSync(repoState)) {
201
+ replaceDirAtomically(repoState, roots.state, {
202
+ preserveRootFiles: MACHINE_STATE_FILES,
203
+ excludeDirs: MACHINE_STATE_DIRS,
204
+ });
205
+ }
206
+ if (settings.includeSkills && fs.existsSync(repoAgents)) {
207
+ if (force) {
208
+ replaceDirAtomically(repoAgents, roots.agents, {
209
+ excludeFiles: new Set([SKILL_LOCK]),
210
+ });
211
+ }
212
+ else {
213
+ syncDirIncremental(repoAgents, roots.agents, {
214
+ excludeFiles: new Set([SKILL_LOCK]),
215
+ deleteExtraneous: false,
216
+ });
217
+ }
218
+ stageSkillLockOut(ctx, repoAgents);
219
+ }
220
+ stageExtraPathsOut(ctx);
221
+ }
222
+ function stageSkillLockOut(ctx, repoAgents) {
223
+ const repoLock = path.join(repoAgents, SKILL_LOCK);
224
+ const localLock = path.join(path.dirname(ctx.roots.agents), SKILL_LOCK);
225
+ if (ctx.force || !fs.existsSync(repoLock) || !fs.existsSync(localLock)) {
226
+ replaceFileAtomically(repoLock, localLock, { preserveMissing: true });
227
+ return;
228
+ }
229
+ const merged = mergeSkillLocks(readJson(localLock), readJson(repoLock));
230
+ if (merged)
231
+ writeIfDiffers(localLock, `${JSON.stringify(merged, null, 2)}\n`);
232
+ else
233
+ replaceFileAtomically(repoLock, localLock);
234
+ }
235
+ function stageExtraPathsOut(ctx) {
236
+ for (const { source, repo } of extraPathEntries(ctx)) {
237
+ if (!fs.existsSync(repo))
238
+ continue;
239
+ if (fs.statSync(repo).isDirectory())
240
+ replaceDirAtomically(repo, source);
241
+ else
242
+ replaceFileAtomically(repo, source);
243
+ }
244
+ }
245
+ /**
246
+ * Drop cached plugin packages that the config no longer references.
247
+ *
248
+ * Only `package.json` and the stale module directories are touched; OpenCode
249
+ * reinstalls whatever it still needs on the next start. Returns how many
250
+ * packages were removed.
251
+ */
252
+ export function prunePluginCache(configRoot, cacheRoot) {
253
+ const cachePackage = path.join(cacheRoot, "package.json");
254
+ const configFile = findConfigFile(configRoot);
255
+ if (!fs.existsSync(cachePackage) || !configFile)
256
+ return 0;
257
+ let config;
258
+ try {
259
+ config = parseJsonc(fs.readFileSync(configFile, "utf8"));
260
+ }
261
+ catch {
262
+ return 0;
263
+ }
264
+ const enabled = new Set((config?.plugin ?? []).map(pluginSpecToName));
265
+ const pkg = readJson(cachePackage);
266
+ if (!pkg)
267
+ return 0;
268
+ const dependencies = pkg.dependencies ?? {};
269
+ const stale = Object.keys(dependencies).filter((name) => !enabled.has(name));
270
+ if (stale.length === 0)
271
+ return 0;
272
+ for (const name of stale)
273
+ delete dependencies[name];
274
+ pkg.dependencies = dependencies;
275
+ fs.writeFileSync(cachePackage, `${JSON.stringify(pkg, null, 2)}\n`);
276
+ for (const name of stale) {
277
+ removeRecursive(path.join(cacheRoot, "node_modules", ...name.split("/")));
278
+ }
279
+ removeRecursive(path.join(cacheRoot, "package-lock.json"));
280
+ removeRecursive(path.join(cacheRoot, "bun.lock"));
281
+ return stale.length;
282
+ }
283
+ /**
284
+ * Reduce a plugin specifier to its package name.
285
+ *
286
+ * `opencode-foo@1.2.3` -> `opencode-foo`
287
+ * `@scope/opencode-foo@1.2.3` -> `@scope/opencode-foo`
288
+ */
289
+ export function pluginSpecToName(spec) {
290
+ if (spec.startsWith("@")) {
291
+ const rest = spec.slice(1);
292
+ const slash = rest.indexOf("/");
293
+ if (slash === -1)
294
+ return spec;
295
+ const after = rest.slice(slash + 1);
296
+ const at = after.indexOf("@");
297
+ if (at === -1)
298
+ return spec;
299
+ return `@${rest.slice(0, slash + 1)}${after.slice(0, at)}`;
300
+ }
301
+ const at = spec.indexOf("@");
302
+ return at === -1 ? spec : spec.slice(0, at);
303
+ }
304
+ //# sourceMappingURL=stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/core/stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { type Roots } from "./paths.js";
2
+ import { type ChangedFile, type Reporter, emptySummary } from "./reporter.js";
3
+ import { type Settings } from "./settings.js";
4
+ export interface SyncOptions {
5
+ settings?: Settings;
6
+ roots?: Roots;
7
+ reporter?: Reporter;
8
+ /** Overwrite the other side on conflict. */
9
+ force?: boolean;
10
+ /** Compute the result without writing anything to the remote. */
11
+ dryRun?: boolean;
12
+ }
13
+ export interface SyncResult {
14
+ action: "push" | "pull";
15
+ changed: boolean;
16
+ summary: ReturnType<typeof emptySummary>;
17
+ files: ChangedFile[];
18
+ sessions?: {
19
+ exported?: number;
20
+ imported?: number;
21
+ skipped?: number;
22
+ conflicts?: number;
23
+ backup?: string;
24
+ };
25
+ message: string;
26
+ /** True when OpenCode must restart for the pulled config to take effect. */
27
+ restartRequired: boolean;
28
+ }
29
+ declare class SyncError extends Error {
30
+ constructor(message: string);
31
+ }
32
+ export declare function push(options?: SyncOptions): Promise<SyncResult>;
33
+ export declare function pull(options?: SyncOptions): Promise<SyncResult>;
34
+ export interface StatusResult {
35
+ configured: boolean;
36
+ remote?: string;
37
+ branch: string;
38
+ initialized: boolean;
39
+ ahead: number;
40
+ behind: number;
41
+ dirty: number;
42
+ lastCommit?: string;
43
+ lastCommitDate?: string;
44
+ sessionsEnabled: boolean;
45
+ sessionShards: number;
46
+ overridesActive: boolean;
47
+ machineAlias: string;
48
+ }
49
+ export declare function status(options?: SyncOptions): StatusResult;
50
+ export declare function formatBytes(bytes: number): string;
51
+ export { SyncError };
52
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,KAAK,EAA6B,MAAM,YAAY,CAAC;AAYnE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,YAAY,EAIb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,QAAQ,EAAqC,MAAM,eAAe,CAAC;AAUjF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACzC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE;QACT,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,cAAM,SAAU,SAAQ,KAAK;gBACf,OAAO,EAAE,MAAM;CAI5B;AA2CD,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAGzE;AAkID,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAGzE;AAuQD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,MAAM,CAAC,OAAO,GAAE,WAAgB,GAAG,YAAY,CAuC9D;AAgDD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}