@itphx/synth-core 0.3.0 → 0.4.4

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 (187) hide show
  1. package/dist/auth/local.d.ts +14 -0
  2. package/dist/auth/local.d.ts.map +1 -1
  3. package/dist/auth/local.js +63 -11
  4. package/dist/auth/local.js.map +1 -1
  5. package/dist/auth/local.test.js +59 -0
  6. package/dist/auth/local.test.js.map +1 -1
  7. package/dist/events/bus.d.ts +7 -0
  8. package/dist/events/bus.d.ts.map +1 -1
  9. package/dist/events/bus.js +26 -3
  10. package/dist/events/bus.js.map +1 -1
  11. package/dist/events/bus.test.js +46 -0
  12. package/dist/events/bus.test.js.map +1 -1
  13. package/dist/index.d.ts +3 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/main.js +247 -8
  18. package/dist/main.js.map +1 -1
  19. package/dist/providers/index.d.ts +1 -0
  20. package/dist/providers/index.d.ts.map +1 -1
  21. package/dist/providers/index.js +4 -0
  22. package/dist/providers/index.js.map +1 -1
  23. package/dist/providers/remote.d.ts +60 -0
  24. package/dist/providers/remote.d.ts.map +1 -0
  25. package/dist/providers/remote.js +394 -0
  26. package/dist/providers/remote.js.map +1 -0
  27. package/dist/providers/remote.test.d.ts +2 -0
  28. package/dist/providers/remote.test.d.ts.map +1 -0
  29. package/dist/providers/remote.test.js +258 -0
  30. package/dist/providers/remote.test.js.map +1 -0
  31. package/dist/remote/aggregate.d.ts +43 -0
  32. package/dist/remote/aggregate.d.ts.map +1 -0
  33. package/dist/remote/aggregate.js +84 -0
  34. package/dist/remote/aggregate.js.map +1 -0
  35. package/dist/remote/aggregate.test.d.ts +2 -0
  36. package/dist/remote/aggregate.test.d.ts.map +1 -0
  37. package/dist/remote/aggregate.test.js +120 -0
  38. package/dist/remote/aggregate.test.js.map +1 -0
  39. package/dist/remote/client.d.ts +142 -0
  40. package/dist/remote/client.d.ts.map +1 -0
  41. package/dist/remote/client.js +290 -0
  42. package/dist/remote/client.js.map +1 -0
  43. package/dist/remote/client.test.d.ts +2 -0
  44. package/dist/remote/client.test.d.ts.map +1 -0
  45. package/dist/remote/client.test.js +176 -0
  46. package/dist/remote/client.test.js.map +1 -0
  47. package/dist/remote/connection.d.ts +66 -0
  48. package/dist/remote/connection.d.ts.map +1 -0
  49. package/dist/remote/connection.js +298 -0
  50. package/dist/remote/connection.js.map +1 -0
  51. package/dist/remote/connection.test.d.ts +2 -0
  52. package/dist/remote/connection.test.d.ts.map +1 -0
  53. package/dist/remote/connection.test.js +323 -0
  54. package/dist/remote/connection.test.js.map +1 -0
  55. package/dist/remote/credentials.d.ts +13 -0
  56. package/dist/remote/credentials.d.ts.map +1 -0
  57. package/dist/remote/credentials.js +81 -0
  58. package/dist/remote/credentials.js.map +1 -0
  59. package/dist/remote/credentials.test.d.ts +2 -0
  60. package/dist/remote/credentials.test.d.ts.map +1 -0
  61. package/dist/remote/credentials.test.js +69 -0
  62. package/dist/remote/credentials.test.js.map +1 -0
  63. package/dist/remote/device-flow.d.ts +72 -0
  64. package/dist/remote/device-flow.d.ts.map +1 -0
  65. package/dist/remote/device-flow.js +229 -0
  66. package/dist/remote/device-flow.js.map +1 -0
  67. package/dist/remote/device-flow.test.d.ts +2 -0
  68. package/dist/remote/device-flow.test.d.ts.map +1 -0
  69. package/dist/remote/device-flow.test.js +103 -0
  70. package/dist/remote/device-flow.test.js.map +1 -0
  71. package/dist/remote/event-bridge.d.ts +46 -0
  72. package/dist/remote/event-bridge.d.ts.map +1 -0
  73. package/dist/remote/event-bridge.js +218 -0
  74. package/dist/remote/event-bridge.js.map +1 -0
  75. package/dist/remote/event-bridge.test.d.ts +2 -0
  76. package/dist/remote/event-bridge.test.d.ts.map +1 -0
  77. package/dist/remote/event-bridge.test.js +240 -0
  78. package/dist/remote/event-bridge.test.js.map +1 -0
  79. package/dist/remote/index.d.ts +19 -0
  80. package/dist/remote/index.d.ts.map +1 -0
  81. package/dist/remote/index.js +11 -0
  82. package/dist/remote/index.js.map +1 -0
  83. package/dist/remote/session.d.ts +72 -0
  84. package/dist/remote/session.d.ts.map +1 -0
  85. package/dist/remote/session.js +248 -0
  86. package/dist/remote/session.js.map +1 -0
  87. package/dist/remote/session.test.d.ts +2 -0
  88. package/dist/remote/session.test.d.ts.map +1 -0
  89. package/dist/remote/session.test.js +482 -0
  90. package/dist/remote/session.test.js.map +1 -0
  91. package/dist/remote/transfer.d.ts +75 -0
  92. package/dist/remote/transfer.d.ts.map +1 -0
  93. package/dist/remote/transfer.js +491 -0
  94. package/dist/remote/transfer.js.map +1 -0
  95. package/dist/remote/transfer.test.d.ts +2 -0
  96. package/dist/remote/transfer.test.d.ts.map +1 -0
  97. package/dist/remote/transfer.test.js +416 -0
  98. package/dist/remote/transfer.test.js.map +1 -0
  99. package/dist/remote/types.d.ts +28 -0
  100. package/dist/remote/types.d.ts.map +1 -0
  101. package/dist/remote/types.js +10 -0
  102. package/dist/remote/types.js.map +1 -0
  103. package/dist/server/app.d.ts +62 -1
  104. package/dist/server/app.d.ts.map +1 -1
  105. package/dist/server/app.js +364 -20
  106. package/dist/server/app.js.map +1 -1
  107. package/dist/server/app.proxy.test.d.ts +2 -0
  108. package/dist/server/app.proxy.test.d.ts.map +1 -0
  109. package/dist/server/app.proxy.test.js +193 -0
  110. package/dist/server/app.proxy.test.js.map +1 -0
  111. package/dist/server/app.remote.test.d.ts +2 -0
  112. package/dist/server/app.remote.test.d.ts.map +1 -0
  113. package/dist/server/app.remote.test.js +674 -0
  114. package/dist/server/app.remote.test.js.map +1 -0
  115. package/dist/server/proxy.d.ts +14 -0
  116. package/dist/server/proxy.d.ts.map +1 -0
  117. package/dist/server/proxy.js +93 -0
  118. package/dist/server/proxy.js.map +1 -0
  119. package/dist/server/routes/auth.d.ts +26 -2
  120. package/dist/server/routes/auth.d.ts.map +1 -1
  121. package/dist/server/routes/auth.js +269 -36
  122. package/dist/server/routes/auth.js.map +1 -1
  123. package/dist/server/routes/auth.test.d.ts +2 -0
  124. package/dist/server/routes/auth.test.d.ts.map +1 -0
  125. package/dist/server/routes/auth.test.js +466 -0
  126. package/dist/server/routes/auth.test.js.map +1 -0
  127. package/dist/server/routes/fs.d.ts +2 -1
  128. package/dist/server/routes/fs.d.ts.map +1 -1
  129. package/dist/server/routes/fs.js +159 -5
  130. package/dist/server/routes/fs.js.map +1 -1
  131. package/dist/server/routes/hybrid.d.ts +32 -0
  132. package/dist/server/routes/hybrid.d.ts.map +1 -0
  133. package/dist/server/routes/hybrid.js +21 -0
  134. package/dist/server/routes/hybrid.js.map +1 -0
  135. package/dist/server/routes/hybrid.test.d.ts +2 -0
  136. package/dist/server/routes/hybrid.test.d.ts.map +1 -0
  137. package/dist/server/routes/hybrid.test.js +454 -0
  138. package/dist/server/routes/hybrid.test.js.map +1 -0
  139. package/dist/server/routes/messages.d.ts +2 -1
  140. package/dist/server/routes/messages.d.ts.map +1 -1
  141. package/dist/server/routes/messages.js +104 -1
  142. package/dist/server/routes/messages.js.map +1 -1
  143. package/dist/server/routes/models.cache.test.d.ts +2 -0
  144. package/dist/server/routes/models.cache.test.d.ts.map +1 -0
  145. package/dist/server/routes/models.cache.test.js +59 -0
  146. package/dist/server/routes/models.cache.test.js.map +1 -0
  147. package/dist/server/routes/models.d.ts +9 -1
  148. package/dist/server/routes/models.d.ts.map +1 -1
  149. package/dist/server/routes/models.js +35 -2
  150. package/dist/server/routes/models.js.map +1 -1
  151. package/dist/server/routes/models.remote.test.d.ts +2 -0
  152. package/dist/server/routes/models.remote.test.d.ts.map +1 -0
  153. package/dist/server/routes/models.remote.test.js +101 -0
  154. package/dist/server/routes/models.remote.test.js.map +1 -0
  155. package/dist/server/routes/project-transfer.d.ts +16 -0
  156. package/dist/server/routes/project-transfer.d.ts.map +1 -0
  157. package/dist/server/routes/project-transfer.js +141 -0
  158. package/dist/server/routes/project-transfer.js.map +1 -0
  159. package/dist/server/routes/project-transfer.test.d.ts +2 -0
  160. package/dist/server/routes/project-transfer.test.d.ts.map +1 -0
  161. package/dist/server/routes/project-transfer.test.js +199 -0
  162. package/dist/server/routes/project-transfer.test.js.map +1 -0
  163. package/dist/server/routes/projects.d.ts +2 -1
  164. package/dist/server/routes/projects.d.ts.map +1 -1
  165. package/dist/server/routes/projects.js +101 -5
  166. package/dist/server/routes/projects.js.map +1 -1
  167. package/dist/server/routes/providers.d.ts +1 -1
  168. package/dist/server/routes/providers.d.ts.map +1 -1
  169. package/dist/server/routes/providers.js +3 -1
  170. package/dist/server/routes/providers.js.map +1 -1
  171. package/dist/server/routes/providers.test.d.ts +2 -0
  172. package/dist/server/routes/providers.test.d.ts.map +1 -0
  173. package/dist/server/routes/providers.test.js +58 -0
  174. package/dist/server/routes/providers.test.js.map +1 -0
  175. package/dist/server/routes/queue.d.ts +2 -1
  176. package/dist/server/routes/queue.d.ts.map +1 -1
  177. package/dist/server/routes/queue.js +89 -1
  178. package/dist/server/routes/queue.js.map +1 -1
  179. package/dist/server/routes/sessions.d.ts +8 -1
  180. package/dist/server/routes/sessions.d.ts.map +1 -1
  181. package/dist/server/routes/sessions.js +202 -9
  182. package/dist/server/routes/sessions.js.map +1 -1
  183. package/dist/server/serialize.d.ts +2 -0
  184. package/dist/server/serialize.d.ts.map +1 -1
  185. package/dist/server/serialize.js +2 -0
  186. package/dist/server/serialize.js.map +1 -1
  187. package/package.json +6 -2
