@abapify/openai-codegen 0.3.6 → 0.4.6
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/cli.d.mts +44 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +116 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/generate-BobARM00.mjs +2957 -0
- package/dist/generate-BobARM00.mjs.map +1 -0
- package/dist/index.d.mts +496 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +224 -0
- package/dist/index.mjs.map +1 -0
- package/dist/naming-9hJCZKjv.d.mts +47 -0
- package/dist/naming-9hJCZKjv.d.mts.map +1 -0
- package/package.json +4 -3
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { r as ResolvedNames, t as NamesConfig } from "./naming-9hJCZKjv.mjs";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
//#region src/cli.d.ts
|
|
4
|
+
declare const SUPPORTED_FORMATS: readonly ["abapgit", "gcts"];
|
|
5
|
+
type SupportedFormat = (typeof SUPPORTED_FORMATS)[number];
|
|
6
|
+
/**
|
|
7
|
+
* CLI-facing resolved options shape. Exposes both the raw {@link NamesConfig}
|
|
8
|
+
* (to pass to `generate()`) and the resolved names (so tests / callers can
|
|
9
|
+
* inspect final artifact names without re-resolving).
|
|
10
|
+
*/
|
|
11
|
+
interface GenerateOptions {
|
|
12
|
+
input: string;
|
|
13
|
+
out: string;
|
|
14
|
+
namesConfig: NamesConfig;
|
|
15
|
+
names: ResolvedNames;
|
|
16
|
+
formats: readonly SupportedFormat[];
|
|
17
|
+
target: 's4-cloud' | 's4-onprem-modern' | 'on-prem-classic';
|
|
18
|
+
description?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Alias kept for newer code that prefers a run-style name. */
|
|
21
|
+
type CliRunOptions = GenerateOptions;
|
|
22
|
+
interface RawCliOptions {
|
|
23
|
+
input?: string;
|
|
24
|
+
out?: string;
|
|
25
|
+
base?: string;
|
|
26
|
+
typesInterface?: string;
|
|
27
|
+
operationsInterface?: string;
|
|
28
|
+
className?: string;
|
|
29
|
+
exceptionClass?: string;
|
|
30
|
+
format?: string;
|
|
31
|
+
target?: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}
|
|
34
|
+
declare function buildCliRunOptions(raw: RawCliOptions): CliRunOptions;
|
|
35
|
+
/**
|
|
36
|
+
* Back-compat shim: older callers used `buildGenerateOptions` and relied on
|
|
37
|
+
* the `GenerateOptions` export. Keep both names working — the modern path
|
|
38
|
+
* is `buildCliRunOptions`.
|
|
39
|
+
*/
|
|
40
|
+
declare const buildGenerateOptions: typeof buildCliRunOptions;
|
|
41
|
+
declare function buildProgram(): Command;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { CliRunOptions, GenerateOptions, SupportedFormat, buildCliRunOptions, buildGenerateOptions, buildProgram };
|
|
44
|
+
//# sourceMappingURL=cli.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.mts","names":[],"sources":["../src/cli.ts"],"mappings":";;;cAkBM;KACM,0BAA0B;;;;;;UAOrB;EACf;EACA;EACA,aAAa;EACb,OAAO;EACP,kBAAkB;EAClB;EACA;;;KAIU,gBAAgB;UAElB;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAyCc,mBAAmB,KAAK,gBAAgB;;;;;;cAsC3C,6BAAoB;iBAEjB,gBAAgB"}
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { h as resolveNames, m as NamesConfigError, t as generate } from "./generate-BobARM00.mjs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { Command, InvalidArgumentError, Option } from "commander";
|
|
5
|
+
|
|
6
|
+
//#region src/cli.ts
|
|
7
|
+
/**
|
|
8
|
+
* openai-codegen CLI (v2).
|
|
9
|
+
*
|
|
10
|
+
* Parses command-line flags and calls the `generate()` pipeline for each
|
|
11
|
+
* requested output format.
|
|
12
|
+
*/
|
|
13
|
+
const SUPPORTED_FORMATS = ["abapgit", "gcts"];
|
|
14
|
+
function parseFormats(raw) {
|
|
15
|
+
const parts = raw.split(",").map((p) => p.trim().toLowerCase()).filter((p) => p.length > 0);
|
|
16
|
+
if (parts.length === 0) throw new InvalidArgumentError("at least one format is required (abapgit, gcts).");
|
|
17
|
+
const result = [];
|
|
18
|
+
for (const p of parts) {
|
|
19
|
+
if (!SUPPORTED_FORMATS.includes(p)) throw new InvalidArgumentError(`unknown format "${p}" (supported: ${SUPPORTED_FORMATS.join(", ")}).`);
|
|
20
|
+
if (!result.includes(p)) result.push(p);
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
function parseTarget(raw) {
|
|
25
|
+
const normalized = raw.trim().toLowerCase();
|
|
26
|
+
if (normalized !== "s4-cloud" && normalized !== "s4-onprem-modern" && normalized !== "on-prem-classic") throw new InvalidArgumentError(`unknown target "${raw}" (supported: s4-cloud, s4-onprem-modern, on-prem-classic).`);
|
|
27
|
+
return normalized;
|
|
28
|
+
}
|
|
29
|
+
function buildCliRunOptions(raw) {
|
|
30
|
+
if (!raw.input) throw new Error("--input is required.");
|
|
31
|
+
if (!raw.out) throw new Error("--out is required.");
|
|
32
|
+
const namesConfig = {
|
|
33
|
+
base: raw.base,
|
|
34
|
+
typesInterface: raw.typesInterface,
|
|
35
|
+
operationsInterface: raw.operationsInterface,
|
|
36
|
+
implementationClass: raw.className,
|
|
37
|
+
exceptionClass: raw.exceptionClass
|
|
38
|
+
};
|
|
39
|
+
const names = resolveNames(namesConfig);
|
|
40
|
+
const formats = parseFormats(raw.format ?? "abapgit");
|
|
41
|
+
const target = parseTarget(raw.target ?? "s4-cloud");
|
|
42
|
+
return {
|
|
43
|
+
input: raw.input,
|
|
44
|
+
out: raw.out,
|
|
45
|
+
namesConfig,
|
|
46
|
+
names,
|
|
47
|
+
formats,
|
|
48
|
+
target,
|
|
49
|
+
description: raw.description
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Back-compat shim: older callers used `buildGenerateOptions` and relied on
|
|
54
|
+
* the `GenerateOptions` export. Keep both names working — the modern path
|
|
55
|
+
* is `buildCliRunOptions`.
|
|
56
|
+
*/
|
|
57
|
+
const buildGenerateOptions = buildCliRunOptions;
|
|
58
|
+
function buildProgram() {
|
|
59
|
+
const program = new Command();
|
|
60
|
+
program.name("openai-codegen").description("Deterministic OpenAPI -> ABAP client code generator (v2 pipeline).").requiredOption("--input <path>", "path to the OpenAPI spec (YAML or JSON)").requiredOption("--out <dir>", "output directory").option("--base <name>", "logical base name used to derive ZCL_<BASE> / ZIF_<BASE> / ZCX_<BASE>_ERROR").option("--types-interface <name>", "override for the types interface name (default: ZIF_<BASE>_TYPES)").option("--operations-interface <name>", "override for the operations interface name (default: ZIF_<BASE>)").option("--class-name <name>", "override for the implementation class name (default: ZCL_<BASE>)").option("--exception-class <name>", "override for the exception class name (default: ZCX_<BASE>_ERROR)").addOption(new Option("--format <list>", "comma-separated output formats (abapgit, gcts)").default("abapgit")).option("--target <profile>", "target profile (e.g. s4-cloud)", "s4-cloud").option("--description <text>", "description stored in the generated CLAS/INTF XML").action(async (opts) => {
|
|
61
|
+
const runOptions = buildCliRunOptions(opts);
|
|
62
|
+
const baseOutDir = resolve(process.cwd(), runOptions.out);
|
|
63
|
+
const results = [];
|
|
64
|
+
for (const format of runOptions.formats) {
|
|
65
|
+
const formatOutDir = runOptions.formats.length === 1 ? baseOutDir : resolve(baseOutDir, format);
|
|
66
|
+
const genOpts = {
|
|
67
|
+
input: runOptions.input,
|
|
68
|
+
outDir: formatOutDir,
|
|
69
|
+
format,
|
|
70
|
+
target: runOptions.target,
|
|
71
|
+
names: runOptions.namesConfig,
|
|
72
|
+
description: runOptions.description
|
|
73
|
+
};
|
|
74
|
+
const result = await generate(genOpts);
|
|
75
|
+
results.push({
|
|
76
|
+
format,
|
|
77
|
+
result
|
|
78
|
+
});
|
|
79
|
+
process.stdout.write(`[openai-codegen] ${format}: wrote ${result.files.length} files (${result.typeCount} types, ${result.operationCount} operations) -> ${formatOutDir}\n`);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
program.exitOverride();
|
|
83
|
+
return program;
|
|
84
|
+
}
|
|
85
|
+
async function main(argv) {
|
|
86
|
+
const program = buildProgram();
|
|
87
|
+
try {
|
|
88
|
+
await program.parseAsync(argv);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
if (err instanceof NamesConfigError) {
|
|
91
|
+
process.stderr.write(`error: ${err.message}\n`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
const anyErr = err;
|
|
95
|
+
if (anyErr.code === "commander.helpDisplayed" || anyErr.code === "commander.version" || anyErr.code === "commander.help") return;
|
|
96
|
+
if (anyErr.code?.startsWith("commander.")) process.exit(1);
|
|
97
|
+
process.stderr.write(`error: ${anyErr.message ?? (err instanceof Error ? err.message : String(err))}\n`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if ((() => {
|
|
102
|
+
try {
|
|
103
|
+
const entry = process.argv[1];
|
|
104
|
+
if (!entry) return false;
|
|
105
|
+
const url = import.meta.url;
|
|
106
|
+
if (!url.startsWith("file:")) return false;
|
|
107
|
+
const urlPath = decodeURIComponent(new URL(url).pathname);
|
|
108
|
+
return urlPath === entry || urlPath.endsWith("/cli.mjs");
|
|
109
|
+
} catch {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
})()) main(process.argv);
|
|
113
|
+
|
|
114
|
+
//#endregion
|
|
115
|
+
export { buildCliRunOptions, buildGenerateOptions, buildProgram };
|
|
116
|
+
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["resolvePath"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * openai-codegen CLI (v2).\n *\n * Parses command-line flags and calls the `generate()` pipeline for each\n * requested output format.\n */\n\nimport { Command, Option, InvalidArgumentError } from 'commander';\nimport { resolveNames, NamesConfigError } from './emit/naming';\nimport type { NamesConfig, ResolvedNames } from './emit/naming';\nimport {\n generate,\n type GenerateOptions as PipelineGenerateOptions,\n type GenerateResult,\n} from './generate';\nimport { resolve as resolvePath } from 'node:path';\n\nconst SUPPORTED_FORMATS = ['abapgit', 'gcts'] as const;\nexport type SupportedFormat = (typeof SUPPORTED_FORMATS)[number];\n\n/**\n * CLI-facing resolved options shape. Exposes both the raw {@link NamesConfig}\n * (to pass to `generate()`) and the resolved names (so tests / callers can\n * inspect final artifact names without re-resolving).\n */\nexport interface GenerateOptions {\n input: string;\n out: string;\n namesConfig: NamesConfig;\n names: ResolvedNames;\n formats: readonly SupportedFormat[];\n target: 's4-cloud' | 's4-onprem-modern' | 'on-prem-classic';\n description?: string;\n}\n\n/** Alias kept for newer code that prefers a run-style name. */\nexport type CliRunOptions = GenerateOptions;\n\ninterface RawCliOptions {\n input?: string;\n out?: string;\n base?: string;\n typesInterface?: string;\n operationsInterface?: string;\n className?: string;\n exceptionClass?: string;\n format?: string;\n target?: string;\n description?: string;\n}\n\nfunction parseFormats(raw: string): SupportedFormat[] {\n const parts = raw\n .split(',')\n .map((p) => p.trim().toLowerCase())\n .filter((p) => p.length > 0);\n if (parts.length === 0) {\n throw new InvalidArgumentError(\n 'at least one format is required (abapgit, gcts).',\n );\n }\n const result: SupportedFormat[] = [];\n for (const p of parts) {\n if (!(SUPPORTED_FORMATS as readonly string[]).includes(p)) {\n throw new InvalidArgumentError(\n `unknown format \"${p}\" (supported: ${SUPPORTED_FORMATS.join(', ')}).`,\n );\n }\n if (!result.includes(p as SupportedFormat)) {\n result.push(p as SupportedFormat);\n }\n }\n return result;\n}\n\nfunction parseTarget(raw: string): CliRunOptions['target'] {\n const normalized = raw.trim().toLowerCase();\n if (\n normalized !== 's4-cloud' &&\n normalized !== 's4-onprem-modern' &&\n normalized !== 'on-prem-classic'\n ) {\n throw new InvalidArgumentError(\n `unknown target \"${raw}\" (supported: s4-cloud, s4-onprem-modern, on-prem-classic).`,\n );\n }\n return normalized as CliRunOptions['target'];\n}\n\nexport function buildCliRunOptions(raw: RawCliOptions): CliRunOptions {\n if (!raw.input) {\n throw new Error('--input is required.');\n }\n if (!raw.out) {\n throw new Error('--out is required.');\n }\n\n const namesConfig: NamesConfig = {\n base: raw.base,\n typesInterface: raw.typesInterface,\n operationsInterface: raw.operationsInterface,\n implementationClass: raw.className,\n exceptionClass: raw.exceptionClass,\n };\n // Validate and resolve eagerly so the CLI fails fast with a useful message\n // AND so tests / downstream code can read resolved global names via `.names`.\n const names = resolveNames(namesConfig);\n\n const formats = parseFormats(raw.format ?? 'abapgit');\n const target = parseTarget(raw.target ?? 's4-cloud');\n\n return {\n input: raw.input,\n out: raw.out,\n namesConfig,\n names,\n formats,\n target,\n description: raw.description,\n };\n}\n\n/**\n * Back-compat shim: older callers used `buildGenerateOptions` and relied on\n * the `GenerateOptions` export. Keep both names working — the modern path\n * is `buildCliRunOptions`.\n */\nexport const buildGenerateOptions = buildCliRunOptions;\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name('openai-codegen')\n .description(\n 'Deterministic OpenAPI -> ABAP client code generator (v2 pipeline).',\n )\n .requiredOption('--input <path>', 'path to the OpenAPI spec (YAML or JSON)')\n .requiredOption('--out <dir>', 'output directory')\n .option(\n '--base <name>',\n 'logical base name used to derive ZCL_<BASE> / ZIF_<BASE> / ZCX_<BASE>_ERROR',\n )\n .option(\n '--types-interface <name>',\n 'override for the types interface name (default: ZIF_<BASE>_TYPES)',\n )\n .option(\n '--operations-interface <name>',\n 'override for the operations interface name (default: ZIF_<BASE>)',\n )\n .option(\n '--class-name <name>',\n 'override for the implementation class name (default: ZCL_<BASE>)',\n )\n .option(\n '--exception-class <name>',\n 'override for the exception class name (default: ZCX_<BASE>_ERROR)',\n )\n .addOption(\n new Option(\n '--format <list>',\n 'comma-separated output formats (abapgit, gcts)',\n ).default('abapgit'),\n )\n .option('--target <profile>', 'target profile (e.g. s4-cloud)', 's4-cloud')\n .option(\n '--description <text>',\n 'description stored in the generated CLAS/INTF XML',\n )\n .action(async (opts: RawCliOptions) => {\n const runOptions = buildCliRunOptions(opts);\n const baseOutDir = resolvePath(process.cwd(), runOptions.out);\n const results: Array<{\n format: SupportedFormat;\n result: GenerateResult;\n }> = [];\n for (const format of runOptions.formats) {\n const formatOutDir =\n runOptions.formats.length === 1\n ? baseOutDir\n : resolvePath(baseOutDir, format);\n const genOpts: PipelineGenerateOptions = {\n input: runOptions.input,\n outDir: formatOutDir,\n format,\n target: runOptions.target,\n names: runOptions.namesConfig,\n description: runOptions.description,\n };\n const result = await generate(genOpts);\n results.push({ format, result });\n process.stdout.write(\n `[openai-codegen] ${format}: wrote ${result.files.length} files ` +\n `(${result.typeCount} types, ${result.operationCount} operations) ` +\n `-> ${formatOutDir}\\n`,\n );\n }\n });\n\n // Do not let commander terminate the process during tests.\n program.exitOverride();\n return program;\n}\n\nasync function main(argv: string[]): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(argv);\n } catch (err) {\n if (err instanceof NamesConfigError) {\n process.stderr.write(`error: ${err.message}\\n`);\n process.exit(1);\n }\n const anyErr = err as { code?: string; message?: string };\n if (\n anyErr.code === 'commander.helpDisplayed' ||\n anyErr.code === 'commander.version' ||\n anyErr.code === 'commander.help'\n ) {\n return;\n }\n if (anyErr.code?.startsWith('commander.')) {\n process.exit(1);\n }\n process.stderr.write(\n `error: ${anyErr.message ?? (err instanceof Error ? err.message : String(err))}\\n`,\n );\n process.exit(1);\n }\n}\n\n// Only run when invoked directly.\nconst invokedDirectly = (() => {\n try {\n const entry = process.argv[1];\n if (!entry) return false;\n const url = import.meta.url;\n if (!url.startsWith('file:')) return false;\n const urlPath = decodeURIComponent(new URL(url).pathname);\n return urlPath === entry || urlPath.endsWith('/cli.mjs');\n } catch {\n return false;\n }\n})();\n\nif (invokedDirectly) {\n void main(process.argv);\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAM,oBAAoB,CAAC,WAAW,MAAM;AAkC5C,SAAS,aAAa,KAAgC;CACpD,MAAM,QAAQ,IACX,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAClC,QAAQ,MAAM,EAAE,SAAS,CAAC;CAC7B,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,qBACR,kDACF;CAEF,MAAM,SAA4B,CAAC;CACnC,KAAK,MAAM,KAAK,OAAO;EACrB,IAAI,CAAE,kBAAwC,SAAS,CAAC,GACtD,MAAM,IAAI,qBACR,mBAAmB,EAAE,gBAAgB,kBAAkB,KAAK,IAAI,EAAE,GACpE;EAEF,IAAI,CAAC,OAAO,SAAS,CAAoB,GACvC,OAAO,KAAK,CAAoB;CAEpC;CACA,OAAO;AACT;AAEA,SAAS,YAAY,KAAsC;CACzD,MAAM,aAAa,IAAI,KAAK,CAAC,CAAC,YAAY;CAC1C,IACE,eAAe,cACf,eAAe,sBACf,eAAe,mBAEf,MAAM,IAAI,qBACR,mBAAmB,IAAI,4DACzB;CAEF,OAAO;AACT;AAEA,SAAgB,mBAAmB,KAAmC;CACpE,IAAI,CAAC,IAAI,OACP,MAAM,IAAI,MAAM,sBAAsB;CAExC,IAAI,CAAC,IAAI,KACP,MAAM,IAAI,MAAM,oBAAoB;CAGtC,MAAM,cAA2B;EAC/B,MAAM,IAAI;EACV,gBAAgB,IAAI;EACpB,qBAAqB,IAAI;EACzB,qBAAqB,IAAI;EACzB,gBAAgB,IAAI;CACtB;CAGA,MAAM,QAAQ,aAAa,WAAW;CAEtC,MAAM,UAAU,aAAa,IAAI,UAAU,SAAS;CACpD,MAAM,SAAS,YAAY,IAAI,UAAU,UAAU;CAEnD,OAAO;EACL,OAAO,IAAI;EACX,KAAK,IAAI;EACT;EACA;EACA;EACA;EACA,aAAa,IAAI;CACnB;AACF;;;;;;AAOA,MAAa,uBAAuB;AAEpC,SAAgB,eAAwB;CACtC,MAAM,UAAU,IAAI,QAAQ;CAC5B,QACG,KAAK,gBAAgB,CAAC,CACtB,YACC,oEACF,CAAC,CACA,eAAe,kBAAkB,yCAAyC,CAAC,CAC3E,eAAe,eAAe,kBAAkB,CAAC,CACjD,OACC,iBACA,6EACF,CAAC,CACA,OACC,4BACA,mEACF,CAAC,CACA,OACC,iCACA,kEACF,CAAC,CACA,OACC,uBACA,kEACF,CAAC,CACA,OACC,4BACA,mEACF,CAAC,CACA,UACC,IAAI,OACF,mBACA,gDACF,CAAC,CAAC,QAAQ,SAAS,CACrB,CAAC,CACA,OAAO,sBAAsB,kCAAkC,UAAU,CAAC,CAC1E,OACC,wBACA,mDACF,CAAC,CACA,OAAO,OAAO,SAAwB;EACrC,MAAM,aAAa,mBAAmB,IAAI;EAC1C,MAAM,aAAaA,QAAY,QAAQ,IAAI,GAAG,WAAW,GAAG;EAC5D,MAAM,UAGD,CAAC;EACN,KAAK,MAAM,UAAU,WAAW,SAAS;GACvC,MAAM,eACJ,WAAW,QAAQ,WAAW,IAC1B,aACAA,QAAY,YAAY,MAAM;GACpC,MAAM,UAAmC;IACvC,OAAO,WAAW;IAClB,QAAQ;IACR;IACA,QAAQ,WAAW;IACnB,OAAO,WAAW;IAClB,aAAa,WAAW;GAC1B;GACA,MAAM,SAAS,MAAM,SAAS,OAAO;GACrC,QAAQ,KAAK;IAAE;IAAQ;GAAO,CAAC;GAC/B,QAAQ,OAAO,MACb,oBAAoB,OAAO,UAAU,OAAO,MAAM,OAAO,UACnD,OAAO,UAAU,UAAU,OAAO,eAAe,kBAC/C,aAAa,GACvB;EACF;CACF,CAAC;CAGH,QAAQ,aAAa;CACrB,OAAO;AACT;AAEA,eAAe,KAAK,MAA+B;CACjD,MAAM,UAAU,aAAa;CAC7B,IAAI;EACF,MAAM,QAAQ,WAAW,IAAI;CAC/B,SAAS,KAAK;EACZ,IAAI,eAAe,kBAAkB;GACnC,QAAQ,OAAO,MAAM,UAAU,IAAI,QAAQ,GAAG;GAC9C,QAAQ,KAAK,CAAC;EAChB;EACA,MAAM,SAAS;EACf,IACE,OAAO,SAAS,6BAChB,OAAO,SAAS,uBAChB,OAAO,SAAS,kBAEhB;EAEF,IAAI,OAAO,MAAM,WAAW,YAAY,GACtC,QAAQ,KAAK,CAAC;EAEhB,QAAQ,OAAO,MACb,UAAU,OAAO,YAAY,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAAG,GACjF;EACA,QAAQ,KAAK,CAAC;CAChB;AACF;AAgBA,WAb+B;CAC7B,IAAI;EACF,MAAM,QAAQ,QAAQ,KAAK;EAC3B,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,MAAM,YAAY;EACxB,IAAI,CAAC,IAAI,WAAW,OAAO,GAAG,OAAO;EACrC,MAAM,UAAU,mBAAmB,IAAI,IAAI,GAAG,CAAC,CAAC,QAAQ;EACxD,OAAO,YAAY,SAAS,QAAQ,SAAS,UAAU;CACzD,QAAQ;EACN,OAAO;CACT;AACF,EAAC,CAEiB,GAChB,AAAK,KAAK,QAAQ,IAAI"}
|