@grove-dev/core 0.14.0 → 0.16.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.
- package/dist/awesome-readme.d.ts +8 -0
- package/dist/awesome-readme.d.ts.map +1 -1
- package/dist/awesome-readme.js +28 -0
- package/dist/awesome-readme.js.map +1 -1
- package/dist/build-data.d.ts.map +1 -1
- package/dist/build-data.js +12 -147
- package/dist/build-data.js.map +1 -1
- package/dist/content-body.d.ts +15 -0
- package/dist/content-body.d.ts.map +1 -1
- package/dist/content-body.js +16 -6
- package/dist/content-body.js.map +1 -1
- package/dist/decisions.d.ts +4 -4
- package/dist/decisions.d.ts.map +1 -1
- package/dist/decisions.js +15 -33
- package/dist/decisions.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/normalize-records.d.ts +193 -0
- package/dist/normalize-records.d.ts.map +1 -0
- package/dist/normalize-records.js +346 -0
- package/dist/normalize-records.js.map +1 -0
- package/dist/schema.d.ts +58 -46
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +36 -5
- package/dist/schema.js.map +1 -1
- package/dist/validate.d.ts +17 -15
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +59 -132
- package/dist/validate.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The record normalizer: the one place that turns the three record
|
|
3
|
+
* layers into the record every output is built from.
|
|
4
|
+
*
|
|
5
|
+
* 1. Human source — a record file (see "Formats" below), patched by
|
|
6
|
+
* `paths.overrides`.
|
|
7
|
+
* 2. Generated cache — `paths.githubCache/<slug>.json` (GitHub
|
|
8
|
+
* metadata and health, written by
|
|
9
|
+
* `grove sync github`), with a legacy inline
|
|
10
|
+
* `github` / `health` block and `paths.health`
|
|
11
|
+
* as fallbacks. Health from a stale sync resolves
|
|
12
|
+
* as `status: unknown` (`sync.github.maxAgeDays`).
|
|
13
|
+
* 3. Decisions — `paths.decisions`, which has the final say on
|
|
14
|
+
* visibility.
|
|
15
|
+
*
|
|
16
|
+
* Formats — all supported permanently, and mixable within one site:
|
|
17
|
+
*
|
|
18
|
+
* - YAML only: `paths.recordsDir/<slug>.yml`, for data-only sites.
|
|
19
|
+
* - YAML + pointer: the same file with `content: ./…/<slug>.md`
|
|
20
|
+
* pointing at a Markdown body. `records.deprecateContentPointer`
|
|
21
|
+
* opts in to a `record_format_deprecated` warning for these.
|
|
22
|
+
* - Markdown: `paths.bodiesDir/<slug>.md`, YAML frontmatter (at least
|
|
23
|
+
* `name`, or `title` on a resource hub) plus the review body. A `.md`
|
|
24
|
+
* file a YAML record points at through `content:` is that record's
|
|
25
|
+
* body, never a record of its own.
|
|
26
|
+
*
|
|
27
|
+
* `generate()` (browse, collections, SEO, sitemap, llms), `grove check`,
|
|
28
|
+
* `grove cleanup` and `grove readme generate` all read records through
|
|
29
|
+
* {@link loadNormalizedRecords}, so they cannot disagree about a
|
|
30
|
+
* record's fields or whether it is visible.
|
|
31
|
+
*/
|
|
32
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
33
|
+
import { basename, join, relative, resolve, sep } from 'node:path';
|
|
34
|
+
import { parse as parseYaml } from 'yaml';
|
|
35
|
+
import { ZodError } from 'zod';
|
|
36
|
+
import { readContentFile, splitFrontmatter } from './content-body.js';
|
|
37
|
+
import { githubSyncFreshnessOptions, loadGithubCache, resolveRecordGithub, } from './github-cache.js';
|
|
38
|
+
import { classifyHealth } from './health.js';
|
|
39
|
+
import { blueprintKind, decisionsFileSchema, healthFileSchema, overridesFileSchema, recordsFileSchema, recordVisibility, unwrapDecisions, unwrapHealth, unwrapOverrides, } from './schema.js';
|
|
40
|
+
function isMapping(value) {
|
|
41
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
42
|
+
}
|
|
43
|
+
/** `./`-prefixed, `/`-separated path relative to `cwd`: the form `content:` pointers use. */
|
|
44
|
+
function contentPointerFor(cwd, path) {
|
|
45
|
+
return `./${relative(cwd, path).split(sep).join('/')}`;
|
|
46
|
+
}
|
|
47
|
+
/** Candidate absolute paths for a `content:` pointer, as the build resolves it. */
|
|
48
|
+
function pointerCandidates(cwd, pointer) {
|
|
49
|
+
return [resolve(cwd, pointer), resolve(cwd, 'apps', 'example', pointer)];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Discover and read every record file, in both formats, without merging
|
|
53
|
+
* any layer. A file that cannot be parsed is returned with an issue and
|
|
54
|
+
* no `data`. The same slug in both formats is a `duplicate_slug_format`
|
|
55
|
+
* error on both files: neither silently wins.
|
|
56
|
+
*/
|
|
57
|
+
export async function readRecordSources(config, cwd = process.cwd()) {
|
|
58
|
+
const recordsDir = resolve(cwd, config.paths.recordsDir);
|
|
59
|
+
const bodiesDir = resolve(cwd, config.paths.bodiesDir ?? 'content/records');
|
|
60
|
+
// The field every record of this blueprint must have: frontmatter
|
|
61
|
+
// without it belongs to some other document.
|
|
62
|
+
const labelKey = blueprintKind[config.blueprint] === 'resource' ? 'title' : 'name';
|
|
63
|
+
const sources = [];
|
|
64
|
+
const issue = (source, code, message, severity = 'error') => ({
|
|
65
|
+
code,
|
|
66
|
+
severity,
|
|
67
|
+
slug: source.slug,
|
|
68
|
+
file: source.file,
|
|
69
|
+
message: `${source.slug}: ${message}`,
|
|
70
|
+
});
|
|
71
|
+
// ── YAML records ───────────────────────────────────────────────────
|
|
72
|
+
// Their `content:` pointers are collected first: a Markdown file one
|
|
73
|
+
// of them points at is that record's body, not a record.
|
|
74
|
+
const pointedAt = new Set();
|
|
75
|
+
const yamlFiles = (await readdir(recordsDir).catch(() => []))
|
|
76
|
+
.filter((name) => name.endsWith('.yml'))
|
|
77
|
+
.sort();
|
|
78
|
+
for (const name of yamlFiles) {
|
|
79
|
+
const path = join(recordsDir, name);
|
|
80
|
+
const source = {
|
|
81
|
+
slug: basename(name, '.yml'),
|
|
82
|
+
format: 'yaml',
|
|
83
|
+
path,
|
|
84
|
+
file: relative(cwd, path),
|
|
85
|
+
issues: [],
|
|
86
|
+
};
|
|
87
|
+
sources.push(source);
|
|
88
|
+
// `schema: 'core'` disables custom-tag interpretation: a record with
|
|
89
|
+
// `!!binary` / `!!js/function` must not become a host object.
|
|
90
|
+
let raw;
|
|
91
|
+
try {
|
|
92
|
+
raw = parseYaml(await readFile(path, 'utf8'), { schema: 'core' });
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
source.issues.push(issue(source, 'schema_error', err.message));
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (!isMapping(raw)) {
|
|
99
|
+
source.issues.push(issue(source, 'schema_error', 'record file is empty or not a YAML mapping'));
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
source.data = raw;
|
|
103
|
+
if (typeof raw.content === 'string' && raw.content) {
|
|
104
|
+
source.format = 'yaml+content';
|
|
105
|
+
for (const candidate of pointerCandidates(cwd, raw.content))
|
|
106
|
+
pointedAt.add(candidate);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// ── Markdown records ───────────────────────────────────────────────
|
|
110
|
+
const markdownFiles = (await readdir(bodiesDir).catch(() => []))
|
|
111
|
+
.filter((name) => name.endsWith('.md'))
|
|
112
|
+
.sort();
|
|
113
|
+
for (const name of markdownFiles) {
|
|
114
|
+
const path = join(bodiesDir, name);
|
|
115
|
+
if (pointedAt.has(path))
|
|
116
|
+
continue;
|
|
117
|
+
const { frontmatter, body, hasFrontmatter } = splitFrontmatter(await readFile(path, 'utf8'));
|
|
118
|
+
// No frontmatter: a body nothing points at, or an unrelated page.
|
|
119
|
+
// Neither is a record.
|
|
120
|
+
if (!hasFrontmatter)
|
|
121
|
+
continue;
|
|
122
|
+
const source = {
|
|
123
|
+
slug: basename(name, '.md'),
|
|
124
|
+
format: 'markdown',
|
|
125
|
+
path,
|
|
126
|
+
file: relative(cwd, path),
|
|
127
|
+
issues: [],
|
|
128
|
+
};
|
|
129
|
+
let raw;
|
|
130
|
+
try {
|
|
131
|
+
raw = parseYaml(frontmatter, { schema: 'core' });
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
source.issues.push(issue(source, 'schema_error', `frontmatter: ${err.message}`));
|
|
135
|
+
sources.push(source);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// A record declares at least its name (`title` on a resource hub);
|
|
139
|
+
// frontmatter without it is some other document's.
|
|
140
|
+
if (!isMapping(raw) || raw[labelKey] === undefined)
|
|
141
|
+
continue;
|
|
142
|
+
source.data = raw;
|
|
143
|
+
source.body = body;
|
|
144
|
+
sources.push(source);
|
|
145
|
+
}
|
|
146
|
+
// ── One slug, one format ───────────────────────────────────────────
|
|
147
|
+
const bySlug = new Map();
|
|
148
|
+
for (const source of sources) {
|
|
149
|
+
bySlug.set(source.slug, [...(bySlug.get(source.slug) ?? []), source]);
|
|
150
|
+
}
|
|
151
|
+
for (const group of bySlug.values()) {
|
|
152
|
+
if (group.length < 2)
|
|
153
|
+
continue;
|
|
154
|
+
const files = group.map((source) => source.file).join(' and ');
|
|
155
|
+
for (const source of group) {
|
|
156
|
+
source.issues.push(issue(source, 'duplicate_slug_format', `record is defined twice (${files}); keep one format and delete the other`));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
sources.sort((a, b) => {
|
|
160
|
+
const nameA = basename(a.path);
|
|
161
|
+
const nameB = basename(b.path);
|
|
162
|
+
return nameA < nameB ? -1 : nameA > nameB ? 1 : 0;
|
|
163
|
+
});
|
|
164
|
+
return { sources };
|
|
165
|
+
}
|
|
166
|
+
/** Read an optional side file; a missing or invalid file yields `fallback`. */
|
|
167
|
+
async function readSideFile(path, cwd, parse, fallback) {
|
|
168
|
+
try {
|
|
169
|
+
const raw = await readFile(resolve(cwd, path), 'utf8');
|
|
170
|
+
return parse(parseYaml(raw, { schema: 'core' }) ?? {});
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return fallback;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function loadDecisionVisibility(config, cwd) {
|
|
177
|
+
return readSideFile(config.paths.decisions, cwd, (raw) => new Map(unwrapDecisions(decisionsFileSchema.parse(raw)).map((d) => [d.id, d.decision.visibility])), new Map());
|
|
178
|
+
}
|
|
179
|
+
function loadHealthEntries(config, cwd) {
|
|
180
|
+
return readSideFile(config.paths.health, cwd, (raw) => new Map(unwrapHealth(healthFileSchema.parse(raw)).map((entry) => [entry.id, entry.health])), new Map());
|
|
181
|
+
}
|
|
182
|
+
function loadOverridePatches(config, cwd) {
|
|
183
|
+
return readSideFile(config.paths.overrides, cwd, (raw) => new Map(unwrapOverrides(overridesFileSchema.parse(raw)).map((entry) => [entry.id, entry.patch])), new Map());
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Apply a `paths.decisions` visibility to a record. For project records
|
|
187
|
+
* the decision overwrites `health.visibility`; a project with no health
|
|
188
|
+
* block gets a fabricated "unknown" one from {@link classifyHealth},
|
|
189
|
+
* because list and index payloads read visibility from `health`. For
|
|
190
|
+
* resource-hub and ecosystem-map records (no `health` block) it sets the
|
|
191
|
+
* top-level `visibility`.
|
|
192
|
+
*/
|
|
193
|
+
export function applyDecisionVisibility(record, visibility) {
|
|
194
|
+
if (!visibility)
|
|
195
|
+
return record;
|
|
196
|
+
if (record.kind === 'project') {
|
|
197
|
+
const health = record.health ?? classifyHealth(record.slug).health;
|
|
198
|
+
return { ...record, health: { ...health, visibility } };
|
|
199
|
+
}
|
|
200
|
+
return { ...record, visibility };
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Discover, parse and merge every record, in either format (see
|
|
204
|
+
* {@link readRecordSources}).
|
|
205
|
+
*
|
|
206
|
+
* Per record, lowest to highest precedence:
|
|
207
|
+
*
|
|
208
|
+
* 1. the record file (YAML, or a Markdown record's frontmatter)
|
|
209
|
+
* 2. the GitHub sync cache, which supplies `github` / `health` over a
|
|
210
|
+
* legacy inline copy ({@link resolveRecordGithub})
|
|
211
|
+
* 3. the `paths.overrides` patch (shallow, top-level fields)
|
|
212
|
+
* 4. schema parse (`recordsFileSchema`); the slug is the file name
|
|
213
|
+
* 5. the `paths.health` entry, for a project record nothing above
|
|
214
|
+
* gave a health block
|
|
215
|
+
* 6. the `paths.decisions` visibility
|
|
216
|
+
*
|
|
217
|
+
* Effective visibility is then decision > health > the record's own
|
|
218
|
+
* `visibility` field ({@link recordVisibility}).
|
|
219
|
+
*
|
|
220
|
+
* Never throws for a bad record: a file that cannot be parsed or fails
|
|
221
|
+
* the schema is reported in `issues` and left out of `records`. Missing
|
|
222
|
+
* or invalid side files are treated as empty; `grove check` reports them.
|
|
223
|
+
*/
|
|
224
|
+
export async function loadNormalizedRecords(config, cwd = process.cwd()) {
|
|
225
|
+
const expectedKind = blueprintKind[config.blueprint];
|
|
226
|
+
const [{ sources }, githubCache, decisions, healthBySlug, patches] = await Promise.all([
|
|
227
|
+
readRecordSources(config, cwd),
|
|
228
|
+
loadGithubCache(config, cwd),
|
|
229
|
+
loadDecisionVisibility(config, cwd),
|
|
230
|
+
loadHealthEntries(config, cwd),
|
|
231
|
+
loadOverridePatches(config, cwd),
|
|
232
|
+
]);
|
|
233
|
+
const cachePath = relative(cwd, githubCache.dir) || '.';
|
|
234
|
+
// A stale sync resolves as `status: unknown` rather than old values.
|
|
235
|
+
const freshness = githubSyncFreshnessOptions(config);
|
|
236
|
+
const warnPointer = config.records?.deprecateContentPointer === true;
|
|
237
|
+
const entries = [];
|
|
238
|
+
for (const source of sources) {
|
|
239
|
+
const { slug, file, format } = source;
|
|
240
|
+
const entry = {
|
|
241
|
+
slug,
|
|
242
|
+
file,
|
|
243
|
+
format,
|
|
244
|
+
issues: [...source.issues],
|
|
245
|
+
syncStale: false,
|
|
246
|
+
};
|
|
247
|
+
entries.push(entry);
|
|
248
|
+
const push = (code, message, severity) => entry.issues.push({ code, severity, slug, file, message: `${slug}: ${message}` });
|
|
249
|
+
const data = source.data;
|
|
250
|
+
if (!data || entry.issues.some((issue) => issue.severity === 'error'))
|
|
251
|
+
continue;
|
|
252
|
+
const raw = { ...data };
|
|
253
|
+
if (format === 'markdown') {
|
|
254
|
+
// The file is the record's body. A pointer elsewhere would give it
|
|
255
|
+
// two bodies, so it is an error rather than silently ignored.
|
|
256
|
+
if (raw.content !== undefined) {
|
|
257
|
+
push('markdown_content_pointer', 'a Markdown record is its own body; remove `content:` from its frontmatter', 'error');
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
// `content` points at the record's own file, so every renderer that
|
|
261
|
+
// reads a body through `content` works unchanged.
|
|
262
|
+
raw.content = contentPointerFor(cwd, source.path);
|
|
263
|
+
if (raw.slug === undefined)
|
|
264
|
+
raw.slug = slug;
|
|
265
|
+
}
|
|
266
|
+
else if (format === 'yaml+content' && warnPointer) {
|
|
267
|
+
push('record_format_deprecated', `YAML record with a \`content:\` pointer; move it to one Markdown file with frontmatter (${config.paths.bodiesDir ?? 'content/records'}/${slug}.md)`, 'warning');
|
|
268
|
+
}
|
|
269
|
+
// Cache wins over a legacy inline copy; a disagreement is a second
|
|
270
|
+
// source of truth, so name the fields.
|
|
271
|
+
const resolved = resolveRecordGithub(raw, githubCache.entries.get(slug), freshness);
|
|
272
|
+
entry.syncStale = resolved.syncStale !== undefined;
|
|
273
|
+
if (resolved.conflicts.length > 0) {
|
|
274
|
+
push('github_cache_mismatch', `inline github/health disagrees with ${cachePath}/${slug}.json — ${resolved.conflicts.join(', ')}. The cache wins; run \`grove migrate github-cache\` to drop the inline copy.`, 'warning');
|
|
275
|
+
}
|
|
276
|
+
const merged = resolved.record;
|
|
277
|
+
if (!merged.kind)
|
|
278
|
+
merged.kind = expectedKind;
|
|
279
|
+
const patch = patches.get(slug);
|
|
280
|
+
const input = patch ? { ...merged, ...patch } : merged;
|
|
281
|
+
let base;
|
|
282
|
+
try {
|
|
283
|
+
base = recordsFileSchema.parse(input);
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
if (err instanceof ZodError) {
|
|
287
|
+
for (const zodIssue of err.issues) {
|
|
288
|
+
const where = zodIssue.path.length > 0 ? zodIssue.path.join('.') : '(root)';
|
|
289
|
+
push('zod_error', `${where} ${zodIssue.message}`, 'error');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
push('schema_error', err.message, 'error');
|
|
294
|
+
}
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
base.slug = slug;
|
|
298
|
+
let healthSource = patch && 'health' in patch
|
|
299
|
+
? 'override'
|
|
300
|
+
: resolved.health === 'none'
|
|
301
|
+
? 'none'
|
|
302
|
+
: resolved.health;
|
|
303
|
+
let record = base;
|
|
304
|
+
if (record.kind === 'project' && !record.health) {
|
|
305
|
+
healthSource = 'none';
|
|
306
|
+
const fromFile = healthBySlug.get(slug);
|
|
307
|
+
if (fromFile) {
|
|
308
|
+
record = { ...record, health: fromFile };
|
|
309
|
+
healthSource = 'file';
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const decision = decisions.get(slug);
|
|
313
|
+
if (decision && record.kind === 'project' && !record.health)
|
|
314
|
+
healthSource = 'decision';
|
|
315
|
+
record = applyDecisionVisibility(record, decision);
|
|
316
|
+
let body;
|
|
317
|
+
if (format === 'markdown')
|
|
318
|
+
body = source.body;
|
|
319
|
+
else if (base.content) {
|
|
320
|
+
body = readContentFile(base.content, pointerCandidates(cwd, base.content))?.body;
|
|
321
|
+
}
|
|
322
|
+
entry.record = {
|
|
323
|
+
slug,
|
|
324
|
+
file,
|
|
325
|
+
format,
|
|
326
|
+
...(body !== undefined ? { body } : {}),
|
|
327
|
+
record,
|
|
328
|
+
base,
|
|
329
|
+
visibility: recordVisibility(record),
|
|
330
|
+
declaredSlug: format === 'markdown' ? data.slug : input.slug,
|
|
331
|
+
provenance: {
|
|
332
|
+
github: resolved.github,
|
|
333
|
+
health: healthSource,
|
|
334
|
+
decision: decision !== undefined,
|
|
335
|
+
override: patch !== undefined,
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
records: entries.flatMap((entry) => (entry.record ? [entry.record] : [])),
|
|
341
|
+
entries,
|
|
342
|
+
issues: entries.flatMap((entry) => entry.issues),
|
|
343
|
+
githubCache,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=normalize-records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-records.js","sourceRoot":"","sources":["../src/normalize-records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAGL,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,aAAa,EAEb,mBAAmB,EAGnB,gBAAgB,EAChB,mBAAmB,EAEnB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,eAAe,GAChB,MAAM,aAAa,CAAC;AAyIrB,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,6FAA6F;AAC7F,SAAS,iBAAiB,CAAC,GAAW,EAAE,IAAY;IAClD,OAAO,KAAK,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,mFAAmF;AACnF,SAAS,iBAAiB,CAAC,GAAW,EAAE,OAAe;IACrD,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAmB,EACnB,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAEnB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,iBAAiB,CAAC,CAAC;IAC5E,kEAAkE;IAClE,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IACnF,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,CACZ,MAA2C,EAC3C,IAAyB,EACzB,OAAe,EACf,WAAoC,OAAO,EAC9B,EAAE,CAAC,CAAC;QACjB,IAAI;QACJ,QAAQ;QACR,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE;KACtC,CAAC,CAAC;IAEH,sEAAsE;IACtE,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,MAAM,SAAS,GAAG,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC;SACtE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACvC,IAAI,EAAE,CAAC;IACV,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAiB;YAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAC5B,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;YACzB,MAAM,EAAE,EAAE;SACX,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,qEAAqE;QACrE,8DAA8D;QAC9D,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,SAAS,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YAC1E,SAAS;QACX,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAChB,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,4CAA4C,CAAC,CAC5E,CAAC;YACF,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;QAClB,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACnD,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC;YAC/B,KAAK,MAAM,SAAS,IAAI,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,MAAM,aAAa,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC;SACzE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SACtC,IAAI,EAAE,CAAC;IACV,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAClC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,gBAAgB,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7F,kEAAkE;QAClE,uBAAuB;QACvB,IAAI,CAAC,cAAc;YAAE,SAAS;QAC9B,MAAM,MAAM,GAAiB;YAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;YAC3B,MAAM,EAAE,UAAU;YAClB,IAAI;YACJ,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;YACzB,MAAM,EAAE,EAAE;SACX,CAAC;QACF,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,SAAS,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,gBAAiB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5F,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,mEAAmE;QACnE,mDAAmD;QACnD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS;YAAE,SAAS;QAC7D,MAAM,CAAC,IAAI,GAAG,GAAG,CAAC;QAClB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAED,sEAAsE;IACtE,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/D,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,IAAI,CAChB,KAAK,CACH,MAAM,EACN,uBAAuB,EACvB,4BAA4B,KAAK,yCAAyC,CAC3E,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,+EAA+E;AAC/E,KAAK,UAAU,YAAY,CACzB,IAAY,EACZ,GAAW,EACX,KAA0B,EAC1B,QAAW;IAEX,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAmB,EAAE,GAAW;IAC9D,OAAO,YAAY,CACjB,MAAM,CAAC,KAAK,CAAC,SAAS,EACtB,GAAG,EACH,CAAC,GAAG,EAAE,EAAE,CACN,IAAI,GAAG,CACL,eAAe,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAC1F,EACH,IAAI,GAAG,EAA8B,CACtC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAmB,EAAE,GAAW;IACzD,OAAO,YAAY,CACjB,MAAM,CAAC,KAAK,CAAC,MAAM,EACnB,GAAG,EACH,CAAC,GAAG,EAAE,EAAE,CACN,IAAI,GAAG,CACL,YAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CACnF,EACH,IAAI,GAAG,EAAiC,CACzC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAmB,EAAE,GAAW;IAC3D,OAAO,YAAY,CACjB,MAAM,CAAC,KAAK,CAAC,SAAS,EACtB,GAAG,EACH,CAAC,GAAG,EAAE,EAAE,CACN,IAAI,GAAG,CACL,eAAe,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CACxF,EACH,IAAI,GAAG,EAAmC,CAC3C,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAgB,EAChB,UAA0C;IAE1C,IAAI,CAAC,UAAU;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACnE,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAmB,EACnB,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAEnB,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACrF,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC;QAC9B,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC;QAC5B,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC;QACnC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC;QAC9B,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC;KACjC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IACxD,qEAAqE;IACrE,MAAM,SAAS,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAErE,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;QACtC,MAAM,KAAK,GAAgB;YACzB,IAAI;YACJ,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;YAC1B,SAAS,EAAE,KAAK;SACjB,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,CAAC,IAAyB,EAAE,OAAe,EAAE,QAAiC,EAAE,EAAE,CAC7F,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,KAAK,OAAO,EAAE,EAAE,CAAC,CAAC;QACpF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC;YAAE,SAAS;QAEhF,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QACxB,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,mEAAmE;YACnE,8DAA8D;YAC9D,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC9B,IAAI,CACF,0BAA0B,EAC1B,2EAA2E,EAC3E,OAAO,CACR,CAAC;gBACF,SAAS;YACX,CAAC;YACD,oEAAoE;YACpE,kDAAkD;YAClD,GAAG,CAAC,OAAO,GAAG,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAClD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;gBAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAC9C,CAAC;aAAM,IAAI,MAAM,KAAK,cAAc,IAAI,WAAW,EAAE,CAAC;YACpD,IAAI,CACF,0BAA0B,EAC1B,2FAA2F,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,iBAAiB,IAAI,IAAI,MAAM,EACpJ,SAAS,CACV,CAAC;QACJ,CAAC;QAED,mEAAmE;QACnE,uCAAuC;QACvC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QACpF,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC;QACnD,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CACF,uBAAuB,EACvB,uCAAuC,SAAS,IAAI,IAAI,WAAW,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,+EAA+E,EAC/K,SAAS,CACV,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAEvD,IAAI,IAAc,CAAC;QACnB,IAAI,CAAC;YACH,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBAC5B,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;oBAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;oBAC5E,IAAI,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,EAAG,GAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxD,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,IAAI,YAAY,GACd,KAAK,IAAI,QAAQ,IAAI,KAAK;YACxB,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM;gBAC1B,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxB,IAAI,MAAM,GAAa,IAAI,CAAC;QAC5B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAChD,YAAY,GAAG,MAAM,CAAC;YACtB,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;gBACzC,YAAY,GAAG,MAAM,CAAC;YACxB,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,YAAY,GAAG,UAAU,CAAC;QACvF,MAAM,GAAG,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEnD,IAAI,IAAwB,CAAC;QAC7B,IAAI,MAAM,KAAK,UAAU;YAAE,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;aACzC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC;QACnF,CAAC;QAED,KAAK,CAAC,MAAM,GAAG;YACb,IAAI;YACJ,IAAI;YACJ,MAAM;YACN,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,MAAM;YACN,IAAI;YACJ,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC;YACpC,YAAY,EAAE,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;YAC5D,UAAU,EAAE;gBACV,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,MAAM,EAAE,YAAY;gBACpB,QAAQ,EAAE,QAAQ,KAAK,SAAS;gBAChC,QAAQ,EAAE,KAAK,KAAK,SAAS;aAC9B;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO;QACP,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;QAChD,WAAW;KACZ,CAAC;AACJ,CAAC"}
|