@stag-build/phonebook 0.1.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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +82 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/doctor.d.ts +33 -0
  7. package/dist/commands/doctor.js +690 -0
  8. package/dist/commands/doctor.js.map +1 -0
  9. package/dist/commands/init.d.ts +27 -0
  10. package/dist/commands/init.js +415 -0
  11. package/dist/commands/init.js.map +1 -0
  12. package/dist/config.d.ts +33 -0
  13. package/dist/config.js +21 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/engines/android.d.ts +70 -0
  16. package/dist/engines/android.js +265 -0
  17. package/dist/engines/android.js.map +1 -0
  18. package/dist/engines/git.d.ts +4 -0
  19. package/dist/engines/git.js +13 -0
  20. package/dist/engines/git.js.map +1 -0
  21. package/dist/engines/ios.d.ts +55 -0
  22. package/dist/engines/ios.js +195 -0
  23. package/dist/engines/ios.js.map +1 -0
  24. package/dist/errors.d.ts +12 -0
  25. package/dist/errors.js +69 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/gradle/catalog.d.ts +110 -0
  28. package/dist/gradle/catalog.js +413 -0
  29. package/dist/gradle/catalog.js.map +1 -0
  30. package/dist/ios/snapshotTestClass.d.ts +59 -0
  31. package/dist/ios/snapshotTestClass.js +195 -0
  32. package/dist/ios/snapshotTestClass.js.map +1 -0
  33. package/dist/manifest.d.ts +32 -0
  34. package/dist/manifest.js +23 -0
  35. package/dist/manifest.js.map +1 -0
  36. package/dist/mcp/server.d.ts +1 -0
  37. package/dist/mcp/server.js +226 -0
  38. package/dist/mcp/server.js.map +1 -0
  39. package/dist/naming.d.ts +18 -0
  40. package/dist/naming.js +34 -0
  41. package/dist/naming.js.map +1 -0
  42. package/dist/scan/android.d.ts +7 -0
  43. package/dist/scan/android.js +222 -0
  44. package/dist/scan/android.js.map +1 -0
  45. package/dist/scan/hints.d.ts +25 -0
  46. package/dist/scan/hints.js +338 -0
  47. package/dist/scan/hints.js.map +1 -0
  48. package/dist/scan/ios.d.ts +7 -0
  49. package/dist/scan/ios.js +201 -0
  50. package/dist/scan/ios.js.map +1 -0
  51. package/dist/scan/types.d.ts +52 -0
  52. package/dist/scan/types.js +7 -0
  53. package/dist/scan/types.js.map +1 -0
  54. package/dist/site/build.d.ts +17 -0
  55. package/dist/site/build.js +0 -0
  56. package/dist/site/build.js.map +1 -0
  57. package/dist/versions.d.ts +71 -0
  58. package/dist/versions.js +334 -0
  59. package/dist/versions.js.map +1 -0
  60. package/package.json +54 -0