@@ -0,0 +1,416 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { mkdtemp, mkdir, writeFile, readFile, rm, stat } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { MessageRole } from '@itphx/synth-shared';
6
+ import { FileStore } from '../storage/file-store.js';
7
+ import { SessionManager } from '../sessions/manager.js';
8
+ import { ProjectStore } from '../storage/project-store.js';
9
+ import { syncProjectToRemote, forkProjectToLocal, walkDir, remoteWalk, resolveLocalWorkspace, slugify, isBinaryBuffer, } from './transfer.js';
10
+ function makeFakeRemoteClient(overrides = {}) {
11
+ const client = {
12
+ createProject: vi.fn(async (body) => ({ id: 'remote-1', ...body })),
13
+ updateProject: vi.fn(async (id, body) => ({ id, ...body })),
14
+ getProject: vi.fn(async () => ({ id: 'remote-1', name: 'Remote Project', description: 'desc', icon: null, color: null, repos: null, workspace: 'remote-project' })),
15
+ fsWorkspaceMkdir: vi.fn(async () => ({ created: true })),
16
+ importSession: vi.fn(async () => ({ id: 'new-session' })),
17
+ listSessions: vi.fn(async () => [{ id: 'rs-1', project_id: 'remote-1' }]),
18
+ exportSession: vi.fn(async () => ({
19
+ title: 'RS1',
20
+ engine: 'synth',
21
+ sessionOrigin: 'user',
22
+ settings: { temperature: 0.3 },
23
+ messages: [
24
+ { id: 'm1', role: 'user', seq: 1, origin: 'local', parts: [{ id: 'p1', type: 'text', data: 'привет' }], content: 'привет', createdAt: '2026-01-01T00:00:00.000Z', disabled: false, pinned: false, hidden: false },
25
+ { id: 'm2', role: 'assistant', seq: 2, origin: 'local', parts: [{ id: 'p2', type: 'text', data: 'ответ' }], content: 'ответ', createdAt: '2026-01-01T00:00:01.000Z', disabled: false, pinned: false, hidden: false },
26
+ ],
27
+ todos: [{ id: 't1', content: 'task', status: 'pending', priority: 'medium' }],
28
+ sticky_notes: [],
29
+ references: [],
30
+ checkpoints: [],
31
+ })),
32
+ fsList: vi.fn(async (params) => {
33
+ if (!params.path) {
34
+ return {
35
+ path: '',
36
+ entries: [
37
+ { name: 'src', path: 'src', isDirectory: true, size: 0, modifiedAt: 0 },
38
+ { name: 'readme.md', path: 'readme.md', isDirectory: false, size: 10, modifiedAt: 0 },
39
+ { name: 'node_modules', path: 'node_modules', isDirectory: true, size: 0, modifiedAt: 0 },
40
+ ],
41
+ };
42
+ }
43
+ if (params.path === 'src') {
44
+ return {
45
+ path: 'src',
46
+ entries: [
47
+ { name: 'main.ts', path: 'src/main.ts', isDirectory: false, size: 5, modifiedAt: 0 },
48
+ ],
49
+ };
50
+ }
51
+ return { path: params.path, entries: [] };
52
+ }),
53
+ fsDownload: vi.fn(async () => new Response(new Uint8Array([104, 105]), { status: 200 })),
54
+ fsWrite: vi.fn(async () => ({ path: 'x', content: '', size: 0, encoding: 'utf-8' })),
55
+ fsUpload: vi.fn(async () => ({ path: 'x', name: 'x' })),
56
+ ...overrides,
57
+ };
58
+ return client;
59
+ }
60
+ describe('transfer helpers', () => {
61
+ let tmpDir;
62
+ let workspacesRoot;
63
+ beforeEach(async () => {
64
+ tmpDir = await mkdtemp(join(tmpdir(), 'synth-transfer-'));
65
+ workspacesRoot = join(tmpDir, 'workspaces');
66
+ await mkdir(workspacesRoot, { recursive: true });
67
+ });
68
+ afterEach(async () => {
69
+ await rm(tmpDir, { recursive: true, force: true });
70
+ });
71
+ describe('slugify', () => {
72
+ it('преобразует имя в безопасный slug', () => {
73
+ expect(slugify('My Cool Project!')).toBe('my-cool-project');
74
+ expect(slugify('Кириллица')).toBe('project'); // не-латиница → дефолт
75
+ expect(slugify('')).toBe('project');
76
+ });
77
+ });
78
+ describe('isBinaryBuffer', () => {
79
+ it('распознаёт бинарные буферы по NUL-байту', () => {
80
+ expect(isBinaryBuffer(Buffer.from([1, 2, 0, 3]))).toBe(true);
81
+ expect(isBinaryBuffer(Buffer.from('text'))).toBe(false);
82
+ expect(isBinaryBuffer(Buffer.from([0xff, 0xfe, 0x68, 0x00]))).toBe(false); // UTF-16 BOM
83
+ });
84
+ });
85
+ describe('resolveLocalWorkspace', () => {
86
+ it('абсолютный workspace — как есть, относительный — от workspacesRoot', () => {
87
+ const project = { workspace: 'rel/ws' };
88
+ expect(resolveLocalWorkspace(project, '/root', '/def')).toBe('/root/rel/ws');
89
+ const absProject = { workspace: '/abs/ws' };
90
+ expect(resolveLocalWorkspace(absProject, '/root', '/def')).toBe('/abs/ws');
91
+ const noWs = {};
92
+ expect(resolveLocalWorkspace(noWs, '/root', '/def')).toBe('/def');
93
+ });
94
+ });
95
+ describe('walkDir', () => {
96
+ it('обходит файлы рекурсивно, исключая node_modules/.git/скрытые', async () => {
97
+ const ws = join(tmpDir, 'ws');
98
+ await mkdir(join(ws, 'src', 'nested'), { recursive: true });
99
+ await mkdir(join(ws, 'node_modules'), { recursive: true });
100
+ await mkdir(join(ws, '.git'), { recursive: true });
101
+ await mkdir(join(ws, '.synth'), { recursive: true });
102
+ await writeFile(join(ws, 'readme.md'), 'hi');
103
+ await writeFile(join(ws, 'src', 'main.ts'), 'code');
104
+ await writeFile(join(ws, 'src', 'nested', 'a.json'), '{}');
105
+ await writeFile(join(ws, 'node_modules', 'pkg.js'), 'x');
106
+ await writeFile(join(ws, '.git', 'config'), 'x');
107
+ await writeFile(join(ws, '.env'), 'SECRET=1');
108
+ await writeFile(join(ws, '.hidden.ts'), 'x');
109
+ const files = await walkDir(ws);
110
+ expect(files).toEqual(['readme.md', 'src/main.ts', 'src/nested/a.json']);
111
+ });
112
+ });
113
+ describe('remoteWalk', () => {
114
+ it('обходит удалённые файлы, исключая node_modules', async () => {
115
+ const client = makeFakeRemoteClient();
116
+ const files = await remoteWalk(client, 'remote-1', '', []);
117
+ expect(files).toEqual(['readme.md', 'src/main.ts']);
118
+ });
119
+ });
120
+ describe('syncProjectToRemote', () => {
121
+ it('создаёт проект, импортирует сессии и загружает файлы', async () => {
122
+ const client = makeFakeRemoteClient();
123
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
124
+ const project = projectStore.create('My Project', 'local', {
125
+ description: 'desc', icon: '🚀', color: 'red',
126
+ repos: [{ path: 'repo1' }],
127
+ workspace: 'my-project',
128
+ });
129
+ await projectStore.save(project);
130
+ const sessionManager = new SessionManager(new FileStore({ dataDir: tmpDir }));
131
+ const session = await sessionManager.createSession({ title: 'S1', projectId: project.id });
132
+ await sessionManager.addMessage(session.id, {
133
+ id: 'm1', role: MessageRole.USER, seq: 1, origin: 'local',
134
+ parts: [{ id: 'p1', type: 'text', data: 'hello' }],
135
+ content: 'hello', createdAt: new Date().toISOString(),
136
+ disabled: false, pinned: false, hidden: false,
137
+ });
138
+ const localProjectDir = join(tmpDir, 'ws');
139
+ await mkdir(join(localProjectDir, 'sub'), { recursive: true });
140
+ await mkdir(join(localProjectDir, 'node_modules'), { recursive: true });
141
+ await writeFile(join(localProjectDir, 'a.txt'), 'text');
142
+ await writeFile(join(localProjectDir, 'sub', 'b.ts'), 'code');
143
+ await writeFile(join(localProjectDir, 'node_modules', 'x.js'), 'x');
144
+ await mkdir(join(localProjectDir, '.git'), { recursive: true });
145
+ await writeFile(join(localProjectDir, '.git', 'config'), 'x');
146
+ await writeFile(join(localProjectDir, 'image.bin'), Buffer.from([1, 0, 2]));
147
+ const stats = await syncProjectToRemote({
148
+ localProject: project,
149
+ remoteClient: client,
150
+ includeFiles: true,
151
+ includeSessions: true,
152
+ localProjectDir,
153
+ localSessions: [session],
154
+ });
155
+ expect(client.createProject).toHaveBeenCalledWith(expect.objectContaining({
156
+ name: 'My Project',
157
+ description: 'desc',
158
+ icon: '🚀',
159
+ color: 'red',
160
+ workspace: 'my-project',
161
+ }));
162
+ expect(client.fsWorkspaceMkdir).toHaveBeenCalledWith({ path: 'my-project' });
163
+ // Каталог workspace создаётся ДО createProject (backend валидирует его наличие).
164
+ const mkdirOrder = client.fsWorkspaceMkdir.mock.invocationCallOrder[0] ?? 0;
165
+ const createOrder = client.createProject.mock.invocationCallOrder[0] ?? 0;
166
+ expect(mkdirOrder).toBeLessThan(createOrder);
167
+ expect(client.importSession).toHaveBeenCalledWith(expect.objectContaining({ import: { project_id: 'remote-1' } }));
168
+ // текстовые файлы — fsWrite, бинарный — fsUpload; node_modules/.git исключены
169
+ expect(client.fsWrite).toHaveBeenCalledWith({ projectId: 'remote-1', path: 'a.txt', content: 'text' });
170
+ expect(client.fsWrite).toHaveBeenCalledWith({ projectId: 'remote-1', path: 'sub/b.ts', content: 'code' });
171
+ expect(client.fsUpload).toHaveBeenCalledTimes(1);
172
+ expect(stats).toMatchObject({ projectId: 'remote-1', sessionsImported: 1, filesUploaded: 3, created: true });
173
+ });
174
+ it('обновляет существующий проект при remoteProjectId', async () => {
175
+ const client = makeFakeRemoteClient();
176
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
177
+ const project = projectStore.create('P', 'local', { description: 'd' });
178
+ await projectStore.save(project);
179
+ const stats = await syncProjectToRemote({
180
+ localProject: project,
181
+ remoteClient: client,
182
+ remoteProjectId: 'remote-1',
183
+ includeFiles: false,
184
+ includeSessions: false,
185
+ localProjectDir: join(tmpDir, 'ws'),
186
+ localSessions: [],
187
+ });
188
+ expect(client.createProject).not.toHaveBeenCalled();
189
+ expect(client.updateProject).toHaveBeenCalledWith('remote-1', expect.objectContaining({ name: 'P' }));
190
+ expect(stats.created).toBe(false);
191
+ });
192
+ it('publish передаёт plan проекта в createProject и updateProject', async () => {
193
+ const plan = {
194
+ version: 1,
195
+ updatedAt: '2026-01-01T00:00:00.000Z',
196
+ columns: [{ id: 'c1', name: 'Колонка', order: 0 }],
197
+ items: [],
198
+ };
199
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
200
+ const project = projectStore.create('PlanPublish', 'local');
201
+ project.plan = plan;
202
+ await projectStore.save(project);
203
+ const baseOpts = {
204
+ includeFiles: false,
205
+ includeSessions: false,
206
+ localProjectDir: join(tmpDir, 'ws'),
207
+ localSessions: [],
208
+ };
209
+ const createClient = makeFakeRemoteClient();
210
+ await syncProjectToRemote({ ...baseOpts, localProject: project, remoteClient: createClient });
211
+ expect(createClient.createProject).toHaveBeenCalledWith(expect.objectContaining({ plan }));
212
+ const updateClient = makeFakeRemoteClient();
213
+ await syncProjectToRemote({
214
+ ...baseOpts,
215
+ localProject: project,
216
+ remoteClient: updateClient,
217
+ remoteProjectId: 'remote-1',
218
+ });
219
+ expect(updateClient.updateProject).toHaveBeenCalledWith('remote-1', expect.objectContaining({ plan }));
220
+ });
221
+ it('publish: parentId/references переписываются на новые remote-id, чужие ссылки зануляются', async () => {
222
+ const importedIds = ['remote-ses-A', 'remote-ses-B'];
223
+ let importCall = 0;
224
+ const client = makeFakeRemoteClient({
225
+ importSession: vi.fn(async (body) => ({
226
+ ...body,
227
+ id: importedIds[importCall++] ?? 'remote-ses-unknown',
228
+ })),
229
+ });
230
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
231
+ const project = projectStore.create('PublishRefs', 'local');
232
+ await projectStore.save(project);
233
+ const sessionManager = new SessionManager(new FileStore({ dataDir: tmpDir }));
234
+ const parent = await sessionManager.createSession({ title: 'Parent', projectId: project.id });
235
+ const child = await sessionManager.createSession({ title: 'Child', projectId: project.id, parentId: parent.id });
236
+ // Ссылка на переносимую сессию + ссылка на непереносимую (вне проекта).
237
+ child.references = [
238
+ { type: 'session_reference', sessionId: parent.id, label: 'parent', messageRange: [1, 2], createdAt: new Date().toISOString() },
239
+ { type: 'session_reference', sessionId: 'outside-session', label: 'outside', messageRange: [1, 2], createdAt: new Date().toISOString() },
240
+ ];
241
+ // Сохраняем references ДО addMessage (иначе addMessage перезапишет их в store).
242
+ await sessionManager.saveSession(child);
243
+ // session_reference-часть в сообщении + sourceMsgId на сообщение, которого нет в наборе.
244
+ await sessionManager.addMessage(child.id, {
245
+ id: 'child-m1', role: MessageRole.USER, seq: 1, origin: 'local',
246
+ parts: [
247
+ { id: 'p1', type: 'text', data: 'hello' },
248
+ { id: 'p2', type: 'session_reference', data: { sessionId: parent.id, label: 'ref-in-msg' } },
249
+ ],
250
+ content: 'hello', sourceMsgId: 'ghost-message', createdAt: new Date().toISOString(),
251
+ disabled: false, pinned: false, hidden: false,
252
+ });
253
+ // addMessage не мутирует in-memory объект — берём свежие копии из store.
254
+ const freshChild = (await sessionManager.getSession(child.id));
255
+ const freshParent = (await sessionManager.getSession(parent.id));
256
+ const stats = await syncProjectToRemote({
257
+ localProject: project,
258
+ remoteClient: client,
259
+ includeFiles: false,
260
+ includeSessions: true,
261
+ localProjectDir: join(tmpDir, 'ws'),
262
+ localSessions: [freshChild, freshParent],
263
+ });
264
+ expect(stats.sessionsImported).toBe(2);
265
+ // Топологический порядок: родитель импортируется раньше ребёнка.
266
+ const bodies = client.importSession.mock.calls.map((c) => c[0]);
267
+ expect(bodies[0].id).toBe(parent.id);
268
+ expect(bodies[1].id).toBe(child.id);
269
+ // parentId ребёнка → новый remote-id родителя.
270
+ expect(bodies[1].parentId).toBe('remote-ses-A');
271
+ // references: переносимая → remote-id, непереносимая → null.
272
+ const refs = bodies[1].references;
273
+ expect(refs[0].sessionId).toBe('remote-ses-A');
274
+ expect(refs[1].sessionId).toBeNull();
275
+ // session_reference-часть сообщения → remote-id; sourceMsgId вне набора → null.
276
+ const childMsgParts = bodies[1].messages[0].parts;
277
+ const refPart = childMsgParts.find((p) => p.type === 'session_reference');
278
+ expect(refPart.data.sessionId).toBe('remote-ses-A');
279
+ expect(bodies[1].messages[0].sourceMsgId).toBeNull();
280
+ });
281
+ it('бросает ошибку, если локальный workspace не существует и нужны файлы', async () => {
282
+ const client = makeFakeRemoteClient();
283
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
284
+ const project = projectStore.create('P', 'local', { workspace: 'missing' });
285
+ await projectStore.save(project);
286
+ await expect(syncProjectToRemote({
287
+ localProject: project,
288
+ remoteClient: client,
289
+ includeFiles: true,
290
+ includeSessions: false,
291
+ localProjectDir: join(tmpDir, 'ws', 'missing'),
292
+ localSessions: [],
293
+ })).rejects.toThrow(/не найден/);
294
+ });
295
+ });
296
+ describe('forkProjectToLocal', () => {
297
+ it('создаёт локальный проект, сессии с историей и скачивает файлы', async () => {
298
+ const client = makeFakeRemoteClient();
299
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
300
+ const sessionManager = new SessionManager(new FileStore({ dataDir: tmpDir }));
301
+ const stats = await forkProjectToLocal({
302
+ remoteProjectId: 'remote-1',
303
+ remoteClient: client,
304
+ localProjectStore: projectStore,
305
+ localSessionManager: sessionManager,
306
+ includeFiles: true,
307
+ includeSessions: true,
308
+ localWorkspacesRoot: workspacesRoot,
309
+ });
310
+ expect(stats.projectId).toBeTruthy();
311
+ expect(stats.sessionsImported).toBe(1);
312
+ expect(stats.filesDownloaded).toBe(2); // readme.md + src/main.ts
313
+ const localProject = await projectStore.load(stats.projectId);
314
+ expect(localProject?.name).toBe('Remote Project');
315
+ expect(localProject?.workspace).toBe('remote-project');
316
+ const sessions = await sessionManager.listSessions({ projectId: stats.projectId });
317
+ expect(sessions).toHaveLength(1);
318
+ expect(sessions[0].title).toBe('RS1');
319
+ expect(sessions[0].messages).toHaveLength(2);
320
+ expect(sessions[0].messages[1].content).toBe('ответ');
321
+ expect(sessions[0].messages[1].seq).toBe(2);
322
+ expect(sessions[0].todos).toEqual([{ id: 't1', content: 'task', status: 'pending', priority: 'medium' }]);
323
+ const downloaded = await readFile(join(workspacesRoot, 'remote-project', 'src', 'main.ts'));
324
+ expect(downloaded.toString()).toBe('hi');
325
+ const wsStat = await stat(join(workspacesRoot, 'remote-project'));
326
+ expect(wsStat.isDirectory()).toBe(true);
327
+ });
328
+ it('фильтрует сессии не из этого проекта', async () => {
329
+ const client = makeFakeRemoteClient({
330
+ listSessions: async () => [
331
+ { id: 'rs-1', project_id: 'remote-1' },
332
+ { id: 'rs-2', project_id: 'other-project' },
333
+ ],
334
+ });
335
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
336
+ const sessionManager = new SessionManager(new FileStore({ dataDir: tmpDir }));
337
+ const stats = await forkProjectToLocal({
338
+ remoteProjectId: 'remote-1',
339
+ remoteClient: client,
340
+ localProjectStore: projectStore,
341
+ localSessionManager: sessionManager,
342
+ includeFiles: false,
343
+ includeSessions: true,
344
+ localWorkspacesRoot: workspacesRoot,
345
+ });
346
+ expect(stats.sessionsImported).toBe(1);
347
+ expect(client.exportSession).toHaveBeenCalledTimes(1);
348
+ expect(client.exportSession).toHaveBeenCalledWith('rs-1');
349
+ });
350
+ it('fork: parentId/references переписываются на новые локальные id, чужие ссылки зануляются', async () => {
351
+ const exportsBySession = {
352
+ 'rs-parent': {
353
+ title: 'Parent',
354
+ engine: 'synth',
355
+ sessionOrigin: 'user',
356
+ settings: { temperature: 0.3 },
357
+ messages: [
358
+ { id: 'pm1', role: 'user', seq: 1, origin: 'local', parts: [{ id: 'pp1', type: 'text', data: 'hi' }], content: 'hi', createdAt: '2026-01-01T00:00:00.000Z', disabled: false, pinned: false, hidden: false },
359
+ ],
360
+ todos: [],
361
+ sticky_notes: [],
362
+ references: [],
363
+ checkpoints: [],
364
+ },
365
+ 'rs-child': {
366
+ title: 'Child',
367
+ engine: 'synth',
368
+ sessionOrigin: 'user',
369
+ parentId: 'rs-parent',
370
+ settings: { temperature: 0.3 },
371
+ messages: [
372
+ { id: 'cm1', role: 'user', seq: 1, origin: 'local', parts: [{ id: 'cp1', type: 'text', data: 'hello' }], content: 'hello', createdAt: '2026-01-01T00:00:00.000Z', disabled: false, pinned: false, hidden: false },
373
+ ],
374
+ todos: [],
375
+ sticky_notes: [],
376
+ references: [
377
+ { type: 'session_reference', sessionId: 'rs-parent', label: 'parent', messageRange: [1, 1], createdAt: '2026-01-01T00:00:00.000Z' },
378
+ { type: 'session_reference', sessionId: 'outside-session', label: 'outside', messageRange: [1, 1], createdAt: '2026-01-01T00:00:00.000Z' },
379
+ ],
380
+ checkpoints: [],
381
+ },
382
+ };
383
+ const client = makeFakeRemoteClient({
384
+ listSessions: async () => [
385
+ { id: 'rs-parent', project_id: 'remote-1' },
386
+ { id: 'rs-child', project_id: 'remote-1' },
387
+ ],
388
+ exportSession: vi.fn(async (id) => exportsBySession[id] ?? {}),
389
+ });
390
+ const projectStore = new ProjectStore({ dataDir: tmpDir });
391
+ const sessionManager = new SessionManager(new FileStore({ dataDir: tmpDir }));
392
+ const stats = await forkProjectToLocal({
393
+ remoteProjectId: 'remote-1',
394
+ remoteClient: client,
395
+ localProjectStore: projectStore,
396
+ localSessionManager: sessionManager,
397
+ includeFiles: false,
398
+ includeSessions: true,
399
+ localWorkspacesRoot: workspacesRoot,
400
+ });
401
+ expect(stats.sessionsImported).toBe(2);
402
+ const sessions = await sessionManager.listSessions({ projectId: stats.projectId });
403
+ const parent = sessions.find((s) => s.title === 'Parent');
404
+ const child = sessions.find((s) => s.title === 'Child');
405
+ expect(parent).toBeDefined();
406
+ expect(child).toBeDefined();
407
+ // parentId ребёнка → новый локальный id родителя.
408
+ expect(child.parentId).toBe(parent.id);
409
+ // references: переносимая → локальный id, непереносимая → null.
410
+ expect(child.references[0].sessionId).toBe(parent.id);
411
+ expect(child.references[1].sessionId).toBeNull();
412
+ expect(parent.parentId).toBeUndefined();
413
+ });
414
+ });
415
+ });
416
+ //# sourceMappingURL=transfer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.test.js","sourceRoot":"","sources":["../../src/remote/transfer.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,OAAO,EACP,UAAU,EACV,qBAAqB,EACrB,OAAO,EACP,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,SAAS,oBAAoB,CAAC,YAAqC,EAAE;IACnE,MAAM,MAAM,GAAG;QACb,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,IAA6B,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5F,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAU,EAAE,IAA6B,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5F,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACnK,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;QACzD,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;QACzE,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAChC,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,OAAO;YACf,aAAa,EAAE,MAAM;YACrB,QAAQ,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE;YAC9B,QAAQ,EAAE;gBACR,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,0BAA0B,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;gBACjN,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,0BAA0B,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;aACrN;YACD,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;YAC7E,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE,EAAE;YACd,WAAW,EAAE,EAAE;SAChB,CAAC,CAAC;QACH,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,MAA4C,EAAE,EAAE;YACnE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE;wBACP,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;wBACvE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;wBACrF,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;qBAC1F;iBACF,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC1B,OAAO;oBACL,IAAI,EAAE,KAAK;oBACX,OAAO,EAAE;wBACP,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;qBACrF;iBACF,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC5C,CAAC,CAAC;QACF,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACxF,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACpF,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACvD,GAAG,SAAS;KACb,CAAC;IACF,OAAO,MAAwD,CAAC;AAClE,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAI,MAAc,CAAC;IACnB,IAAI,cAAsB,CAAC;IAE3B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC1D,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC5C,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC5D,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB;YACrE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa;QAC1F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,MAAM,OAAO,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAiD,CAAC;YACvF,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC7E,MAAM,UAAU,GAAG,EAAE,SAAS,EAAE,SAAS,EAAiD,CAAC;YAC3F,MAAM,CAAC,qBAAqB,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3E,MAAM,IAAI,GAAG,EAAiD,CAAC;YAC/D,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9B,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACnD,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;YAC7C,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;YAC3D,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YACzD,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YACjD,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;YAC9C,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC;YAE7C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3D,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;YACtC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE;gBACzD,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK;gBAC7C,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBAC1B,SAAS,EAAE,YAAY;aACxB,CAAC,CAAC;YACH,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEjC,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAC9E,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3F,MAAM,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE;gBAC1C,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,OAAgB;gBAClE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACrD,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;aAC9C,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC3C,MAAM,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,MAAM,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YACxD,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9D,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;YACpE,MAAM,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YAC9D,MAAM,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAE5E,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;gBACtC,YAAY,EAAE,OAAO;gBACrB,YAAY,EAAE,MAAM;gBACpB,YAAY,EAAE,IAAI;gBAClB,eAAe,EAAE,IAAI;gBACrB,eAAe;gBACf,aAAa,EAAE,CAAC,OAAO,CAAC;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC;gBACxE,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,MAAM;gBACnB,IAAI,EAAE,IAAI;gBACV,KAAK,EAAE,KAAK;gBACZ,SAAS,EAAE,YAAY;aACxB,CAAC,CAAC,CAAC;YACJ,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAC7E,iFAAiF;YACjF,MAAM,UAAU,GAAI,MAAM,CAAC,gBAA6C,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1G,MAAM,WAAW,GAAI,MAAM,CAAC,aAA0C,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxG,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAC/C,MAAM,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC,CAChE,CAAC;YACF,8EAA8E;YAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACvG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1G,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/G,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;YACtC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACxE,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEjC,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;gBACtC,YAAY,EAAE,OAAO;gBACrB,YAAY,EAAE,MAAM;gBACpB,eAAe,EAAE,UAAU;gBAC3B,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;gBACnC,aAAa,EAAE,EAAE;aAClB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YACpD,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,EAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YACtG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC7E,MAAM,IAAI,GAAG;gBACX,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,0BAA0B;gBACrC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;gBAClD,KAAK,EAAE,EAAE;aACV,CAAC;YACF,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG;gBACf,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;gBACnC,aAAa,EAAE,EAAE;aAClB,CAAC;YAEF,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAC;YAC5C,MAAM,mBAAmB,CAAC,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,CAAC;YAC9F,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAE3F,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAC;YAC5C,MAAM,mBAAmB,CAAC;gBACxB,GAAG,QAAQ;gBACX,YAAY,EAAE,OAAO;gBACrB,YAAY,EAAE,YAAY;gBAC1B,eAAe,EAAE,UAAU;aAC5B,CAAC,CAAC;YACH,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,EAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;YACvG,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;YACrD,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,oBAAoB,CAAC;gBAClC,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,IAA6B,EAAE,EAAE,CAAC,CAAC;oBAC7D,GAAG,IAAI;oBACP,EAAE,EAAE,WAAW,CAAC,UAAU,EAAE,CAAC,IAAI,oBAAoB;iBACtD,CAAC,CAAC;aACJ,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEjC,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9F,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YACjH,wEAAwE;YACxE,KAAK,CAAC,UAAU,GAAG;gBACjB,EAAE,IAAI,EAAE,mBAA4B,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;gBACxI,EAAE,IAAI,EAAE,mBAA4B,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;aAClJ,CAAC;YACF,gFAAgF;YAChF,MAAM,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACxC,yFAAyF;YACzF,MAAM,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE;gBACxC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,OAAgB;gBACxE,KAAK,EAAE;oBACL,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE;oBAClD,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,mBAA4B,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE;iBACtG;gBACD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnF,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;aAC9C,CAAC,CAAC;YACH,yEAAyE;YACzE,MAAM,UAAU,GAAG,CAAC,MAAM,cAAc,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAE,CAAC;YAChE,MAAM,WAAW,GAAG,CAAC,MAAM,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAE,CAAC;YAElE,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;gBACtC,YAAY,EAAE,OAAO;gBACrB,YAAY,EAAE,MAAM;gBACpB,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,IAAI;gBACrB,eAAe,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;gBACnC,aAAa,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC;aACzC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvC,iEAAiE;YACjE,MAAM,MAAM,GAAI,MAAM,CAAC,aAA0C,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAA4B,CAAC,CAAC;YACzH,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAErC,+CAA+C;YAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACjD,6DAA6D;YAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC,UAAiD,CAAC;YAC1E,MAAM,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YACtC,gFAAgF;YAChF,MAAM,aAAa,GAAI,MAAM,CAAC,CAAC,CAAE,CAAC,QAAqF,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAClI,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAE,CAAC;YAC3E,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACpD,MAAM,CAAE,MAAM,CAAC,CAAC,CAAE,CAAC,QAAkD,CAAC,CAAC,CAAE,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpG,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;YACpF,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;YACtC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;YAC5E,MAAM,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEjC,MAAM,MAAM,CAAC,mBAAmB,CAAC;gBAC/B,YAAY,EAAE,OAAO;gBACrB,YAAY,EAAE,MAAM;gBACpB,YAAY,EAAE,IAAI;gBAClB,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;gBAC9C,aAAa,EAAE,EAAE;aAClB,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC7E,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;YACtC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAE9E,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC;gBACrC,eAAe,EAAE,UAAU;gBAC3B,YAAY,EAAE,MAAM;gBACpB,iBAAiB,EAAE,YAAY;gBAC/B,mBAAmB,EAAE,cAAc;gBACnC,YAAY,EAAE,IAAI;gBAClB,eAAe,EAAE,IAAI;gBACrB,mBAAmB,EAAE,cAAc;aACpC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B;YAEjE,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC9D,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAClD,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAEvD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YACnF,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;YAE3G,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;YAC5F,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC;YAClE,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,MAAM,GAAG,oBAAoB,CAAC;gBAClC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC;oBACxB,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE;oBACtC,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE;iBAC5C;aACF,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAE9E,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC;gBACrC,eAAe,EAAE,UAAU;gBAC3B,YAAY,EAAE,MAAM;gBACpB,iBAAiB,EAAE,YAAY;gBAC/B,mBAAmB,EAAE,cAAc;gBACnC,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,IAAI;gBACrB,mBAAmB,EAAE,cAAc;aACpC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;YACvG,MAAM,gBAAgB,GAA4C;gBAChE,WAAW,EAAE;oBACX,KAAK,EAAE,QAAQ;oBACf,MAAM,EAAE,OAAO;oBACf,aAAa,EAAE,MAAM;oBACrB,QAAQ,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE;oBAC9B,QAAQ,EAAE;wBACR,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,0BAA0B,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;qBAC5M;oBACD,KAAK,EAAE,EAAE;oBACT,YAAY,EAAE,EAAE;oBAChB,UAAU,EAAE,EAAE;oBACd,WAAW,EAAE,EAAE;iBAChB;gBACD,UAAU,EAAE;oBACV,KAAK,EAAE,OAAO;oBACd,MAAM,EAAE,OAAO;oBACf,aAAa,EAAE,MAAM;oBACrB,QAAQ,EAAE,WAAW;oBACrB,QAAQ,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE;oBAC9B,QAAQ,EAAE;wBACR,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,0BAA0B,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;qBAClN;oBACD,KAAK,EAAE,EAAE;oBACT,YAAY,EAAE,EAAE;oBAChB,UAAU,EAAE;wBACV,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE;wBACnI,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE;qBAC3I;oBACD,WAAW,EAAE,EAAE;iBAChB;aACF,CAAC;YACF,MAAM,MAAM,GAAG,oBAAoB,CAAC;gBAClC,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC;oBACxB,EAAE,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;oBAC3C,EAAE,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE;iBAC3C;gBACD,aAAa,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;aACvE,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YAE9E,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC;gBACrC,eAAe,EAAE,UAAU;gBAC3B,YAAY,EAAE,MAAM;gBACpB,iBAAiB,EAAE,YAAY;gBAC/B,mBAAmB,EAAE,cAAc;gBACnC,YAAY,EAAE,KAAK;gBACnB,eAAe,EAAE,IAAI;gBACrB,mBAAmB,EAAE,cAAc;aACpC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAE,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YAE5B,kDAAkD;YAClD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvC,gEAAgE;YAChE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** Источник сущности в гибридном режиме. */
2
+ export type Origin = 'local' | 'remote';
3
+ /** Способ аутентификации локального core к удалённому backend. */
4
+ export type RemoteAuthType = 'device' | 'api_key';
5
+ /** Пользователь удалённого backend (подмножество /auth/status.user). */
6
+ export interface RemoteUser {
7
+ id: string;
8
+ username: string;
9
+ roles: string[];
10
+ }
11
+ /**
12
+ * Учётные данные для подключения к удалённому backend.
13
+ * Хранятся в файле credentials как Record<backendUrl, RemoteCredentials>.
14
+ */
15
+ export interface RemoteCredentials {
16
+ backendUrl: string;
17
+ accessToken: string;
18
+ refreshToken?: string;
19
+ expiresAt?: string;
20
+ user?: RemoteUser;
21
+ }
22
+ /** Код ошибки remote-клиента: OFFLINE (сеть/таймаут), UNAUTHORIZED (401), AUTH (device flow), HTTP_<status>. */
23
+ export type RemoteErrorCode = 'OFFLINE' | 'UNAUTHORIZED' | 'AUTH' | `HTTP_${number}`;
24
+ export declare class RemoteError extends Error {
25
+ readonly code: RemoteErrorCode;
26
+ constructor(message: string, code: RemoteErrorCode);
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/remote/types.ts"],"names":[],"mappings":"AAEA,4CAA4C;AAC5C,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExC,kEAAkE;AAClE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElD,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,gHAAgH;AAChH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,MAAM,EAAE,CAAC;AAErF,qBAAa,WAAY,SAAQ,KAAK;aAGlB,IAAI,EAAE,eAAe;gBADrC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,eAAe;CAKxC"}
@@ -0,0 +1,10 @@
1
+ // Типы гибридного режима: источник сущности, учётные данные, ошибки remote-клиента.
2
+ export class RemoteError extends Error {
3
+ code;
4
+ constructor(message, code) {
5
+ super(message);
6
+ this.code = code;
7
+ this.name = 'RemoteError';
8
+ }
9
+ }
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/remote/types.ts"],"names":[],"mappings":"AAAA,oFAAoF;AA8BpF,MAAM,OAAO,WAAY,SAAQ,KAAK;IAGlB;IAFlB,YACE,OAAe,EACC,IAAqB;QAErC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAiB;QAGrC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF"}
@@ -1,7 +1,11 @@
1
1
  import { IncomingMessage } from 'node:http';
2
2
  import { WebSocket } from 'ws';
3
3
  import { Hono } from 'hono';
4
- import type { PermissionConfig, PlanMode, McpServerConfig, SecurityConfig, LLMGatewayConfig } from '@itphx/synth-shared';
4
+ import type { ProviderConfig, ModelConfig, PermissionConfig, PlanMode, McpServerConfig, SecurityConfig, LLMGatewayConfig } from '@itphx/synth-shared';
5
+ import { EventBus } from '../index.js';
6
+ import { RemoteConnection } from '../remote/connection.js';
7
+ import type { RemoteUser } from '../remote/types.js';
8
+ import { RemoteEventBridge } from '../remote/event-bridge.js';
5
9
  export interface StandaloneConfig {
6
10
  port: number;
7
11
  dataDir: string;
@@ -21,11 +25,68 @@ export interface StandaloneConfig {
21
25
  gatewayConfig?: LLMGatewayConfig;
22
26
  /** Конфигурация MCP-серверов из config.yaml mcp.servers (для probe и загрузки тулов). */
23
27
  mcpServers?: Record<string, McpServerConfig>;
28
+ /**
29
+ * Дефолтный адрес удалённого backend (гибрид, `serve --connect`/env/конфиг).
30
+ * Нужен для авто-логина (GET /auth/status) и POST /auth/login без поля server.
31
+ * Сам сервер при этом стартует «холодным»: подключение происходит в рантайме.
32
+ */
33
+ defaultBackendUrl?: string;
34
+ /** API-ключ к удалённому backend (`serve --token`) — машинное подключение при старте. */
35
+ defaultToken?: string;
36
+ /**
37
+ * Параметры remote-аутентификации (гибрид): нужны RemoteConnection как
38
+ * fallback OIDC issuer/client_id (дискавери с сервера имеет приоритет) и
39
+ * путь к credentials. backendUrl больше НЕ передаётся — адрес сервера в
40
+ * defaultBackendUrl.
41
+ */
42
+ remoteAuth?: {
43
+ issuer?: string;
44
+ clientId?: string;
45
+ credentialsPath?: string;
46
+ };
47
+ /** Куда идут LLM-запросы локальных сессий: server (централизация) | local | auto. */
48
+ remoteLlm?: 'server' | 'local' | 'auto';
49
+ /** Таймаут запросов к удалённому backend (мс). */
50
+ remoteTimeoutMs?: number;
51
+ /** Путь к файлу credentials (~/.config/synth/credentials.json по умолчанию). */
52
+ remoteCredentialsPath?: string;
24
53
  }
54
+ /** Описание одного remote-зеркала серверного провайдера для инъекции в кэши. */
55
+ export interface RemoteProviderSpec {
56
+ /** Конфиг провайдера: { name: 'itphx', type: 'remote', baseUrl: backendUrl, apiKey: '', enabled: true }. */
57
+ provider: ProviderConfig;
58
+ /** Модели, которые сервер отдаёт для этого провайдера (смерживаются в models-роут). */
59
+ models?: ModelConfig[];
60
+ /** Поставщик токена (обычно RemoteConnection.getToken) — автообновление в рантайме. */
61
+ getToken?: () => Promise<string | null>;
62
+ }
63
+ /**
64
+ * Инъекция одного remote-зеркала в кэши (гибрид: зеркалирование серверных
65
+ * провайдеров). Добавляет провайдера в providerCache и его модели в modelCache —
66
+ * только in-memory, в JsonStore не пишется. Регистрирует поставщика токена для
67
+ * RemoteProvider, создаваемых через ProviderFactory. Возвращает имя
68
+ * remote-провайдера (для политики blockLocalProviders) или undefined.
69
+ */
70
+ export declare function injectRemoteProvider(providerCache: Map<string, ProviderConfig>, modelCache: Map<string, ModelConfig>, remoteProvider?: RemoteProviderSpec): string | undefined;
25
71
  export declare function createStandaloneApp(config: StandaloneConfig): Promise<{
26
72
  app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
27
73
  server: import("http").Server<typeof IncomingMessage, typeof import("http").ServerResponse>;
28
74
  wss: import("ws").Server<typeof WebSocket, typeof IncomingMessage>;
29
75
  port: number;
76
+ connection: RemoteConnection;
77
+ connectRemote: (serverUrl: string, username: string, password: string) => Promise<RemoteUser>;
78
+ connectRemoteFromSaved: (backendUrl?: string) => Promise<RemoteUser | null>;
79
+ connectRemoteWithApiKey: (serverUrl: string, apiKey: string) => Promise<RemoteUser>;
80
+ disconnectRemote: () => Promise<void>;
81
+ getHybridStatus: () => {
82
+ enabled: boolean;
83
+ connected: boolean;
84
+ backendUrl: string | null;
85
+ user: RemoteUser | null;
86
+ serverConfigured: boolean;
87
+ serverLoginAvailable: boolean;
88
+ };
89
+ eventBus: EventBus;
90
+ readonly remoteEventBridge: RemoteEventBridge | undefined;
30
91
  }>;
31
92
  //# sourceMappingURL=app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAmB,SAAS,EAAE,MAAM,IAAI,CAAC;AAKhD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAyD,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA2BhL,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,gFAAgF;IAChF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,yEAAyE;IACzE,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC9C;AA+GD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB;;;;;GA+fjE"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAmB,SAAS,EAAE,MAAM,IAAI,CAAC;AAKhD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAA4B,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChL,OAAO,EACsB,QAAQ,EAIpC,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAuB9D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,gFAAgF;IAChF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,yEAAyE;IACzE,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,qFAAqF;IACrF,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACxC,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAuHD,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,4GAA4G;IAC5G,QAAQ,EAAE,cAAc,CAAC;IACzB,uFAAuF;IACvF,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACzC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EAC1C,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,cAAc,CAAC,EAAE,kBAAkB,GAClC,MAAM,GAAG,SAAS,CAYpB;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB;;;;;;+BA0LxB,MAAM,YAAY,MAAM,YAAY,MAAM,KAAG,OAAO,CAAC,UAAU,CAAC;0CAKrD,MAAM,KAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;yCAMpC,MAAM,UAAU,MAAM,KAAG,OAAO,CAAC,UAAU,CAAC;4BAnB3D,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;gCAqpBrB,iBAAiB,GAAG,SAAS;GAIzD"}