coding-config 1.0.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 (66) hide show
  1. package/README.md +194 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +70 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/config.d.ts +21 -0
  7. package/dist/commands/config.d.ts.map +1 -0
  8. package/dist/commands/config.js +212 -0
  9. package/dist/commands/config.js.map +1 -0
  10. package/dist/commands/install.d.ts +5 -0
  11. package/dist/commands/install.d.ts.map +1 -0
  12. package/dist/commands/install.js +197 -0
  13. package/dist/commands/install.js.map +1 -0
  14. package/dist/commands/publish.d.ts +5 -0
  15. package/dist/commands/publish.d.ts.map +1 -0
  16. package/dist/commands/publish.js +172 -0
  17. package/dist/commands/publish.js.map +1 -0
  18. package/dist/commands/register.d.ts +5 -0
  19. package/dist/commands/register.d.ts.map +1 -0
  20. package/dist/commands/register.js +110 -0
  21. package/dist/commands/register.js.map +1 -0
  22. package/dist/commands/status.d.ts +5 -0
  23. package/dist/commands/status.d.ts.map +1 -0
  24. package/dist/commands/status.js +73 -0
  25. package/dist/commands/status.js.map +1 -0
  26. package/dist/constants.d.ts +32 -0
  27. package/dist/constants.d.ts.map +1 -0
  28. package/dist/constants.js +70 -0
  29. package/dist/constants.js.map +1 -0
  30. package/dist/index.d.ts +14 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +39 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/types/index.d.ts +85 -0
  35. package/dist/types/index.d.ts.map +1 -0
  36. package/dist/types/index.js +14 -0
  37. package/dist/types/index.js.map +1 -0
  38. package/dist/utils/config.d.ts +50 -0
  39. package/dist/utils/config.d.ts.map +1 -0
  40. package/dist/utils/config.js +166 -0
  41. package/dist/utils/config.js.map +1 -0
  42. package/dist/utils/conflict.d.ts +25 -0
  43. package/dist/utils/conflict.d.ts.map +1 -0
  44. package/dist/utils/conflict.js +183 -0
  45. package/dist/utils/conflict.js.map +1 -0
  46. package/dist/utils/diff.d.ts +8 -0
  47. package/dist/utils/diff.d.ts.map +1 -0
  48. package/dist/utils/diff.js +152 -0
  49. package/dist/utils/diff.js.map +1 -0
  50. package/dist/utils/git.d.ts +73 -0
  51. package/dist/utils/git.d.ts.map +1 -0
  52. package/dist/utils/git.js +259 -0
  53. package/dist/utils/git.js.map +1 -0
  54. package/dist/utils/merge.d.ts +21 -0
  55. package/dist/utils/merge.d.ts.map +1 -0
  56. package/dist/utils/merge.js +273 -0
  57. package/dist/utils/merge.js.map +1 -0
  58. package/dist/utils/prompt.d.ts +27 -0
  59. package/dist/utils/prompt.d.ts.map +1 -0
  60. package/dist/utils/prompt.js +183 -0
  61. package/dist/utils/prompt.js.map +1 -0
  62. package/dist/utils/sync-record.d.ts +30 -0
  63. package/dist/utils/sync-record.d.ts.map +1 -0
  64. package/dist/utils/sync-record.js +151 -0
  65. package/dist/utils/sync-record.js.map +1 -0
  66. package/package.json +47 -0
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.detectConflicts = detectConflicts;
40
+ exports.copyDir = copyDir;
41
+ exports.deleteFile = deleteFile;
42
+ exports.copyFile = copyFile;
43
+ const fs = __importStar(require("fs-extra"));
44
+ const path = __importStar(require("path"));
45
+ const trash_1 = __importDefault(require("trash"));
46
+ const types_1 = require("../types");
47
+ const sync_record_1 = require("./sync-record");
48
+ /**
49
+ * 获取目录下所有文件(递归)
50
+ */
51
+ async function getAllFiles(dir, baseDir) {
52
+ if (!baseDir) {
53
+ baseDir = dir;
54
+ }
55
+ const entries = await fs.readdir(dir, { withFileTypes: true });
56
+ const files = [];
57
+ for (const entry of entries) {
58
+ const fullPath = path.join(dir, entry.name);
59
+ if (entry.isDirectory()) {
60
+ const subFiles = await getAllFiles(fullPath, baseDir);
61
+ files.push(...subFiles);
62
+ }
63
+ else {
64
+ files.push(path.relative(baseDir, fullPath));
65
+ }
66
+ }
67
+ return files;
68
+ }
69
+ /**
70
+ * 比较两个文件是否相同
71
+ */
72
+ async function filesEqual(file1, file2) {
73
+ const [stat1Exists, stat2Exists] = await Promise.all([
74
+ fs.pathExists(file1),
75
+ fs.pathExists(file2),
76
+ ]);
77
+ if (!stat1Exists || !stat2Exists) {
78
+ return false;
79
+ }
80
+ const [content1, content2] = await Promise.all([
81
+ fs.readFile(file1, 'utf-8'),
82
+ fs.readFile(file2, 'utf-8'),
83
+ ]);
84
+ return content1 === content2;
85
+ }
86
+ /**
87
+ * 检测文件冲突
88
+ * 使用同步记录来判断文件是否为远程删除
89
+ * @param localDir 本地目录
90
+ * @param remoteDir 远程目录
91
+ * @param targetPath 目标同步路径(如 ~/.claude 或 /project/.claude)
92
+ * @param configDir 配置目录名称(如 'agents', 'commands' 等)
93
+ */
94
+ async function detectConflicts(localDir, remoteDir, targetPath, configDir) {
95
+ const conflicts = [];
96
+ // 获取远程和本地的所有文件
97
+ const [remoteFiles, localFilesExists, syncedFiles] = await Promise.all([
98
+ getAllFiles(remoteDir),
99
+ fs.pathExists(localDir),
100
+ (0, sync_record_1.getSyncedFiles)(targetPath),
101
+ ]);
102
+ const localFiles = localFilesExists ? await getAllFiles(localDir) : [];
103
+ // 检查远程文件
104
+ for (const file of remoteFiles) {
105
+ const remotePath = path.join(remoteDir, file);
106
+ const localPath = path.join(localDir, file);
107
+ const localExists = await fs.pathExists(localPath);
108
+ if (!localExists) {
109
+ // 远程有,本地没有 - 正常新增,不算冲突
110
+ continue;
111
+ }
112
+ // 检查文件是否相同
113
+ const equal = await filesEqual(localPath, remotePath);
114
+ if (!equal) {
115
+ // 远程和本地都有,但内容不同 - 冲突
116
+ conflicts.push({
117
+ file,
118
+ type: types_1.ConflictType.BothModified,
119
+ localPath,
120
+ remotePath,
121
+ });
122
+ }
123
+ }
124
+ // 检查本地文件是否为远程删除
125
+ // 只有在同步记录中的文件,如果远程没有了,才认为是远程删除
126
+ const remoteFileSet = new Set(remoteFiles);
127
+ const syncedFileSet = new Set(syncedFiles);
128
+ for (const file of localFiles) {
129
+ // 构建完整路径用于匹配同步记录
130
+ const fullPath = configDir ? path.join(configDir, file) : file;
131
+ if (!remoteFileSet.has(file) && syncedFileSet.has(fullPath)) {
132
+ // 本地有、远程没有、且在同步记录中 - 远程删除
133
+ const localPath = path.join(localDir, file);
134
+ conflicts.push({
135
+ file,
136
+ type: types_1.ConflictType.RemoteDeleted,
137
+ localPath,
138
+ remotePath: '',
139
+ });
140
+ }
141
+ }
142
+ return conflicts;
143
+ }
144
+ /**
145
+ * 复制目录(递归)
146
+ */
147
+ async function copyDir(src, dest) {
148
+ await fs.copy(src, dest, {
149
+ overwrite: true,
150
+ });
151
+ }
152
+ /**
153
+ * 删除文件(移到废纸篓/回收站)
154
+ * @param filePath 要删除的文件路径
155
+ * @param useTrash 是否使用废纸篓(默认为 true)
156
+ */
157
+ async function deleteFile(filePath, useTrash = true) {
158
+ if (!(await fs.pathExists(filePath))) {
159
+ return;
160
+ }
161
+ try {
162
+ if (useTrash) {
163
+ // 移动到废纸篓
164
+ await (0, trash_1.default)(filePath);
165
+ }
166
+ else {
167
+ // 永久删除
168
+ await fs.remove(filePath);
169
+ }
170
+ }
171
+ catch (error) {
172
+ console.error(`删除文件失败 ${filePath}:`, error);
173
+ throw error;
174
+ }
175
+ }
176
+ /**
177
+ * 复制单个文件
178
+ */
179
+ async function copyFile(src, dest) {
180
+ await fs.ensureDir(path.dirname(dest));
181
+ await fs.copyFile(src, dest);
182
+ }
183
+ //# sourceMappingURL=conflict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict.js","sourceRoot":"","sources":["../../src/utils/conflict.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 展示两个文件的差异(重点展示第一个冲突位置)
3
+ * @param localPath 本地文件路径
4
+ * @param remotePath 远程文件路径
5
+ * @param fileName 文件名(用于显示)
6
+ */
7
+ export declare function showFileDiff(localPath: string, remotePath: string, fileName: string): Promise<void>;
8
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAqEA;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAsEf"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.showFileDiff = showFileDiff;
40
+ const fs = __importStar(require("fs-extra"));
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ /**
43
+ * 查找冲突位置
44
+ */
45
+ function findConflicts(localLines, remoteLines) {
46
+ const conflicts = [];
47
+ let i = 0;
48
+ let j = 0;
49
+ while (i < localLines.length || j < remoteLines.length) {
50
+ // 如果两行相同,继续
51
+ if (i < localLines.length && j < remoteLines.length && localLines[i] === remoteLines[j]) {
52
+ i++;
53
+ j++;
54
+ continue;
55
+ }
56
+ // 找到不同的地方
57
+ const startLine = Math.min(i, j);
58
+ let endLine = startLine;
59
+ // 向前查找匹配点
60
+ let foundMatch = false;
61
+ const lookAhead = 5;
62
+ for (let k = 1; k <= lookAhead; k++) {
63
+ if (i + k < localLines.length && j + k < remoteLines.length) {
64
+ if (localLines[i + k] === remoteLines[j + k]) {
65
+ endLine = Math.max(i + k - 1, j + k - 1);
66
+ i = i + k;
67
+ j = j + k;
68
+ foundMatch = true;
69
+ break;
70
+ }
71
+ }
72
+ }
73
+ if (!foundMatch) {
74
+ // 没找到匹配,这是一个较大的冲突
75
+ const maxAdvance = Math.min(lookAhead, Math.max(localLines.length - i, remoteLines.length - j));
76
+ endLine = startLine + maxAdvance - 1;
77
+ i += maxAdvance;
78
+ j += maxAdvance;
79
+ }
80
+ conflicts.push({
81
+ startLine: startLine + 1, // 1-based
82
+ endLine: endLine + 1,
83
+ type: 'different'
84
+ });
85
+ if (i >= localLines.length && j >= remoteLines.length)
86
+ break;
87
+ }
88
+ return conflicts;
89
+ }
90
+ /**
91
+ * 展示两个文件的差异(重点展示第一个冲突位置)
92
+ * @param localPath 本地文件路径
93
+ * @param remotePath 远程文件路径
94
+ * @param fileName 文件名(用于显示)
95
+ */
96
+ async function showFileDiff(localPath, remotePath, fileName) {
97
+ const [localContent, remoteContent] = await Promise.all([
98
+ fs.readFile(localPath, 'utf-8'),
99
+ fs.readFile(remotePath, 'utf-8'),
100
+ ]);
101
+ const localLines = localContent.split('\n');
102
+ const remoteLines = remoteContent.split('\n');
103
+ // 查找冲突位置
104
+ const conflicts = findConflicts(localLines, remoteLines);
105
+ console.log(chalk_1.default.cyan(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`));
106
+ console.log(chalk_1.default.cyan(` 文件差异: ${fileName}`));
107
+ console.log(chalk_1.default.cyan(` 发现 ${conflicts.length} 个冲突位置`));
108
+ console.log(chalk_1.default.cyan(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`));
109
+ if (conflicts.length === 0) {
110
+ console.log(chalk_1.default.green('✓ 文件内容相同,无冲突'));
111
+ return;
112
+ }
113
+ // 显示文件长度信息
114
+ console.log(chalk_1.default.gray(`本地版本: ${localLines.length} 行`));
115
+ console.log(chalk_1.default.gray(`远程版本: ${remoteLines.length} 行\n`));
116
+ // 展示所有冲突位置(前后各显示3行上下文)
117
+ const contextLines = 3;
118
+ conflicts.forEach((conflict, index) => {
119
+ const showStart = Math.max(0, conflict.startLine - 1 - contextLines);
120
+ const showEnd = Math.min(Math.max(localLines.length, remoteLines.length), conflict.endLine + contextLines);
121
+ console.log(chalk_1.default.yellow(`\n冲突 ${index + 1}/${conflicts.length} (第 ${conflict.startLine}-${conflict.endLine} 行):\n`));
122
+ console.log(chalk_1.default.bold('本地版本:'));
123
+ console.log(chalk_1.default.green('─'.repeat(60)));
124
+ for (let i = showStart; i < showEnd && i < localLines.length; i++) {
125
+ const line = localLines[i];
126
+ const lineNum = i + 1;
127
+ const isConflict = lineNum >= conflict.startLine && lineNum <= conflict.endLine;
128
+ if (isConflict) {
129
+ console.log(chalk_1.default.green(`${String(lineNum).padStart(3, ' ')} | ${line}`));
130
+ }
131
+ else {
132
+ console.log(chalk_1.default.gray(`${String(lineNum).padStart(3, ' ')} | ${line}`));
133
+ }
134
+ }
135
+ console.log(chalk_1.default.bold('\n远程版本:'));
136
+ console.log(chalk_1.default.blue('─'.repeat(60)));
137
+ for (let i = showStart; i < showEnd && i < remoteLines.length; i++) {
138
+ const line = remoteLines[i];
139
+ const lineNum = i + 1;
140
+ const isConflict = lineNum >= conflict.startLine && lineNum <= conflict.endLine;
141
+ if (isConflict) {
142
+ console.log(chalk_1.default.blue(`${String(lineNum).padStart(3, ' ')} | ${line}`));
143
+ }
144
+ else {
145
+ console.log(chalk_1.default.gray(`${String(lineNum).padStart(3, ' ')} | ${line}`));
146
+ }
147
+ }
148
+ console.log(''); // 空行分隔不同的冲突
149
+ });
150
+ console.log(chalk_1.default.cyan(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`));
151
+ }
152
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { SimpleGit } from 'simple-git';
2
+ /**
3
+ * 创建临时目录
4
+ */
5
+ export declare function createTempDir(): string;
6
+ /**
7
+ * 清理临时目录
8
+ */
9
+ export declare function cleanupTempDir(tempDir: string): Promise<void>;
10
+ /**
11
+ * 克隆仓库到指定目录
12
+ * 如果是本地路径,直接复制文件;否则使用 git clone
13
+ */
14
+ export declare function cloneRepo(repoUrl: string, localPath: string): Promise<SimpleGit>;
15
+ /**
16
+ * 拉取最新代码
17
+ */
18
+ export declare function pullRepo(localPath: string, branch?: string): Promise<void>;
19
+ /**
20
+ * 检查团队目录是否存在
21
+ */
22
+ export declare function checkTeamExists(repoPath: string, teamName: string): Promise<boolean>;
23
+ /**
24
+ * 获取所有团队列表
25
+ */
26
+ export declare function listTeams(repoPath: string): Promise<string[]>;
27
+ /**
28
+ * 判断是否为 GitHub 仓库
29
+ */
30
+ export declare function isGithubRepo(repoUrl: string): boolean;
31
+ /**
32
+ * 判断是否为 Gerrit/iCode 仓库
33
+ */
34
+ export declare function isGerritRepo(repoUrl: string): boolean;
35
+ /**
36
+ * 创建新分支并切换
37
+ */
38
+ export declare function createBranch(localPath: string, branchName: string): Promise<void>;
39
+ /**
40
+ * 生成 Gerrit Change-Id
41
+ * Change-Id 格式: I + 40位十六进制字符
42
+ */
43
+ export declare function generateChangeId(): string;
44
+ /**
45
+ * 提交变更
46
+ * 如果是 Gerrit 仓库,会自动添加 Change-Id 和 CardID
47
+ */
48
+ export declare function commitChanges(localPath: string, message: string, repoUrl?: string, cardId?: string): Promise<void>;
49
+ /**
50
+ * 推送到远程
51
+ */
52
+ export declare function pushToRemote(localPath: string, branchName: string): Promise<void>;
53
+ /**
54
+ * 推送到远程用于 Code Review (Gerrit 风格)
55
+ * 使用 refs/for/<branch> 格式发起 CR
56
+ */
57
+ export declare function pushForReview(localPath: string, targetBranch?: string): Promise<void>;
58
+ /**
59
+ * 解析 GitHub 仓库信息
60
+ */
61
+ export declare function parseGithubRepo(repoUrl: string): {
62
+ owner: string;
63
+ repo: string;
64
+ } | null;
65
+ /**
66
+ * 创建 Pull Request
67
+ */
68
+ export declare function createPullRequest(repoUrl: string, branchName: string, title: string, body: string, token: string): Promise<string>;
69
+ /**
70
+ * 创建团队目录结构
71
+ */
72
+ export declare function createTeamDirectory(repoPath: string, teamName: string): Promise<void>;
73
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQlD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAInE;AASD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAsBtF;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,MAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhG;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG1F;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKnE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIrD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAQzC;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,YAAY,GAAE,MAAuB,GACpC,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASvF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe3F"}