@kkkwww/deploy 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +105 -172
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -14,151 +14,96 @@ import os from 'os';
|
|
|
14
14
|
import SftpClient from 'ssh2-sftp-client';
|
|
15
15
|
import { fileURLToPath } from 'url';
|
|
16
16
|
// ==========================
|
|
17
|
-
// ESM 兼容 __dirname
|
|
18
|
-
// ==========================
|
|
19
17
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
18
|
const __dirname = path.dirname(__filename);
|
|
21
19
|
// ==========================
|
|
22
|
-
// 读取 package.json 版本号
|
|
23
|
-
// ==========================
|
|
24
|
-
let VERSION = '0.0.0';
|
|
25
|
-
try {
|
|
26
|
-
const pkgPath = path.resolve(__dirname, '../package.json');
|
|
27
|
-
if (fs.existsSync(pkgPath)) {
|
|
28
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
29
|
-
VERSION = pkg.version || '0.0.0';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
catch (e) { }
|
|
33
|
-
// ==========================
|
|
34
|
-
// 多线程配置
|
|
35
|
-
// ==========================
|
|
36
20
|
const CONCURRENCY = 5;
|
|
37
|
-
// ==========================
|
|
38
|
-
// 缓存文件
|
|
39
|
-
// ==========================
|
|
40
21
|
const CACHE_FILE = path.join(os.homedir(), '.deploy-cache.json');
|
|
41
|
-
const SKIP_LOG_FILE = path.join(os.homedir(), '.deploy-skip.log');
|
|
42
|
-
// ==========================
|
|
43
|
-
// 解析命令行
|
|
22
|
+
const SKIP_LOG_FILE = path.join(os.homedir(), '.deploy-skip.log');
|
|
44
23
|
// ==========================
|
|
45
24
|
function getArgs() {
|
|
46
25
|
const args = {};
|
|
47
26
|
process.argv.slice(2).forEach((arg) => {
|
|
48
27
|
if (arg.startsWith('--')) {
|
|
49
28
|
const [key, ...valArr] = arg.slice(2).split('=');
|
|
50
|
-
args[key] = valArr.join('=');
|
|
29
|
+
args[key] = valArr.join('=') || 'true';
|
|
51
30
|
}
|
|
52
31
|
});
|
|
53
32
|
return args;
|
|
54
33
|
}
|
|
55
34
|
// ==========================
|
|
56
|
-
// 读取缓存
|
|
57
|
-
// ==========================
|
|
58
35
|
function loadCache() {
|
|
59
36
|
try {
|
|
60
37
|
if (fs.existsSync(CACHE_FILE)) {
|
|
61
|
-
|
|
62
|
-
return JSON.parse(data);
|
|
38
|
+
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
|
|
63
39
|
}
|
|
64
40
|
}
|
|
65
|
-
catch (
|
|
41
|
+
catch (_a) { }
|
|
66
42
|
return {};
|
|
67
43
|
}
|
|
68
44
|
// ==========================
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const allCache = loadCache();
|
|
74
|
-
if (config.host) {
|
|
75
|
-
allCache[config.host] = config;
|
|
76
|
-
fs.writeFileSync(CACHE_FILE, JSON.stringify(allCache, null, 2));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch (e) { }
|
|
45
|
+
function saveCache(host, config) {
|
|
46
|
+
const all = loadCache();
|
|
47
|
+
all[host] = config;
|
|
48
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(all, null, 2));
|
|
80
49
|
}
|
|
81
50
|
// ==========================
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
51
|
+
function logSkip(local, remote) {
|
|
52
|
+
const line = `${new Date().toISOString()} ⚡ 跳过 本地: ${local} → 远程: ${remote}\n`;
|
|
53
|
+
fs.appendFileSync(SKIP_LOG_FILE, line);
|
|
54
|
+
console.log(line.trim());
|
|
86
55
|
}
|
|
87
56
|
// ==========================
|
|
88
|
-
|
|
89
|
-
// ==========================
|
|
90
|
-
function isSameFile(sftp, localFile, remoteFile) {
|
|
57
|
+
function isSameFile(sftp, local, remote) {
|
|
91
58
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
59
|
try {
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Math.floor(localStat.mtimeMs / 1000) === Math.floor(remoteStat.modifyTime / 1000)) {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
60
|
+
const l = fs.statSync(local);
|
|
61
|
+
const r = yield sftp.stat(remote);
|
|
62
|
+
return (l.size === r.size &&
|
|
63
|
+
Math.floor(l.mtimeMs / 1000) === Math.floor(r.modifyTime / 1000));
|
|
100
64
|
}
|
|
101
|
-
catch (
|
|
102
|
-
return false;
|
|
65
|
+
catch (_a) {
|
|
66
|
+
return false;
|
|
103
67
|
}
|
|
104
|
-
return false;
|
|
105
68
|
});
|
|
106
69
|
}
|
|
107
70
|
// ==========================
|
|
108
|
-
// 写跳过日志
|
|
109
|
-
// ==========================
|
|
110
|
-
function logSkip(fileName) {
|
|
111
|
-
const logLine = `${new Date().toISOString()} ⚡ 跳过已存在文件:${fileName}\n`;
|
|
112
|
-
fs.appendFileSync(SKIP_LOG_FILE, logLine);
|
|
113
|
-
console.log(logLine.trim());
|
|
114
|
-
}
|
|
115
|
-
// ==========================
|
|
116
|
-
// 确保远程目录存在(逐级创建)
|
|
117
|
-
// ==========================
|
|
118
71
|
function ensureRemoteDir(sftp, remoteDir) {
|
|
119
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
-
const
|
|
121
|
-
let
|
|
122
|
-
for (const
|
|
123
|
-
|
|
73
|
+
const parts = remoteDir.split('/').filter(Boolean);
|
|
74
|
+
let cur = '';
|
|
75
|
+
for (const p of parts) {
|
|
76
|
+
cur += '/' + p;
|
|
124
77
|
try {
|
|
125
|
-
yield sftp.stat(
|
|
78
|
+
yield sftp.stat(cur);
|
|
126
79
|
}
|
|
127
|
-
catch (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
console.log(`📁 创建远程目录:${current}`);
|
|
131
|
-
}
|
|
132
|
-
catch (err) {
|
|
133
|
-
console.error(`❌ 创建目录失败:${current}`, err);
|
|
134
|
-
}
|
|
80
|
+
catch (_a) {
|
|
81
|
+
yield sftp.mkdir(cur);
|
|
82
|
+
console.log(`📁 创建目录:${cur}`);
|
|
135
83
|
}
|
|
136
84
|
}
|
|
137
85
|
});
|
|
138
86
|
}
|
|
139
87
|
// ==========================
|
|
140
|
-
|
|
141
|
-
// ==========================
|
|
142
|
-
function uploadFile(sftp, localFile, remoteFile) {
|
|
88
|
+
function uploadFile(sftp, local, remote) {
|
|
143
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
logSkip(fileName);
|
|
90
|
+
if (yield isSameFile(sftp, local, remote)) {
|
|
91
|
+
logSkip(local, remote);
|
|
147
92
|
return;
|
|
148
93
|
}
|
|
149
|
-
const
|
|
94
|
+
const size = fs.statSync(local).size;
|
|
150
95
|
let uploaded = 0;
|
|
151
|
-
console.log(`\n📤 上传:${
|
|
96
|
+
console.log(`\n📤 上传:${local} → ${remote}`);
|
|
152
97
|
return new Promise((resolve, reject) => {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
uploaded +=
|
|
156
|
-
const pct = ((uploaded /
|
|
157
|
-
process.stdout.write(`
|
|
98
|
+
const rs = fs.createReadStream(local);
|
|
99
|
+
rs.on('data', (c) => {
|
|
100
|
+
uploaded += c.length;
|
|
101
|
+
const pct = ((uploaded / size) * 100).toFixed(1);
|
|
102
|
+
process.stdout.write(` ${pct}% (${uploaded}/${size})\r`);
|
|
158
103
|
});
|
|
159
|
-
sftp.put(
|
|
104
|
+
sftp.put(rs, remote)
|
|
160
105
|
.then(() => {
|
|
161
|
-
console.log(` ✅
|
|
106
|
+
console.log(` ✅ 完成`);
|
|
162
107
|
resolve();
|
|
163
108
|
})
|
|
164
109
|
.catch(reject);
|
|
@@ -166,122 +111,110 @@ function uploadFile(sftp, localFile, remoteFile) {
|
|
|
166
111
|
});
|
|
167
112
|
}
|
|
168
113
|
// ==========================
|
|
169
|
-
|
|
170
|
-
// ==========================
|
|
171
|
-
function uploadWithConcurrency(tasks, concurrency) {
|
|
114
|
+
function uploadWithConcurrency(tasks) {
|
|
172
115
|
return __awaiter(this, void 0, void 0, function* () {
|
|
173
|
-
const
|
|
174
|
-
for (const
|
|
175
|
-
const p =
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
yield Promise.race(
|
|
116
|
+
const pool = new Set();
|
|
117
|
+
for (const t of tasks) {
|
|
118
|
+
const p = t().finally(() => pool.delete(p));
|
|
119
|
+
pool.add(p);
|
|
120
|
+
if (pool.size >= CONCURRENCY) {
|
|
121
|
+
yield Promise.race(pool);
|
|
179
122
|
}
|
|
180
123
|
}
|
|
181
|
-
yield Promise.all(
|
|
124
|
+
yield Promise.all(pool);
|
|
182
125
|
});
|
|
183
126
|
}
|
|
184
127
|
// ==========================
|
|
185
|
-
|
|
186
|
-
// ==========================
|
|
187
|
-
function uploadDirConcurrent(sftp, localDir, remoteDir) {
|
|
128
|
+
function uploadDir(sftp, localDir, remoteDir) {
|
|
188
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
189
130
|
yield ensureRemoteDir(sftp, remoteDir);
|
|
190
|
-
const
|
|
131
|
+
const list = fs.readdirSync(localDir);
|
|
191
132
|
const tasks = [];
|
|
192
|
-
for (const
|
|
193
|
-
const local = path.join(localDir,
|
|
194
|
-
const remote = path.posix.join(remoteDir,
|
|
133
|
+
for (const f of list) {
|
|
134
|
+
const local = path.join(localDir, f);
|
|
135
|
+
const remote = path.posix.join(remoteDir, f);
|
|
195
136
|
const stat = fs.statSync(local);
|
|
196
137
|
if (stat.isDirectory()) {
|
|
197
|
-
yield
|
|
138
|
+
yield uploadDir(sftp, local, remote);
|
|
198
139
|
}
|
|
199
140
|
else {
|
|
200
141
|
tasks.push(() => uploadFile(sftp, local, remote));
|
|
201
142
|
}
|
|
202
143
|
}
|
|
203
|
-
yield uploadWithConcurrency(tasks
|
|
144
|
+
yield uploadWithConcurrency(tasks);
|
|
204
145
|
});
|
|
205
146
|
}
|
|
206
147
|
// ==========================
|
|
207
|
-
// 主逻辑
|
|
208
|
-
// ==========================
|
|
209
148
|
function run() {
|
|
210
149
|
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
const allCache = loadCache();
|
|
223
|
-
const argParams = getArgs();
|
|
224
|
-
console.log('argParams', JSON.stringify(argParams));
|
|
225
|
-
const hostKey = argParams.host || '';
|
|
226
|
-
const lastCache = hostKey ? allCache[hostKey] : {};
|
|
227
|
-
const config = {
|
|
228
|
-
host: argParams.host || lastCache.host,
|
|
229
|
-
port: Number(argParams.port || (lastCache === null || lastCache === void 0 ? void 0 : lastCache.port)) || 22,
|
|
230
|
-
user: argParams.user || (lastCache === null || lastCache === void 0 ? void 0 : lastCache.user),
|
|
231
|
-
password: argParams.password || (lastCache === null || lastCache === void 0 ? void 0 : lastCache.password),
|
|
232
|
-
localPath: argParams.local,
|
|
233
|
-
remotePath: argParams.remote || (lastCache === null || lastCache === void 0 ? void 0 : lastCache.remotePath),
|
|
234
|
-
backup: argParams.backup === 'false' ? false : ((_a = lastCache === null || lastCache === void 0 ? void 0 : lastCache.backup) !== null && _a !== void 0 ? _a : true),
|
|
235
|
-
};
|
|
236
|
-
console.log(config);
|
|
237
|
-
if (!config.host || !config.user || !config.localPath || !config.remotePath) {
|
|
150
|
+
const args = getArgs();
|
|
151
|
+
const host = args.host;
|
|
152
|
+
const port = Number(args.port || 22);
|
|
153
|
+
const user = args.user || args.username;
|
|
154
|
+
const password = args.password;
|
|
155
|
+
const localPath = args.local || args.dir;
|
|
156
|
+
const remotePath = args.remote || args.serverDir;
|
|
157
|
+
const backup = args.backup !== 'false';
|
|
158
|
+
if (!host || !user || !password || !localPath || !remotePath) {
|
|
238
159
|
console.log(`
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
│ 关闭备份:--backup=false
|
|
245
|
-
│ 版本查看:-v / --version
|
|
246
|
-
└───────────────────────────────────────────┘
|
|
247
|
-
`);
|
|
160
|
+
用法:
|
|
161
|
+
--host=IP --user=root --password=xxx
|
|
162
|
+
--local=./dist 或 --dir=./dist
|
|
163
|
+
--remote=/www/app 或 --serverDir=/www/app
|
|
164
|
+
`);
|
|
248
165
|
return;
|
|
249
166
|
}
|
|
167
|
+
const config = { host, port, user, password, localPath, remotePath, backup };
|
|
168
|
+
console.log('配置:\n', config);
|
|
250
169
|
const sftp = new SftpClient();
|
|
251
170
|
try {
|
|
252
|
-
console.log('🔗 连接服务器中...');
|
|
253
171
|
yield sftp.connect(config);
|
|
254
|
-
console.log('✅
|
|
255
|
-
|
|
172
|
+
console.log('✅ 已连接\n');
|
|
173
|
+
// ======================
|
|
174
|
+
// 根目录处理逻辑
|
|
175
|
+
// ======================
|
|
176
|
+
const localAbs = path.resolve(localPath);
|
|
177
|
+
const baseName = path.basename(localAbs);
|
|
178
|
+
const keepRoot = remotePath.endsWith('/');
|
|
179
|
+
const finalRemote = keepRoot
|
|
180
|
+
? path.posix.join(remotePath, baseName)
|
|
181
|
+
: remotePath;
|
|
182
|
+
console.log(keepRoot
|
|
183
|
+
? `📁 保留根目录:${baseName}`
|
|
184
|
+
: `📂 不保留根目录,仅上传内容`);
|
|
185
|
+
console.log(`🚀 ${localAbs} → ${finalRemote}`);
|
|
186
|
+
// ======================
|
|
187
|
+
// 备份
|
|
188
|
+
// ======================
|
|
189
|
+
if (backup) {
|
|
256
190
|
try {
|
|
257
|
-
yield sftp.stat(
|
|
258
|
-
const backupPath =
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
catch (e) {
|
|
263
|
-
console.log('ℹ 远程目录不存在,跳过备份');
|
|
191
|
+
yield sftp.stat(finalRemote);
|
|
192
|
+
const backupPath = finalRemote + '_bak_' + Date.now();
|
|
193
|
+
yield sftp.rename(finalRemote, backupPath);
|
|
194
|
+
console.log(`📦 已备份 → ${backupPath}`);
|
|
264
195
|
}
|
|
196
|
+
catch (_a) { }
|
|
265
197
|
}
|
|
266
|
-
|
|
198
|
+
// ======================
|
|
199
|
+
// 上传
|
|
200
|
+
// ======================
|
|
267
201
|
if (fs.statSync(localAbs).isDirectory()) {
|
|
268
|
-
|
|
269
|
-
yield uploadDirConcurrent(sftp, localAbs, config.remotePath);
|
|
202
|
+
yield uploadDir(sftp, localAbs, finalRemote);
|
|
270
203
|
}
|
|
271
204
|
else {
|
|
272
|
-
yield uploadFile(sftp, localAbs,
|
|
205
|
+
yield uploadFile(sftp, localAbs, finalRemote);
|
|
273
206
|
}
|
|
274
|
-
console.log('\n🎉
|
|
275
|
-
// ✅
|
|
276
|
-
saveCache(config);
|
|
277
|
-
console.log('✅
|
|
207
|
+
console.log('\n🎉 完成');
|
|
208
|
+
// ✅ 最后保存缓存
|
|
209
|
+
saveCache(host, config);
|
|
210
|
+
console.log('✅ 已缓存');
|
|
278
211
|
}
|
|
279
|
-
catch (
|
|
280
|
-
console.error('
|
|
212
|
+
catch (e) {
|
|
213
|
+
console.error('❌ 错误', e.message);
|
|
281
214
|
}
|
|
282
215
|
finally {
|
|
283
216
|
yield sftp.end();
|
|
284
|
-
console.log('🔌
|
|
217
|
+
console.log('🔌 已断开');
|
|
285
218
|
}
|
|
286
219
|
});
|
|
287
220
|
}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,6BAA6B;AAC7B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,6BAA6B;AAC7B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,6BAA6B;AAC7B,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;AACjE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAalE,6BAA6B;AAC7B,SAAS,OAAO;IACZ,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAClC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC;QAC3C,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,6BAA6B;AAC7B,SAAS,SAAS;IACd,IAAI,CAAC;QACD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;IAAC,WAAM,CAAC,CAAA,CAAC;IACV,OAAO,EAAE,CAAC;AACd,CAAC;AAED,6BAA6B;AAC7B,SAAS,SAAS,CAAC,IAAY,EAAE,MAAkB;IAC/C,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACnB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,6BAA6B;AAC7B,SAAS,OAAO,CAAC,KAAa,EAAE,MAAc;IAC1C,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,aAAa,KAAK,UAAU,MAAM,IAAI,CAAC;IAC/E,EAAE,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,6BAA6B;AAC7B,SAAe,UAAU,CAAC,IAAgB,EAAE,KAAa,EAAE,MAAc;;QACrE,IAAI,CAAC;YACD,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAClC,OAAO,CACH,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;gBACjB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,CACnE,CAAC;QACN,CAAC;QAAC,WAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;CAAA;AAED,6BAA6B;AAC7B,SAAe,eAAe,CAAC,IAAgB,EAAE,SAAiB;;QAC9D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACpB,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;YACf,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;YAAC,WAAM,CAAC;gBACL,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;YAClC,CAAC;QACL,CAAC;IACL,CAAC;CAAA;AAED,6BAA6B;AAC7B,SAAe,UAAU,CAAC,IAAgB,EAAE,KAAa,EAAE,MAAc;;QACrE,IAAI,MAAM,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvB,OAAO;QACX,CAAC;QAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;QACrC,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;QAE5C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACzC,MAAM,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACtC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;gBAChB,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC;gBACrB,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC;iBACf,IAAI,CAAC,GAAG,EAAE;gBACP,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC;YACd,CAAC,CAAC;iBACD,KAAK,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACP,CAAC;CAAA;AAED,6BAA6B;AAC7B,SAAe,qBAAqB,CAAC,KAA8B;;QAC/D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAiB,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC3B,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;CAAA;AAED,6BAA6B;AAC7B,SAAe,SAAS,CAAC,IAAgB,EAAE,QAAgB,EAAE,SAAiB;;QAC1E,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEvC,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,KAAK,GAA4B,EAAE,CAAC;QAE1C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAEhC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrB,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACJ,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;YACtD,CAAC;QACL,CAAC;QAED,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;CAAA;AAED,6BAA6B;AAC7B,SAAe,GAAG;;QACd,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QAEvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC;QAEvC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC;;;;;CAKnB,CAAC,CAAC;YACK,OAAO;QACX,CAAC;QAED,MAAM,MAAM,GAAe,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QACzF,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE7B,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAE9B,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,OAAO,CAAC,MAAa,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEvB,yBAAyB;YACzB,UAAU;YACV,yBAAyB;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEzC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,WAAW,GAAG,QAAQ;gBACxB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;gBACvC,CAAC,CAAC,UAAU,CAAC;YAEjB,OAAO,CAAC,GAAG,CACP,QAAQ;gBACJ,CAAC,CAAC,YAAY,QAAQ,EAAE;gBACxB,CAAC,CAAC,iBAAiB,CAC1B,CAAC;YAEF,OAAO,CAAC,GAAG,CAAC,MAAM,QAAQ,MAAM,WAAW,EAAE,CAAC,CAAC;YAE/C,yBAAyB;YACzB,KAAK;YACL,yBAAyB;YACzB,IAAI,MAAM,EAAE,CAAC;gBACT,IAAI,CAAC;oBACD,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBAC7B,MAAM,UAAU,GAAG,WAAW,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACtD,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;oBAC3C,OAAO,CAAC,GAAG,CAAC,YAAY,UAAU,EAAE,CAAC,CAAC;gBAC1C,CAAC;gBAAC,WAAM,CAAC,CAAA,CAAC;YACd,CAAC;YAED,yBAAyB;YACzB,KAAK;YACL,yBAAyB;YACzB,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtC,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACJ,MAAM,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YAClD,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEvB,WAAW;YACX,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEzB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,MAAM,EAAG,CAAW,CAAC,OAAO,CAAC,CAAC;QAChD,CAAC;gBAAS,CAAC;YACP,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;IACL,CAAC;CAAA;AAED,GAAG,EAAE,CAAC"}
|