putitoutthere 0.1.20 → 0.1.21
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.
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
* captured for the failure dump. Short-circuits on
|
|
13
13
|
* already-published (idempotent). Honors ctx.dryRun.
|
|
14
14
|
*
|
|
15
|
+
* --allow-dirty is required for our writeVersion-then-publish model
|
|
16
|
+
* (#135), but cargo's default dirty-check is exactly the safety net
|
|
17
|
+
* that catches shipping uncommitted stray edits. We restore a
|
|
18
|
+
* narrower version of that check: before invoking cargo, scan the
|
|
19
|
+
* working tree via `git status --porcelain` and refuse to publish
|
|
20
|
+
* if anything is dirty outside the Cargo.toml we just wrote. If we
|
|
21
|
+
* can't scan (e.g. no git repo), we fall back to cargo's own
|
|
22
|
+
* --allow-dirty behavior.
|
|
23
|
+
*
|
|
15
24
|
* OIDC: the crates-io-auth-action GHA step exchanges the OIDC JWT for
|
|
16
25
|
* a short-lived CARGO_REGISTRY_TOKEN in the env. The handler doesn't
|
|
17
26
|
* drive the exchange -- it just reads the env var the workflow wired
|
|
@@ -25,5 +34,12 @@ import type { Handler } from '../types.js';
|
|
|
25
34
|
* silently creating a half-broken manifest).
|
|
26
35
|
*/
|
|
27
36
|
export declare function replaceCargoVersion(source: string, version: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Return paths of dirty working-tree files that are NOT the package's
|
|
39
|
+
* managed Cargo.toml. Returns null if we can't determine (not inside
|
|
40
|
+
* a git work tree, git command missing, etc) — callers treat null as
|
|
41
|
+
* "can't verify, fall through to cargo's own --allow-dirty behavior."
|
|
42
|
+
*/
|
|
43
|
+
export declare function scanDirtyOutsideManifest(cwd: string, pkgPath: string): string[] | null;
|
|
28
44
|
export declare const crates: Handler;
|
|
29
45
|
//# sourceMappingURL=crates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crates.d.ts","sourceRoot":"","sources":["../../src/handlers/crates.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"crates.d.ts","sourceRoot":"","sources":["../../src/handlers/crates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,OAAO,KAAK,EAAO,OAAO,EAAiB,MAAM,aAAa,CAAC;AA6G/D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAa3E;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,GAAG,IAAI,CAuDjB;AAQD,eAAO,MAAM,MAAM,EAAE,OAKpB,CAAC"}
|
package/dist/handlers/crates.js
CHANGED
|
@@ -12,6 +12,15 @@
|
|
|
12
12
|
* captured for the failure dump. Short-circuits on
|
|
13
13
|
* already-published (idempotent). Honors ctx.dryRun.
|
|
14
14
|
*
|
|
15
|
+
* --allow-dirty is required for our writeVersion-then-publish model
|
|
16
|
+
* (#135), but cargo's default dirty-check is exactly the safety net
|
|
17
|
+
* that catches shipping uncommitted stray edits. We restore a
|
|
18
|
+
* narrower version of that check: before invoking cargo, scan the
|
|
19
|
+
* working tree via `git status --porcelain` and refuse to publish
|
|
20
|
+
* if anything is dirty outside the Cargo.toml we just wrote. If we
|
|
21
|
+
* can't scan (e.g. no git repo), we fall back to cargo's own
|
|
22
|
+
* --allow-dirty behavior.
|
|
23
|
+
*
|
|
15
24
|
* OIDC: the crates-io-auth-action GHA step exchanges the OIDC JWT for
|
|
16
25
|
* a short-lived CARGO_REGISTRY_TOKEN in the env. The handler doesn't
|
|
17
26
|
* drive the exchange -- it just reads the env var the workflow wired
|
|
@@ -19,7 +28,7 @@
|
|
|
19
28
|
*/
|
|
20
29
|
import { execFileSync } from 'node:child_process';
|
|
21
30
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
22
|
-
import { join } from 'node:path';
|
|
31
|
+
import { join, relative } from 'node:path';
|
|
23
32
|
import { TransientError } from '../types.js';
|
|
24
33
|
const REGISTRY = 'https://crates.io';
|
|
25
34
|
async function isPublishedImpl(pkg, version, _ctx) {
|
|
@@ -71,6 +80,18 @@ async function publishImpl(pkg, version, ctx) {
|
|
|
71
80
|
if (ctx.dryRun) {
|
|
72
81
|
return { status: 'skipped' };
|
|
73
82
|
}
|
|
83
|
+
// #135: --allow-dirty disarms cargo's own "is the tree clean?" guard.
|
|
84
|
+
// Reinstate a narrower check: only the Cargo.toml we just wrote may
|
|
85
|
+
// be dirty. Anything else = a bug or a stray edit that would end up
|
|
86
|
+
// in the crate tarball. Published crates can't be unpublished.
|
|
87
|
+
const unexpected = scanDirtyOutsideManifest(ctx.cwd, pkg.path);
|
|
88
|
+
if (unexpected !== null && unexpected.length > 0) {
|
|
89
|
+
throw new Error([
|
|
90
|
+
`cargo publish: refusing to proceed; unexpected dirty files in the working tree outside ${relativeOrSelf(ctx.cwd, join(pkg.path, 'Cargo.toml'))}:`,
|
|
91
|
+
...unexpected.map((p) => ` - ${p}`),
|
|
92
|
+
'Commit or stash these before publishing (putitoutthere passes --allow-dirty to cargo only to permit the managed version bump).',
|
|
93
|
+
].join('\n'));
|
|
94
|
+
}
|
|
74
95
|
try {
|
|
75
96
|
execFileSync('cargo', ['publish', '--allow-dirty', '--verbose', '--manifest-path', join(pkg.path, 'Cargo.toml')], {
|
|
76
97
|
cwd: ctx.cwd,
|
|
@@ -119,6 +140,79 @@ export function replaceCargoVersion(source, version) {
|
|
|
119
140
|
const end = start + prefix.length + old.length + suffix.length;
|
|
120
141
|
return source.slice(0, start) + prefix + version + suffix + source.slice(end);
|
|
121
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Return paths of dirty working-tree files that are NOT the package's
|
|
145
|
+
* managed Cargo.toml. Returns null if we can't determine (not inside
|
|
146
|
+
* a git work tree, git command missing, etc) — callers treat null as
|
|
147
|
+
* "can't verify, fall through to cargo's own --allow-dirty behavior."
|
|
148
|
+
*/
|
|
149
|
+
export function scanDirtyOutsideManifest(cwd, pkgPath) {
|
|
150
|
+
// Confirm we're inside a git work tree. If not, bail and let cargo's
|
|
151
|
+
// own --allow-dirty handling take over.
|
|
152
|
+
try {
|
|
153
|
+
const topOut = execFileSync('git', ['rev-parse', '--show-toplevel'], {
|
|
154
|
+
cwd,
|
|
155
|
+
encoding: 'utf8',
|
|
156
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
157
|
+
});
|
|
158
|
+
if (!topOut.trim())
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// Ask git for the managed file's path relative to the repo root, so
|
|
165
|
+
// we can string-compare against porcelain output directly without
|
|
166
|
+
// fighting platform path conventions (macOS /private/ symlinks,
|
|
167
|
+
// Windows 8.3 short names + case-insensitive FS).
|
|
168
|
+
let managedRel = '';
|
|
169
|
+
try {
|
|
170
|
+
managedRel = execFileSync('git', ['ls-files', '--full-name', '--', 'Cargo.toml'], {
|
|
171
|
+
cwd: pkgPath,
|
|
172
|
+
encoding: 'utf8',
|
|
173
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
174
|
+
}).trim();
|
|
175
|
+
/* v8 ignore next 4 -- Cargo.toml is always tracked at publish time */
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Cargo.toml not tracked (e.g. first release on a fresh tree).
|
|
179
|
+
// Fall through; empty managedRel means nothing is allowed dirty.
|
|
180
|
+
}
|
|
181
|
+
let porcelain;
|
|
182
|
+
try {
|
|
183
|
+
porcelain = execFileSync('git', ['status', '--porcelain'], {
|
|
184
|
+
cwd,
|
|
185
|
+
encoding: 'utf8',
|
|
186
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
187
|
+
});
|
|
188
|
+
/* v8 ignore start -- rev-parse succeeded above, status shouldn't fail */
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
/* v8 ignore stop */
|
|
194
|
+
const unexpected = [];
|
|
195
|
+
for (const raw of porcelain.split('\n')) {
|
|
196
|
+
if (raw.length < 4)
|
|
197
|
+
continue;
|
|
198
|
+
// Porcelain v1: "XY path" or "XY old -> new" for renames. Index 3+
|
|
199
|
+
// is the path; strip quoting if git applied any.
|
|
200
|
+
const rest = raw.slice(3);
|
|
201
|
+
/* v8 ignore next -- rename-row rendering not exercised by current tests */
|
|
202
|
+
const path = rest.includes(' -> ') ? rest.split(' -> ').pop() : rest;
|
|
203
|
+
/* v8 ignore next -- quoted-path rendering not exercised by current tests */
|
|
204
|
+
const normalized = path.startsWith('"') && path.endsWith('"') ? path.slice(1, -1) : path;
|
|
205
|
+
if (normalized === managedRel)
|
|
206
|
+
continue;
|
|
207
|
+
unexpected.push(normalized);
|
|
208
|
+
}
|
|
209
|
+
return unexpected;
|
|
210
|
+
}
|
|
211
|
+
function relativeOrSelf(base, target) {
|
|
212
|
+
const r = relative(base, target);
|
|
213
|
+
/* v8 ignore next -- relative() only returns '' when base === target */
|
|
214
|
+
return r === '' ? target : r;
|
|
215
|
+
}
|
|
122
216
|
export const crates = {
|
|
123
217
|
kind: 'crates',
|
|
124
218
|
isPublished: isPublishedImpl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crates.js","sourceRoot":"","sources":["../../src/handlers/crates.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"crates.js","sourceRoot":"","sources":["../../src/handlers/crates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAErC,KAAK,UAAU,eAAe,CAC5B,GAAqC,EACrC,OAAe,EACf,IAAS;IAET,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,GAAG,QAAQ,kBAAkB,kBAAkB,CAAC,SAAS,CAAC,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;IACxG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE;KACjD,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QACtB,MAAM,IAAI,cAAc,CAAC,iBAAiB,GAAG,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,8FAA8F;IAC9F,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,gBAAgB,CACvB,GAAqB,EACrB,OAAe,EACf,IAAS;IAET,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC/C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,SAAS,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;QACD,iFAAiF;QACjF,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrD,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,GAAmD,EACnD,OAAe,EACf,GAAQ;IAER,IAAI,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,oEAAoE;IACpE,+DAA+D;IAC/D,MAAM,UAAU,GAAG,wBAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb;YACE,0FAA0F,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,GAAG;YAClJ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,gIAAgI;SACjI,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,YAAY,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,EAAE;YAChH,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,GAAG,EAAE;gBACH,GAAG,OAAO,CAAC,GAAG;gBACd,GAAG,GAAG,CAAC,GAAG;gBACV,kBAAkB,EAAE,MAAM;aAC3B;YACD,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5E,MAAM,IAAI,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAClG,CAAC;IAED,OAAO;QACL,MAAM,EAAE,WAAW;QACnB,GAAG,EAAE,GAAG,QAAQ,WAAW,YAAY,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE;KAC1D,CAAC;AACJ,CAAC;AAED,6EAA6E;AAE7E;oCACoC;AACpC,SAAS,YAAY,CAAC,GAAqC;IACzD,OAAO,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,OAAe;IACjE,gEAAgE;IAChE,oEAAoE;IACpE,MAAM,EAAE,GAAG,uDAAuD,CAAC;IACnE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAwD,CAAC;IAC9F,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;IACnC,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAChF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,GAAW,EACX,OAAe;IAEf,qEAAqE;IACrE,wCAAwC;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE;YACnE,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,oEAAoE;IACpE,kEAAkE;IAClE,gEAAgE;IAChE,kDAAkD;IAClD,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE;YAChF,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,sEAAsE;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;QAC/D,iEAAiE;IACnE,CAAC;IACD,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;YACzD,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,yEAAyE;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,oBAAoB;IACpB,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC7B,mEAAmE;QACnE,iDAAiD;QACjD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,2EAA2E;QAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QACtE,4EAA4E;QAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzF,IAAI,UAAU,KAAK,UAAU;YAAE,SAAS;QACxC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,MAAc;IAClD,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjC,uEAAuE;IACvE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAY;IAC7B,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,eAAyC;IACtD,YAAY,EAAE,gBAA2C;IACzD,OAAO,EAAE,WAAiC;CAC3C,CAAC"}
|