package/dist/errors.js ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Signature matching over raw Gradle (or xcodebuild) output, turning known
3
+ * failure patterns into human diagnosis lines. Zero lines means "no known
4
+ * signature matched" — the raw output should still be shown to the user.
5
+ */
6
+ export function diagnoseGradleFailure(output) {
7
+ const lines = [];
8
+ const mentionsRoborazzi = /roborazzi/i.test(output);
9
+ const incompatibleKotlin = /was compiled with an incompatible\s+version of Kotlin/.test(output);
10
+ const metadataMatch = output.match(/binary version of its metadata is ([\d.]+),\s*expected version is ([\d.]+)/);
11
+ if (mentionsRoborazzi && (incompatibleKotlin || metadataMatch)) {
12
+ const detail = metadataMatch ? ` (found metadata ${metadataMatch[1]}, expected ${metadataMatch[2]})` : '';
13
+ lines.push(`Roborazzi is too new for this project's Kotlin.${detail} Run \`phonebook doctor\` for the exact ` +
14
+ 'compatible version, or see the kotlin-compat check.');
15
+ }
16
+ const isJunit4Unresolved = /Unresolved reference '?junit4'?/.test(output) ||
17
+ /Cannot access class 'androidx\.compose\.ui\.test\.junit4/.test(output);
18
+ if (isJunit4Unresolved) {
19
+ lines.push('Missing test dependency: add testImplementation("androidx.compose.ui:ui-test-junit4") to the module.');
20
+ }
21
+ const mentionsRoborazziGeneratedTest = /generated[\/\\]roborazzi/.test(output) || /RoborazziPreviewParameterizedTests/.test(output);
22
+ if (!isJunit4Unresolved && /FileAnalysisException|Internal compiler error/.test(output) && mentionsRoborazziGeneratedTest) {
23
+ const locationMatch = output.match(/While analysing (\S+?):(\d+):(\d+):/);
24
+ const location = locationMatch ? ` (at ${locationMatch[1]}:${locationMatch[2]}:${locationMatch[3]})` : '';
25
+ lines.push('Kotlin compiler crashed analyzing the generated Roborazzi test. This is usually a missing test ' +
26
+ 'dependency — most often androidx.compose.ui:ui-test-junit4 — or a Roborazzi/ComposablePreviewScanner ' +
27
+ `version mismatch. Run \`phonebook doctor\` for dependency checks.${location}`);
28
+ }
29
+ const javaMatch = output.match(/Android Gradle plugin requires Java (\d+)/);
30
+ if (javaMatch) {
31
+ lines.push(`Android Gradle plugin requires Java ${javaMatch[1]}+; check JAVA_HOME (note: /usr/libexec/java_home may ` +
32
+ 'point at an old JDK even when newer ones are installed, e.g. via Homebrew).');
33
+ }
34
+ if (/(?:0 tests|No tests found)/.test(output) && /recordRoborazzi/.test(output)) {
35
+ lines.push('No previews were recorded. If your @Preview functions are private, set includePrivatePreviews = true ' +
36
+ 'in the roborazzi { generateComposePreviewRobolectricTests { ... } } block.');
37
+ }
38
+ return lines;
39
+ }
40
+ /**
41
+ * Signature matching over raw xcodebuild output, turning known failure
42
+ * patterns into human diagnosis lines. Zero lines means "no known signature
43
+ * matched" — the raw output should still be shown to the user.
44
+ */
45
+ export function diagnoseXcodebuildFailure(output) {
46
+ const lines = [];
47
+ const missingModule = output.match(/Unable to find module dependency: '([^']+)'/);
48
+ if (missingModule) {
49
+ lines.push(`A Swift file imports '${missingModule[1]}', but the target does not link a module with that name.`);
50
+ lines.push("The SnapshotTest base class lives in the SnapshottingTests module — the snapshot test file should say " +
51
+ '`import SnapshottingTests`. Otherwise, add the missing package product to the test target in Xcode.');
52
+ }
53
+ if (/Failed to install or launch the test runner|Mach error -308|\(ipc\/mig\) server died/.test(output)) {
54
+ lines.push('The iOS simulator runtime died while installing the test runner — usually transient, not a setup problem.');
55
+ lines.push('Retry once; if it persists run: xcrun simctl shutdown all (and if still failing: xcrun simctl erase ' +
56
+ '"<device name>"). First boot of a newly installed runtime can also take minutes — let it finish in ' +
57
+ 'Simulator.app before retrying.');
58
+ }
59
+ if (/Scheme (.+?) is not currently configured for the test action|does not contain any tests|There are no test bundles/.test(output)) {
60
+ lines.push("The scheme's Test action has no runnable tests. Ensure the test target with your SnapshotTest subclass " +
61
+ 'is included in the scheme\'s Test action, then run `phonebook doctor`.');
62
+ }
63
+ if (/Unable to find a d(?:estination|evice) matching/.test(output)) {
64
+ lines.push('No simulator matches the configured name. List devices with: xcrun simctl list devices available — ' +
65
+ 'then update ios.simulator in phonebook.config.json.');
66
+ }
67
+ return lines;
68
+ }
69
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ export interface CatalogLibrary {
2
+ alias: string;
3
+ accessor: string;
4
+ group: string;
5
+ name: string;
6
+ version?: string;
7
+ }
8
+ export interface CatalogPlugin {
9
+ alias: string;
10
+ accessor: string;
11
+ id: string;
12
+ version?: string;
13
+ }
14
+ export interface CatalogBundle {
15
+ alias: string;
16
+ accessor: string;
17
+ /** Library aliases this bundle groups together. */
18
+ members: string[];
19
+ }
20
+ export interface VersionCatalog {
21
+ versions: Map<string, string>;
22
+ libraries: CatalogLibrary[];
23
+ plugins: CatalogPlugin[];
24
+ bundles: CatalogBundle[];
25
+ }
26
+ /** Gradle configurations that reach the unit-test compile classpath. */
27
+ export declare const UNIT_TEST_CONFIGURATIONS: string[];
28
+ /** `alias-with-dashes_or_underscores` -> `<prefix>.alias.with.dashes.or.underscores`. */
29
+ export declare function accessorFor(alias: string, prefix?: string): string;
30
+ /** `alias-with-dashes` -> `<prefix>.plugins.alias.with.dashes`. */
31
+ export declare function pluginAccessorFor(alias: string, prefix?: string): string;
32
+ /** `alias-with-dashes` -> `<prefix>.bundles.alias.with.dashes`. */
33
+ export declare function bundleAccessorFor(alias: string, prefix?: string): string;
34
+ /**
35
+ * True when `accessor` appears in `text` as a whole token: not immediately
36
+ * preceded or followed by an identifier character or `.` (so a longer
37
+ * neighbouring accessor, e.g. `libs.androidx.compose.ui.test.junit4.something`,
38
+ * doesn't falsely match a shorter one).
39
+ */
40
+ export declare function accessorAppears(text: string, accessor: string): boolean;
41
+ /**
42
+ * Minimal parser for a Gradle version catalog TOML file: [versions],
43
+ * [libraries], [plugins] sections. Handles the entry shapes documented on
44
+ * CatalogLibrary/CatalogPlugin. Comments and blank lines are ignored;
45
+ * malformed entries are skipped rather than throwing. `prefix` is the
46
+ * catalog's Gradle accessor prefix ("libs" by default, or the name given to
47
+ * `versionCatalogs { create("name") { ... } }` for a custom catalog).
48
+ */
49
+ export declare function parseVersionCatalogText(toml: string, prefix?: string): VersionCatalog;
50
+ export interface CatalogDeclaration {
51
+ /** The catalog's accessor prefix, e.g. "deps" for `libs.plugins.foo` -> `deps.plugins.foo`. */
52
+ prefix: string;
53
+ /** Path to the catalog's TOML file, relative to the project root. */
54
+ tomlPath: string;
55
+ }
56
+ /**
57
+ * Parses `settings.gradle(.kts)` for additional named version catalogs
58
+ * declared via `versionCatalogs { create("name") { from(files("path")) } }`.
59
+ * Does not include the default "libs" catalog (see loadVersionCatalog).
60
+ */
61
+ export declare function parseCatalogDeclarations(settingsText: string): CatalogDeclaration[];
62
+ /**
63
+ * Loads every version catalog available to the project: the default
64
+ * `gradle/libs.versions.toml` (prefix "libs") plus any custom catalogs
65
+ * declared in settings.gradle(.kts) via `versionCatalogs { create(...) }`.
66
+ * Returns a map keyed by accessor prefix; empty if none are present or
67
+ * parseable.
68
+ */
69
+ export declare function loadVersionCatalog(projectDir: string): Promise<Map<string, VersionCatalog>>;
70
+ export interface CoordinateLookup {
71
+ found: boolean;
72
+ version?: string;
73
+ via: 'literal' | 'catalog' | 'wrong-configuration' | 'none';
74
+ /**
75
+ * Set when `via` is 'wrong-configuration': the Gradle configuration the
76
+ * coordinate was actually found under (e.g. "androidTestImplementation"),
77
+ * which doesn't reach the unit-test compile classpath.
78
+ */
79
+ foundConfiguration?: string;
80
+ }
81
+ export interface FindLibraryOptions {
82
+ /**
83
+ * When set, a match only counts as "found" if it's declared under one of
84
+ * these Gradle configurations (e.g. testImplementation). A match under a
85
+ * different configuration is reported as `via: 'wrong-configuration'`
86
+ * rather than silently accepted or silently ignored. Omit to accept a
87
+ * match under any configuration (original, configuration-blind behavior).
88
+ */
89
+ configurations?: string[];
90
+ }
91
+ type CatalogInput = VersionCatalog | VersionCatalog[] | undefined;
92
+ /**
93
+ * Looks up a `group:name` Maven coordinate in raw Gradle build-file text,
94
+ * either as a literal coordinate string or, if a version catalog (or list of
95
+ * catalogs) is supplied, via a `<prefix>.*` accessor that resolves to that
96
+ * group:name. With `options.configurations` set, a match declared under a
97
+ * configuration outside that list (e.g. androidTestImplementation when only
98
+ * testImplementation etc. were requested) is reported as
99
+ * `via: 'wrong-configuration'` instead of `found: true`.
100
+ */
101
+ export declare function findLibrary(gradleText: string, catalog: CatalogInput, group: string, name: string, options?: FindLibraryOptions): CoordinateLookup;
102
+ /**
103
+ * Looks up a Gradle plugin id in raw build-file text: as `id("x")` /
104
+ * `id 'x'` (optionally with `version "y"` on the same line), as the Gradle
105
+ * plugin marker dependency coordinate (`pluginId:pluginId.gradle.plugin[:version]`),
106
+ * or, if a version catalog (or list of catalogs) is supplied, via a
107
+ * `<prefix>.plugins.*` accessor.
108
+ */
109
+ export declare function findPlugin(gradleText: string, catalog: CatalogInput, pluginId: string): CoordinateLookup;
110
+ export {};
@@ -0,0 +1,413 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ /** Gradle configurations that reach the unit-test compile classpath. */
4
+ export const UNIT_TEST_CONFIGURATIONS = [
5
+ 'testImplementation',
6
+ 'testDebugImplementation',
7
+ 'testReleaseImplementation',
8
+ 'testApi',
9
+ 'testCompileOnly',
10
+ 'implementation',
11
+ 'api',
12
+ ];
13
+ /** `alias-with-dashes_or_underscores` -> `<prefix>.alias.with.dashes.or.underscores`. */
14
+ export function accessorFor(alias, prefix = 'libs') {
15
+ return `${prefix}.${alias.replace(/[-_]/g, '.')}`;
16
+ }
17
+ /** `alias-with-dashes` -> `<prefix>.plugins.alias.with.dashes`. */
18
+ export function pluginAccessorFor(alias, prefix = 'libs') {
19
+ return `${prefix}.plugins.${alias.replace(/[-_]/g, '.')}`;
20
+ }
21
+ /** `alias-with-dashes` -> `<prefix>.bundles.alias.with.dashes`. */
22
+ export function bundleAccessorFor(alias, prefix = 'libs') {
23
+ return `${prefix}.bundles.${alias.replace(/[-_]/g, '.')}`;
24
+ }
25
+ function escapeRegExp(s) {
26
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
27
+ }
28
+ /**
29
+ * True when `accessor` appears in `text` as a whole token: not immediately
30
+ * preceded or followed by an identifier character or `.` (so a longer
31
+ * neighbouring accessor, e.g. `libs.androidx.compose.ui.test.junit4.something`,
32
+ * doesn't falsely match a shorter one).
33
+ */
34
+ export function accessorAppears(text, accessor) {
35
+ const re = new RegExp(`(?<![\\w.])${escapeRegExp(accessor)}(?![\\w.])`);
36
+ return re.test(text);
37
+ }
38
+ /** Strips a `#` comment that isn't inside a quoted string. */
39
+ function stripComment(line) {
40
+ let inString = false;
41
+ for (let i = 0; i < line.length; i++) {
42
+ const c = line[i];
43
+ if (c === '"')
44
+ inString = !inString;
45
+ else if (c === '#' && !inString)
46
+ return line.slice(0, i);
47
+ }
48
+ return line;
49
+ }
50
+ /** Extracts `field = "value"` from an inline-table body. */
51
+ function extractString(body, field) {
52
+ const m = body.match(new RegExp(`\\b${field}\\s*=\\s*"([^"]*)"`));
53
+ return m?.[1];
54
+ }
55
+ /** Extracts a version ref name from `version.ref = "x"` or `version = { ref = "x" }`. */
56
+ function extractVersionRef(body) {
57
+ const dotted = body.match(/\bversion\.ref\s*=\s*"([^"]*)"/);
58
+ if (dotted)
59
+ return dotted[1];
60
+ const nested = body.match(/\bversion\s*=\s*\{[^}]*\bref\s*=\s*"([^"]*)"[^}]*\}/);
61
+ if (nested)
62
+ return nested[1];
63
+ return undefined;
64
+ }
65
+ /** Extracts a literal `version = "x"` (not the `.ref` / nested-object forms). */
66
+ function extractVersionLiteral(body) {
67
+ const m = body.match(/\bversion\s*=\s*"([^"]*)"/);
68
+ return m?.[1];
69
+ }
70
+ function resolveVersion(body, versions) {
71
+ const ref = extractVersionRef(body);
72
+ if (ref !== undefined)
73
+ return versions.get(ref);
74
+ return extractVersionLiteral(body);
75
+ }
76
+ function parseLibraryEntry(alias, value, versions, prefix) {
77
+ const accessor = accessorFor(alias, prefix);
78
+ if (value.startsWith('"')) {
79
+ const m = value.match(/^"([^"]*)"$/);
80
+ if (!m)
81
+ return undefined;
82
+ const [group, name, version] = m[1].split(':');
83
+ if (!group || !name)
84
+ return undefined;
85
+ return { alias, accessor, group, name, version };
86
+ }
87
+ if (value.startsWith('{')) {
88
+ const module = extractString(value, 'module');
89
+ let group = extractString(value, 'group');
90
+ let name = extractString(value, 'name');
91
+ if (module) {
92
+ const idx = module.indexOf(':');
93
+ if (idx !== -1) {
94
+ group = module.slice(0, idx);
95
+ name = module.slice(idx + 1);
96
+ }
97
+ }
98
+ if (!group || !name)
99
+ return undefined;
100
+ return { alias, accessor, group, name, version: resolveVersion(value, versions) };
101
+ }
102
+ return undefined;
103
+ }
104
+ function parseBundleEntry(alias, value, prefix) {
105
+ const m = value.match(/^\[([\s\S]*)\]$/);
106
+ if (!m)
107
+ return undefined;
108
+ const members = [...m[1].matchAll(/"([^"]*)"/g)].map((mm) => mm[1]);
109
+ return { alias, accessor: bundleAccessorFor(alias, prefix), members };
110
+ }
111
+ function parsePluginEntry(alias, value, versions, prefix) {
112
+ const accessor = pluginAccessorFor(alias, prefix);
113
+ if (value.startsWith('"')) {
114
+ const m = value.match(/^"([^"]*)"$/);
115
+ if (!m)
116
+ return undefined;
117
+ const idx = m[1].lastIndexOf(':');
118
+ if (idx === -1)
119
+ return undefined;
120
+ const id = m[1].slice(0, idx);
121
+ const version = m[1].slice(idx + 1);
122
+ if (!id)
123
+ return undefined;
124
+ return { alias, accessor, id, version };
125
+ }
126
+ if (value.startsWith('{')) {
127
+ const id = extractString(value, 'id');
128
+ if (!id)
129
+ return undefined;
130
+ return { alias, accessor, id, version: resolveVersion(value, versions) };
131
+ }
132
+ return undefined;
133
+ }
134
+ /**
135
+ * Minimal parser for a Gradle version catalog TOML file: [versions],
136
+ * [libraries], [plugins] sections. Handles the entry shapes documented on
137
+ * CatalogLibrary/CatalogPlugin. Comments and blank lines are ignored;
138
+ * malformed entries are skipped rather than throwing. `prefix` is the
139
+ * catalog's Gradle accessor prefix ("libs" by default, or the name given to
140
+ * `versionCatalogs { create("name") { ... } }` for a custom catalog).
141
+ */
142
+ export function parseVersionCatalogText(toml, prefix = 'libs') {
143
+ const versions = new Map();
144
+ const libraries = [];
145
+ const plugins = [];
146
+ const bundles = [];
147
+ let section;
148
+ for (const rawLine of toml.split('\n')) {
149
+ const line = stripComment(rawLine).trim();
150
+ if (line === '')
151
+ continue;
152
+ const sectionMatch = line.match(/^\[(versions|libraries|plugins|bundles)\]$/);
153
+ if (sectionMatch) {
154
+ section = sectionMatch[1];
155
+ continue;
156
+ }
157
+ if (!section)
158
+ continue;
159
+ const eq = line.indexOf('=');
160
+ if (eq === -1)
161
+ continue;
162
+ const key = line.slice(0, eq).trim();
163
+ const value = line.slice(eq + 1).trim();
164
+ if (!/^[A-Za-z0-9_-]+$/.test(key))
165
+ continue;
166
+ if (section === 'versions') {
167
+ const m = value.match(/^"([^"]*)"$/);
168
+ if (m)
169
+ versions.set(key, m[1]);
170
+ continue;
171
+ }
172
+ if (section === 'libraries') {
173
+ const lib = parseLibraryEntry(key, value, versions, prefix);
174
+ if (lib)
175
+ libraries.push(lib);
176
+ continue;
177
+ }
178
+ if (section === 'plugins') {
179
+ const plugin = parsePluginEntry(key, value, versions, prefix);
180
+ if (plugin)
181
+ plugins.push(plugin);
182
+ continue;
183
+ }
184
+ if (section === 'bundles') {
185
+ const bundle = parseBundleEntry(key, value, prefix);
186
+ if (bundle)
187
+ bundles.push(bundle);
188
+ continue;
189
+ }
190
+ }
191
+ return { versions, libraries, plugins, bundles };
192
+ }
193
+ async function readTextOrUndefined(path) {
194
+ try {
195
+ return await readFile(path, 'utf8');
196
+ }
197
+ catch {
198
+ return undefined;
199
+ }
200
+ }
201
+ /**
202
+ * Parses `settings.gradle(.kts)` for additional named version catalogs
203
+ * declared via `versionCatalogs { create("name") { from(files("path")) } }`.
204
+ * Does not include the default "libs" catalog (see loadVersionCatalog).
205
+ */
206
+ export function parseCatalogDeclarations(settingsText) {
207
+ const results = [];
208
+ const createRe = /create\(\s*"([^"]+)"\s*\)\s*\{([\s\S]*?)\}/g;
209
+ let m;
210
+ while ((m = createRe.exec(settingsText))) {
211
+ const prefix = m[1];
212
+ const body = m[2];
213
+ const fromMatch = body.match(/from\(\s*files\(\s*"([^"]+)"\s*\)\s*\)/);
214
+ const tomlPath = fromMatch?.[1] ?? `gradle/${prefix}.versions.toml`;
215
+ results.push({ prefix, tomlPath });
216
+ }
217
+ return results;
218
+ }
219
+ /**
220
+ * Loads every version catalog available to the project: the default
221
+ * `gradle/libs.versions.toml` (prefix "libs") plus any custom catalogs
222
+ * declared in settings.gradle(.kts) via `versionCatalogs { create(...) }`.
223
+ * Returns a map keyed by accessor prefix; empty if none are present or
224
+ * parseable.
225
+ */
226
+ export async function loadVersionCatalog(projectDir) {
227
+ const result = new Map();
228
+ const defaultText = await readTextOrUndefined(join(projectDir, 'gradle', 'libs.versions.toml'));
229
+ if (defaultText !== undefined) {
230
+ try {
231
+ result.set('libs', parseVersionCatalogText(defaultText, 'libs'));
232
+ }
233
+ catch {
234
+ // Unparseable; leave the default catalog absent.
235
+ }
236
+ }
237
+ let settingsText;
238
+ for (const rel of ['settings.gradle.kts', 'settings.gradle']) {
239
+ settingsText = await readTextOrUndefined(join(projectDir, rel));
240
+ if (settingsText !== undefined)
241
+ break;
242
+ }
243
+ if (settingsText) {
244
+ for (const decl of parseCatalogDeclarations(settingsText)) {
245
+ if (result.has(decl.prefix))
246
+ continue;
247
+ const text = await readTextOrUndefined(join(projectDir, decl.tomlPath));
248
+ if (text === undefined)
249
+ continue;
250
+ try {
251
+ result.set(decl.prefix, parseVersionCatalogText(text, decl.prefix));
252
+ }
253
+ catch {
254
+ // Unparseable; skip this catalog.
255
+ }
256
+ }
257
+ }
258
+ return result;
259
+ }
260
+ function toCatalogArray(catalog) {
261
+ if (!catalog)
262
+ return [];
263
+ return Array.isArray(catalog) ? catalog : [catalog];
264
+ }
265
+ /**
266
+ * Determines the Gradle configuration (e.g. "testImplementation",
267
+ * "androidTestImplementation") whose declaration statement contains the
268
+ * match starting at `matchIndex`, by walking back from the match to the
269
+ * nearest identifier — handling both `config(coordinate)` and
270
+ * `config "coordinate"` styles, and leading whitespace. Returns undefined
271
+ * when no identifier immediately precedes the match (unrecognized style;
272
+ * treated as unknown rather than guessed).
273
+ */
274
+ function configurationForMatch(text, matchIndex) {
275
+ let searchEnd = matchIndex;
276
+ for (let hops = 0; hops < 5; hops++) {
277
+ const lineStart = text.lastIndexOf('\n', searchEnd - 1) + 1;
278
+ let prefix = text.slice(lineStart, searchEnd).trimEnd();
279
+ while (/[("',]$/.test(prefix)) {
280
+ prefix = prefix.slice(0, -1).trimEnd();
281
+ }
282
+ if (prefix === '') {
283
+ // Nothing useful on this line (e.g. the coordinate is on its own
284
+ // line inside a multi-line statement) — hop to the end of the
285
+ // previous line and keep looking for the configuration identifier.
286
+ if (lineStart === 0)
287
+ return undefined;
288
+ searchEnd = lineStart - 1;
289
+ continue;
290
+ }
291
+ const m = prefix.match(/([A-Za-z_][A-Za-z0-9_]*)$/);
292
+ return m?.[1];
293
+ }
294
+ return undefined;
295
+ }
296
+ /** Scans all matches of `regex` (must have the 'g' flag) against `text`, applying the configuration filter. */
297
+ function scan(text, regex, configurations) {
298
+ let disallowed;
299
+ for (const m of text.matchAll(regex)) {
300
+ if (!configurations)
301
+ return { kind: 'allowed', version: m[1] };
302
+ const configuration = configurationForMatch(text, m.index);
303
+ if (configuration === undefined || configurations.includes(configuration)) {
304
+ return { kind: 'allowed', version: m[1] };
305
+ }
306
+ if (!disallowed)
307
+ disallowed = { version: m[1], configuration };
308
+ }
309
+ return disallowed ? { kind: 'disallowed', ...disallowed } : { kind: 'none' };
310
+ }
311
+ /**
312
+ * Scans for a `group:name` coordinate in either its plain string form
313
+ * (`"group:name[:version]"`, Kotlin or Groovy) or Groovy's map form
314
+ * (`group: 'g', name: 'n'[, version: 'v']`).
315
+ */
316
+ function scanLibraryLiteral(text, group, name, configurations) {
317
+ const coordRe = new RegExp(`${escapeRegExp(`${group}:${name}`)}(?::([0-9][^"'\\s),]*))?`, 'g');
318
+ const coordScan = scan(text, coordRe, configurations);
319
+ if (coordScan.kind === 'allowed')
320
+ return coordScan;
321
+ const mapRe = new RegExp(`group:\\s*['"]${escapeRegExp(group)}['"]\\s*,\\s*name:\\s*['"]${escapeRegExp(name)}['"](?:\\s*,\\s*version:\\s*['"]([^'"]+)['"])?`, 'g');
322
+ const mapScan = scan(text, mapRe, configurations);
323
+ if (mapScan.kind === 'allowed')
324
+ return mapScan;
325
+ return coordScan.kind === 'disallowed' ? coordScan : mapScan;
326
+ }
327
+ /**
328
+ * Looks up a `group:name` Maven coordinate in raw Gradle build-file text,
329
+ * either as a literal coordinate string or, if a version catalog (or list of
330
+ * catalogs) is supplied, via a `<prefix>.*` accessor that resolves to that
331
+ * group:name. With `options.configurations` set, a match declared under a
332
+ * configuration outside that list (e.g. androidTestImplementation when only
333
+ * testImplementation etc. were requested) is reported as
334
+ * `via: 'wrong-configuration'` instead of `found: true`.
335
+ */
336
+ export function findLibrary(gradleText, catalog, group, name, options = {}) {
337
+ const { configurations } = options;
338
+ const literalScan = scanLibraryLiteral(gradleText, group, name, configurations);
339
+ if (literalScan.kind === 'allowed') {
340
+ return { found: true, version: literalScan.version, via: 'literal' };
341
+ }
342
+ let disallowed = literalScan.kind === 'disallowed'
343
+ ? { version: literalScan.version, configuration: literalScan.configuration }
344
+ : undefined;
345
+ for (const cat of toCatalogArray(catalog)) {
346
+ for (const lib of cat.libraries) {
347
+ if (lib.group !== group || lib.name !== name)
348
+ continue;
349
+ const accessorRe = new RegExp(`(?<![\\w.])${escapeRegExp(lib.accessor)}(?![\\w.])`, 'g');
350
+ const catScan = scan(gradleText, accessorRe, configurations);
351
+ if (catScan.kind === 'allowed') {
352
+ return { found: true, version: lib.version, via: 'catalog' };
353
+ }
354
+ if (catScan.kind === 'disallowed' && !disallowed) {
355
+ disallowed = { version: lib.version, configuration: catScan.configuration };
356
+ }
357
+ }
358
+ for (const bundle of cat.bundles) {
359
+ const memberLib = cat.libraries.find((lib) => bundle.members.includes(lib.alias) && lib.group === group && lib.name === name);
360
+ if (!memberLib)
361
+ continue;
362
+ const accessorRe = new RegExp(`(?<![\\w.])${escapeRegExp(bundle.accessor)}(?![\\w.])`, 'g');
363
+ const bundleScan = scan(gradleText, accessorRe, configurations);
364
+ if (bundleScan.kind === 'allowed') {
365
+ return { found: true, version: memberLib.version, via: 'catalog' };
366
+ }
367
+ if (bundleScan.kind === 'disallowed' && !disallowed) {
368
+ disallowed = { version: memberLib.version, configuration: bundleScan.configuration };
369
+ }
370
+ }
371
+ }
372
+ if (disallowed) {
373
+ return { found: false, via: 'wrong-configuration', version: disallowed.version, foundConfiguration: disallowed.configuration };
374
+ }
375
+ return { found: false, via: 'none' };
376
+ }
377
+ /**
378
+ * Looks up a Gradle plugin id in raw build-file text: as `id("x")` /
379
+ * `id 'x'` (optionally with `version "y"` on the same line), as the Gradle
380
+ * plugin marker dependency coordinate (`pluginId:pluginId.gradle.plugin[:version]`),
381
+ * or, if a version catalog (or list of catalogs) is supplied, via a
382
+ * `<prefix>.plugins.*` accessor.
383
+ */
384
+ export function findPlugin(gradleText, catalog, pluginId) {
385
+ const idEscaped = escapeRegExp(pluginId);
386
+ const idPatterns = [
387
+ new RegExp(`id\\(\\s*["']${idEscaped}["']\\s*\\)(?:\\s+version\\s+["']([^"']+)["'])?`),
388
+ new RegExp(`id\\s+["']${idEscaped}["'](?:\\s+version\\s+["']([^"']+)["'])?`),
389
+ // Legacy Groovy application: apply plugin: 'x.y.z' (no version on this form).
390
+ new RegExp(`apply\\s+plugin:\\s*["']${idEscaped}["']`),
391
+ ];
392
+ for (const pattern of idPatterns) {
393
+ const m = gradleText.match(pattern);
394
+ if (m)
395
+ return { found: true, version: m[1], via: 'literal' };
396
+ }
397
+ // buildscript { dependencies { classpath "<pluginId>:<artifact>:<version>" } }.
398
+ // Matched on group only — the artifact (e.g. "roborazzi-gradle-plugin") doesn't
399
+ // have to equal the plugin id.
400
+ const classpathRe = new RegExp(`${idEscaped}:[A-Za-z0-9_.-]+(?::([0-9][^"'\\s),]*))?`);
401
+ const classpathMatch = gradleText.match(classpathRe);
402
+ if (classpathMatch)
403
+ return { found: true, version: classpathMatch[1], via: 'literal' };
404
+ for (const cat of toCatalogArray(catalog)) {
405
+ for (const plugin of cat.plugins) {
406
+ if (plugin.id === pluginId && accessorAppears(gradleText, plugin.accessor)) {
407
+ return { found: true, version: plugin.version, via: 'catalog' };
408
+ }
409
+ }
410
+ }
411
+ return { found: false, via: 'none' };
412
+ }
413
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/gradle/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA+BjC,wEAAwE;AACxE,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,oBAAoB;IACpB,yBAAyB;IACzB,2BAA2B;IAC3B,SAAS;IACT,iBAAiB;IACjB,gBAAgB;IAChB,KAAK;CACN,CAAC;AAEF,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,MAAM,GAAG,MAAM;IACxD,OAAO,GAAG,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;AACpD,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,MAAM,GAAG,MAAM;IAC9D,OAAO,GAAG,MAAM,YAAY,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,MAAM,GAAG,MAAM;IAC9D,OAAO,GAAG,MAAM,YAAY,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB;IAC5D,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,cAAc,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACxE,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,8DAA8D;AAC9D,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG;YAAE,QAAQ,GAAG,CAAC,QAAQ,CAAC;aAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4DAA4D;AAC5D,SAAS,aAAa,CAAC,IAAY,EAAE,KAAa;IAChD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,oBAAoB,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAChB,CAAC;AAED,yFAAyF;AACzF,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC5D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACjF,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,iFAAiF;AACjF,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,QAA6B;IACjE,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChD,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAa,EACb,KAAa,EACb,QAA6B,EAC7B,MAAc;IAEd,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QACzB,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,KAAK,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,IAAI,GAAG,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACxC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC7B,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;IACpF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,KAAa,EAAE,MAAc;IACpE,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACzC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAa,EACb,KAAa,EACb,QAA6B,EAC7B,MAAc;IAEd,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QACjC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC3E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,MAAM,GAAG,MAAM;IACnE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,SAAS,GAAqB,EAAE,CAAC;IACvC,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,IAAI,OAAqE,CAAC;IAC1E,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,IAAI,IAAI,KAAK,EAAE;YAAE,SAAS;QAE1B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC9E,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,GAAG,YAAY,CAAC,CAAC,CAAqD,CAAC;YAC9E,SAAS;QACX,CAAC;QACD,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,SAAS;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5C,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACrC,IAAI,CAAC;gBAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC5D,IAAI,GAAG;gBAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9D,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YACpD,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAY;IAC7C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AASD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,YAAoB;IAC3D,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,6CAA6C,CAAC;IAC/D,IAAI,CAAyB,CAAC;IAC9B,OAAO,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACvE,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,MAAM,gBAAgB,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IACzD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEjD,MAAM,WAAW,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAChG,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACP,iDAAiD;QACnD,CAAC;IACH,CAAC;IAED,IAAI,YAAgC,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC7D,YAAY,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,YAAY,KAAK,SAAS;YAAE,MAAM;IACxC,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,IAAI,IAAI,wBAAwB,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1D,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS;YACtC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACxE,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACtE,CAAC;YAAC,MAAM,CAAC;gBACP,kCAAkC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AA2BD,SAAS,cAAc,CAAC,OAAqB;IAC3C,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,qBAAqB,CAAC,IAAY,EAAE,UAAkB;IAC7D,IAAI,SAAS,GAAG,UAAU,CAAC;IAC3B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAC5D,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACzC,CAAC;QACD,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YAClB,iEAAiE;YACjE,8DAA8D;YAC9D,mEAAmE;YACnE,IAAI,SAAS,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACtC,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACpD,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAOD,+GAA+G;AAC/G,SAAS,IAAI,CAAC,IAAY,EAAE,KAAa,EAAE,cAAyB;IAClE,IAAI,UAAmE,CAAC;IACxE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,cAAc;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,aAAa,GAAG,qBAAqB,CAAC,IAAI,EAAE,CAAC,CAAC,KAAM,CAAC,CAAC;QAC5D,IAAI,aAAa,KAAK,SAAS,IAAI,cAAc,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,UAAU;YAAE,UAAU,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC;IACjE,CAAC;IACD,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,IAAY,EAAE,KAAa,EAAE,IAAY,EAAE,cAAyB;IAC9F,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;IAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAEnD,MAAM,KAAK,GAAG,IAAI,MAAM,CACtB,iBAAiB,YAAY,CAAC,KAAK,CAAC,6BAA6B,YAAY,CAAC,IAAI,CAAC,gDAAgD,EACnI,GAAG,CACJ,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IAE/C,OAAO,SAAS,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CACzB,UAAkB,EAClB,OAAqB,EACrB,KAAa,EACb,IAAY,EACZ,UAA8B,EAAE;IAEhC,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IACnC,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAChF,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,UAAU,GACZ,WAAW,CAAC,IAAI,KAAK,YAAY;QAC/B,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,aAAa,EAAE;QAC5E,CAAC,CAAC,SAAS,CAAC;IAEhB,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI;gBAAE,SAAS;YACvD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,cAAc,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YACzF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;YAC7D,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YAC/D,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC;gBACjD,UAAU,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;YAC9E,CAAC;QACH,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,CAClC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CACxF,CAAC;YACF,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,cAAc,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YAC5F,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;YAChE,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YACrE,CAAC;YACD,IAAI,UAAU,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpD,UAAU,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC;YACvF,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,CAAC,aAAa,EAAE,CAAC;IACjI,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,UAAkB,EAAE,OAAqB,EAAE,QAAgB;IACpF,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG;QACjB,IAAI,MAAM,CAAC,gBAAgB,SAAS,iDAAiD,CAAC;QACtF,IAAI,MAAM,CAAC,aAAa,SAAS,0CAA0C,CAAC;QAC5E,8EAA8E;QAC9E,IAAI,MAAM,CAAC,2BAA2B,SAAS,MAAM,CAAC;KACvD,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IAC/D,CAAC;IAED,gFAAgF;IAChF,gFAAgF;IAChF,+BAA+B;IAC/B,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,GAAG,SAAS,0CAA0C,CAAC,CAAC;IACvF,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrD,IAAI,cAAc;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IAEvF,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,MAAM,CAAC,EAAE,KAAK,QAAQ,IAAI,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YAClE,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC"}