@ifc-lite/server-bin 1.16.0 → 1.16.1
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/dist/binary.d.ts.map +1 -1
- package/dist/binary.js +44 -11
- package/dist/binary.js.map +1 -1
- package/dist/checksum.d.ts +9 -0
- package/dist/checksum.d.ts.map +1 -0
- package/dist/checksum.js +115 -0
- package/dist/checksum.js.map +1 -0
- package/package.json +1 -1
package/dist/binary.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"AAiBA,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"AAiBA,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AA4B3F;;GAEG;AACH,wBAAgB,aAAa,CAAC,YAAY,CAAC,EAAE,YAAY,GAAG,MAAM,CAGjE;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAmBvD;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAwG3E;;GAEG;AACH,wBAAsB,cAAc,CAAC,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6FnF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAKjF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAsDpE;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI;IAC/B,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,CASA"}
|
package/dist/binary.js
CHANGED
|
@@ -10,8 +10,9 @@ import { join, dirname } from 'path';
|
|
|
10
10
|
import { spawn } from 'child_process';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
import { extract } from 'tar';
|
|
13
|
-
import {
|
|
13
|
+
import { execFileSync } from 'child_process';
|
|
14
14
|
import { getPlatformInfo, getPlatformDescription } from './platform.js';
|
|
15
|
+
import { verifyArchiveChecksum } from './checksum.js';
|
|
15
16
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
17
|
// GitHub release URL pattern
|
|
17
18
|
const GITHUB_REPO = 'LTplus-AG/ifc-lite';
|
|
@@ -28,8 +29,8 @@ async function getPackageVersion() {
|
|
|
28
29
|
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
29
30
|
return pkg.version;
|
|
30
31
|
}
|
|
31
|
-
catch {
|
|
32
|
-
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw new Error(`Cannot determine @ifc-lite/server-bin package version (corrupt or unreadable package.json): ${error instanceof Error ? error.message : String(error)}`);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
@@ -114,12 +115,20 @@ async function extractTarGz(archivePath, destDir) {
|
|
|
114
115
|
async function extractZip(archivePath, destDir) {
|
|
115
116
|
mkdirSync(destDir, { recursive: true });
|
|
116
117
|
if (process.platform === 'win32') {
|
|
117
|
-
// Use PowerShell on Windows
|
|
118
|
-
|
|
118
|
+
// Use PowerShell on Windows. Pass paths via environment variables and
|
|
119
|
+
// reference them with $env: + -LiteralPath so quoting/wildcard handling in
|
|
120
|
+
// the path cannot break out of the command.
|
|
121
|
+
const psScript = `$ErrorActionPreference='Stop'; ` +
|
|
122
|
+
`Expand-Archive -LiteralPath $env:IL_ARCHIVE -DestinationPath $env:IL_DEST -Force`;
|
|
123
|
+
execFileSync('powershell', ['-NoProfile', '-NonInteractive', '-Command', psScript], {
|
|
124
|
+
stdio: 'pipe',
|
|
125
|
+
env: { ...process.env, IL_ARCHIVE: archivePath, IL_DEST: destDir },
|
|
126
|
+
});
|
|
119
127
|
}
|
|
120
128
|
else {
|
|
121
|
-
// Use unzip on Unix (fallback, shouldn't normally be needed)
|
|
122
|
-
|
|
129
|
+
// Use unzip on Unix (fallback, shouldn't normally be needed). execFileSync
|
|
130
|
+
// passes argv directly with no shell, so path metacharacters are inert.
|
|
131
|
+
execFileSync('unzip', ['-o', archivePath, '-d', destDir], { stdio: 'pipe' });
|
|
123
132
|
}
|
|
124
133
|
}
|
|
125
134
|
/**
|
|
@@ -151,6 +160,9 @@ export async function downloadBinary(onProgress) {
|
|
|
151
160
|
}
|
|
152
161
|
// Download archive
|
|
153
162
|
console.log(`Downloading from: ${downloadUrl}`);
|
|
163
|
+
// Track the asset URL that actually succeeded so the checksum sidecar is
|
|
164
|
+
// fetched from the SAME release/asset that produced this archive.
|
|
165
|
+
let resolvedAssetUrl = downloadUrl;
|
|
154
166
|
try {
|
|
155
167
|
await downloadFile(downloadUrl, archivePath, onProgress);
|
|
156
168
|
}
|
|
@@ -165,6 +177,7 @@ export async function downloadBinary(onProgress) {
|
|
|
165
177
|
try {
|
|
166
178
|
console.log(`Trying alternate URL: ${altUrl}`);
|
|
167
179
|
await downloadFile(altUrl, archivePath, onProgress);
|
|
180
|
+
resolvedAssetUrl = altUrl;
|
|
168
181
|
downloaded = true;
|
|
169
182
|
break;
|
|
170
183
|
}
|
|
@@ -185,6 +198,10 @@ export async function downloadBinary(onProgress) {
|
|
|
185
198
|
` - Build from source: cargo build --release -p ifc-lite-server`);
|
|
186
199
|
}
|
|
187
200
|
}
|
|
201
|
+
// Verify archive integrity before we extract / chmod / execute it. Fails
|
|
202
|
+
// closed on a checksum mismatch; fails open (with a warning) for older
|
|
203
|
+
// releases that predate the checksum pipeline.
|
|
204
|
+
await verifyArchiveChecksum(archivePath, resolvedAssetUrl, platformInfo.archiveName);
|
|
188
205
|
console.log('Extracting archive...');
|
|
189
206
|
// Extract archive based on type
|
|
190
207
|
await extractArchive(archivePath, CACHE_DIR, platformInfo.archiveType);
|
|
@@ -230,10 +247,26 @@ export async function runBinary(args = []) {
|
|
|
230
247
|
env: process.env,
|
|
231
248
|
};
|
|
232
249
|
const child = spawn(binaryPath, args, options);
|
|
250
|
+
// Forward signals to child process. Track the handlers so they can be
|
|
251
|
+
// removed once the child exits or fails to start, preventing unbounded
|
|
252
|
+
// listener accumulation and stale child.kill calls on subsequent calls.
|
|
253
|
+
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
254
|
+
const handlers = new Map();
|
|
255
|
+
let cleanedUp = false;
|
|
256
|
+
const cleanup = () => {
|
|
257
|
+
if (cleanedUp)
|
|
258
|
+
return;
|
|
259
|
+
cleanedUp = true;
|
|
260
|
+
for (const [sig, handler] of handlers) {
|
|
261
|
+
process.removeListener(sig, handler);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
233
264
|
child.on('error', (error) => {
|
|
265
|
+
cleanup();
|
|
234
266
|
reject(new Error(`Failed to start server: ${error.message}`));
|
|
235
267
|
});
|
|
236
268
|
child.on('exit', (code, signal) => {
|
|
269
|
+
cleanup();
|
|
237
270
|
if (signal) {
|
|
238
271
|
// Process was killed by a signal
|
|
239
272
|
resolve(128 + (signal === 'SIGINT' ? 2 : signal === 'SIGTERM' ? 15 : 1));
|
|
@@ -242,12 +275,12 @@ export async function runBinary(args = []) {
|
|
|
242
275
|
resolve(code ?? 0);
|
|
243
276
|
}
|
|
244
277
|
});
|
|
245
|
-
// Forward signals to child process
|
|
246
|
-
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
247
278
|
for (const sig of signals) {
|
|
248
|
-
|
|
279
|
+
const handler = () => {
|
|
249
280
|
child.kill(sig);
|
|
250
|
-
}
|
|
281
|
+
};
|
|
282
|
+
handlers.set(sig, handler);
|
|
283
|
+
process.on(sig, handler);
|
|
251
284
|
}
|
|
252
285
|
});
|
|
253
286
|
}
|
package/dist/binary.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary.js","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,sEAAsE;AACtE,4DAA4D;AAE5D;;GAEG;AAEH,OAAO,EAAqB,UAAU,EAAE,SAAS,EAAE,SAAS,EAAY,UAAU,EAAoB,MAAM,IAAI,CAAC;AACjH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGrC,OAAO,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"binary.js","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify the downloaded archive against its published SHA-256 checksum.
|
|
3
|
+
*
|
|
4
|
+
* Fail-closed when a checksum is found and MISMATCHES (the artifact is unlinked
|
|
5
|
+
* and an error thrown). Fail-open when NO checksum asset exists (older releases
|
|
6
|
+
* predating the checksum pipeline) by logging a warning and proceeding.
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifyArchiveChecksum(archivePath: string, assetUrl: string, archiveName: string): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=checksum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.d.ts","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AA6FA;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
package/dist/checksum.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Integrity verification for downloaded release archives.
|
|
6
|
+
*
|
|
7
|
+
* Implements a non-breaking SHA-256 check: the per-asset checksum sidecar is
|
|
8
|
+
* fetched from the SAME release as the archive and compared before the archive
|
|
9
|
+
* is extracted / chmod'd / executed. A mismatch fails closed (the artifact is
|
|
10
|
+
* unlinked and an error thrown); a missing checksum asset fails open (warn and
|
|
11
|
+
* proceed) for backward compatibility with older releases.
|
|
12
|
+
*
|
|
13
|
+
* NOTE: The release pipeline SHOULD publish "<asset>.sha256" alongside every
|
|
14
|
+
* archive so this verification becomes fail-closed everywhere.
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, unlinkSync, createReadStream } from 'fs';
|
|
17
|
+
import { pipeline } from 'stream/promises';
|
|
18
|
+
import { createHash } from 'crypto';
|
|
19
|
+
/**
|
|
20
|
+
* Compute the SHA-256 of a file, streamed so large archives are not buffered
|
|
21
|
+
* entirely in memory.
|
|
22
|
+
*/
|
|
23
|
+
async function computeFileSha256(filePath) {
|
|
24
|
+
const hash = createHash('sha256');
|
|
25
|
+
await pipeline(createReadStream(filePath), hash);
|
|
26
|
+
return hash.digest('hex');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse an expected SHA-256 hex digest for the given archive file name out of a
|
|
30
|
+
* checksum body. Supports both the single-digest sidecar form ("<hex>" or
|
|
31
|
+
* "<hex> <name>") and the multi-line SHA256SUMS form ("<hex> <name>" per
|
|
32
|
+
* line). Returns the lowercased 64-char hex digest, or null if not found.
|
|
33
|
+
*/
|
|
34
|
+
function parseExpectedSha256(body, archiveName) {
|
|
35
|
+
const lines = body.split('\n');
|
|
36
|
+
for (const raw of lines) {
|
|
37
|
+
const line = raw.trim();
|
|
38
|
+
if (!line)
|
|
39
|
+
continue;
|
|
40
|
+
// Each line is "<hex>" or "<hex> <filename>" (filename may have a leading '*').
|
|
41
|
+
const match = line.match(/^([0-9a-fA-F]{64})(?:[ \t]+\*?(.+))?$/);
|
|
42
|
+
if (!match)
|
|
43
|
+
continue;
|
|
44
|
+
const [, digest, name] = match;
|
|
45
|
+
// A bare single-digest sidecar (no filename) always applies to this asset.
|
|
46
|
+
if (!name)
|
|
47
|
+
return digest.toLowerCase();
|
|
48
|
+
// SHA256SUMS lists many files; only accept the line for this archive.
|
|
49
|
+
const fileName = name.trim();
|
|
50
|
+
if (fileName === archiveName || fileName.endsWith(`/${archiveName}`)) {
|
|
51
|
+
return digest.toLowerCase();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Fetch the expected SHA-256 for the resolved asset from the SAME release.
|
|
58
|
+
* Tries the per-asset sidecar ("<assetUrl>.sha256") first, then a release-wide
|
|
59
|
+
* "SHA256SUMS" asset. Returns null if no checksum asset is published (older
|
|
60
|
+
* releases) so callers can fail open for backward compatibility.
|
|
61
|
+
*/
|
|
62
|
+
async function fetchExpectedSha256(assetUrl, archiveName) {
|
|
63
|
+
const sumsUrl = assetUrl.replace(/[^/]+$/, 'SHA256SUMS');
|
|
64
|
+
const candidates = [`${assetUrl}.sha256`, sumsUrl];
|
|
65
|
+
for (const url of candidates) {
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
headers: { 'User-Agent': 'ifc-lite-server-bin' },
|
|
69
|
+
redirect: 'follow',
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok)
|
|
72
|
+
continue;
|
|
73
|
+
const body = await response.text();
|
|
74
|
+
const expected = parseExpectedSha256(body, archiveName);
|
|
75
|
+
if (expected)
|
|
76
|
+
return expected;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
// Network/checksum-fetch failure for one candidate; log and try the next.
|
|
80
|
+
console.warn(`Warning: failed to fetch checksum from ${url}: ` +
|
|
81
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Verify the downloaded archive against its published SHA-256 checksum.
|
|
89
|
+
*
|
|
90
|
+
* Fail-closed when a checksum is found and MISMATCHES (the artifact is unlinked
|
|
91
|
+
* and an error thrown). Fail-open when NO checksum asset exists (older releases
|
|
92
|
+
* predating the checksum pipeline) by logging a warning and proceeding.
|
|
93
|
+
*/
|
|
94
|
+
export async function verifyArchiveChecksum(archivePath, assetUrl, archiveName) {
|
|
95
|
+
const expected = await fetchExpectedSha256(assetUrl, archiveName);
|
|
96
|
+
if (!expected) {
|
|
97
|
+
console.warn(`Warning: no SHA-256 checksum published for ${archiveName}; ` +
|
|
98
|
+
`skipping integrity verification. The release pipeline should publish ` +
|
|
99
|
+
`"${archiveName}.sha256" so this becomes a hard requirement.`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const actual = await computeFileSha256(archivePath);
|
|
103
|
+
if (actual !== expected) {
|
|
104
|
+
// Integrity failure: remove the tampered/corrupt artifact and fail closed.
|
|
105
|
+
if (existsSync(archivePath)) {
|
|
106
|
+
unlinkSync(archivePath);
|
|
107
|
+
}
|
|
108
|
+
throw new Error(`Checksum verification failed for ${archiveName}.\n` +
|
|
109
|
+
` Expected: ${expected}\n` +
|
|
110
|
+
` Actual: ${actual}\n` +
|
|
111
|
+
`The downloaded archive does not match the published SHA-256 and will not be used.`);
|
|
112
|
+
}
|
|
113
|
+
console.log(`Checksum verified (SHA-256): ${expected}`);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=checksum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.js","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,sEAAsE;AACtE,4DAA4D;AAE5D;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,IAAI,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,IAAY,EAAE,WAAmB;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,iFAAiF;QACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAClE,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QAC/B,2EAA2E;QAC3E,IAAI,CAAC,IAAI;YAAE,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;QACvC,sEAAsE;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,CAAC;YACrE,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,mBAAmB,CAChC,QAAgB,EAChB,WAAmB;IAEnB,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,CAAC,GAAG,QAAQ,SAAS,EAAE,OAAO,CAAC,CAAC;IAEnD,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,OAAO,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE;gBAChD,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,SAAS;YAC3B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACxD,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0EAA0E;YAC1E,OAAO,CAAC,IAAI,CACV,0CAA0C,GAAG,IAAI;gBACjD,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5D,CAAC;YACF,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,WAAmB,EACnB,QAAgB,EAChB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAElE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CACV,8CAA8C,WAAW,IAAI;YAC7D,uEAAuE;YACvE,IAAI,WAAW,8CAA8C,CAC9D,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,2EAA2E;QAC3E,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,UAAU,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,oCAAoC,WAAW,KAAK;YACpD,eAAe,QAAQ,IAAI;YAC3B,eAAe,MAAM,IAAI;YACzB,mFAAmF,CACpF,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAC;AAC1D,CAAC"}
|