qfai 0.4.2 → 0.4.4
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/README.md +14 -0
- package/assets/init/.qfai/README.md +1 -0
- package/assets/init/.qfai/contracts/README.md +17 -8
- package/assets/init/.qfai/contracts/api/api-0001-sample.yaml +3 -2
- package/assets/init/.qfai/contracts/db/db-0001-sample.sql +2 -1
- package/assets/init/.qfai/contracts/ui/ui-0001-sample.yaml +3 -1
- package/assets/init/.qfai/promptpack/modes/change.md +3 -2
- package/assets/init/.qfai/promptpack/modes/compatibility.md +2 -0
- package/assets/init/.qfai/prompts/require-to-spec.md +4 -2
- package/assets/init/.qfai/specs/README.md +9 -2
- package/assets/init/.qfai/specs/spec-0001/spec.md +2 -0
- package/assets/init/root/qfai.config.yaml +0 -1
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +30 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/report.d.ts +7 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +80 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +9 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +57 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.cjs +504 -328
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +504 -328
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib/args.d.ts +18 -0
- package/dist/cli/lib/args.d.ts.map +1 -0
- package/dist/cli/lib/args.js +98 -0
- package/dist/cli/lib/args.js.map +1 -0
- package/dist/cli/lib/assets.d.ts +2 -0
- package/dist/cli/lib/assets.d.ts.map +1 -0
- package/dist/cli/lib/assets.js +24 -0
- package/dist/cli/lib/assets.js.map +1 -0
- package/dist/cli/lib/failOn.d.ts +5 -0
- package/dist/cli/lib/failOn.d.ts.map +1 -0
- package/dist/cli/lib/failOn.js +10 -0
- package/dist/cli/lib/failOn.js.map +1 -0
- package/dist/cli/lib/fs.d.ts +11 -0
- package/dist/cli/lib/fs.d.ts.map +1 -0
- package/dist/cli/lib/fs.js +91 -0
- package/dist/cli/lib/fs.js.map +1 -0
- package/dist/cli/lib/logger.d.ts +4 -0
- package/dist/cli/lib/logger.d.ts.map +1 -0
- package/dist/cli/lib/logger.js +10 -0
- package/dist/cli/lib/logger.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +66 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/core/config.d.ts +47 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +224 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contractIndex.d.ts +12 -0
- package/dist/core/contractIndex.d.ts.map +1 -0
- package/dist/core/contractIndex.js +38 -0
- package/dist/core/contractIndex.js.map +1 -0
- package/dist/core/contracts.d.ts +5 -0
- package/dist/core/contracts.d.ts.map +1 -0
- package/dist/core/contracts.js +42 -0
- package/dist/core/contracts.js.map +1 -0
- package/dist/core/contractsDecl.d.ts +3 -0
- package/dist/core/contractsDecl.d.ts.map +1 -0
- package/dist/core/contractsDecl.js +19 -0
- package/dist/core/contractsDecl.js.map +1 -0
- package/dist/core/discovery.d.ts +14 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +55 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/fs.d.ts +11 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +68 -0
- package/dist/core/fs.js.map +1 -0
- package/dist/core/gherkin/parse.d.ts +7 -0
- package/dist/core/gherkin/parse.d.ts.map +1 -0
- package/dist/core/gherkin/parse.js +25 -0
- package/dist/core/gherkin/parse.js.map +1 -0
- package/dist/core/ids.d.ts +6 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +52 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/parse/adr.d.ts +13 -0
- package/dist/core/parse/adr.d.ts.map +1 -0
- package/dist/core/parse/adr.js +33 -0
- package/dist/core/parse/adr.js.map +1 -0
- package/dist/core/parse/gherkin.d.ts +12 -0
- package/dist/core/parse/gherkin.d.ts.map +1 -0
- package/dist/core/parse/gherkin.js +22 -0
- package/dist/core/parse/gherkin.js.map +1 -0
- package/dist/core/parse/markdown.d.ts +14 -0
- package/dist/core/parse/markdown.d.ts.map +1 -0
- package/dist/core/parse/markdown.js +45 -0
- package/dist/core/parse/markdown.js.map +1 -0
- package/dist/core/parse/spec.d.ts +36 -0
- package/dist/core/parse/spec.d.ts.map +1 -0
- package/dist/core/parse/spec.js +123 -0
- package/dist/core/parse/spec.js.map +1 -0
- package/dist/core/report.d.ts +55 -0
- package/dist/core/report.d.ts.map +1 -0
- package/dist/core/report.js +393 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/scenarioModel.d.ts +33 -0
- package/dist/core/scenarioModel.d.ts.map +1 -0
- package/dist/core/scenarioModel.js +128 -0
- package/dist/core/scenarioModel.js.map +1 -0
- package/dist/core/specLayout.d.ts +8 -0
- package/dist/core/specLayout.d.ts.map +1 -0
- package/dist/core/specLayout.js +36 -0
- package/dist/core/specLayout.js.map +1 -0
- package/dist/core/traceability.d.ts +26 -0
- package/dist/core/traceability.d.ts.map +1 -0
- package/dist/core/traceability.js +157 -0
- package/dist/core/traceability.js.map +1 -0
- package/dist/core/types.d.ts +31 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/validate.d.ts +4 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +45 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/core/validators/contracts.d.ts +5 -0
- package/dist/core/validators/contracts.d.ts.map +1 -0
- package/dist/core/validators/contracts.js +189 -0
- package/dist/core/validators/contracts.js.map +1 -0
- package/dist/core/validators/delta.d.ts +4 -0
- package/dist/core/validators/delta.d.ts.map +1 -0
- package/dist/core/validators/delta.js +68 -0
- package/dist/core/validators/delta.js.map +1 -0
- package/dist/core/validators/ids.d.ts +4 -0
- package/dist/core/validators/ids.d.ts.map +1 -0
- package/dist/core/validators/ids.js +88 -0
- package/dist/core/validators/ids.js.map +1 -0
- package/dist/core/validators/scenario.d.ts +5 -0
- package/dist/core/validators/scenario.d.ts.map +1 -0
- package/dist/core/validators/scenario.js +127 -0
- package/dist/core/validators/scenario.js.map +1 -0
- package/dist/core/validators/spec.d.ts +5 -0
- package/dist/core/validators/spec.d.ts.map +1 -0
- package/dist/core/validators/spec.js +94 -0
- package/dist/core/validators/spec.js.map +1 -0
- package/dist/core/validators/traceability.d.ts +4 -0
- package/dist/core/validators/traceability.d.ts.map +1 -0
- package/dist/core/validators/traceability.js +222 -0
- package/dist/core/validators/traceability.js.map +1 -0
- package/dist/core/version.d.ts +2 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +25 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.cjs +504 -328
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -4
- package/dist/index.d.ts +2 -156
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +504 -328
- package/dist/index.mjs.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +1 -1
package/dist/cli/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/init.ts","../../src/cli/lib/fs.ts","../../src/cli/lib/assets.ts","../../src/cli/lib/logger.ts","../../src/cli/commands/report.ts","../../src/core/config.ts","../../src/core/report.ts","../../src/core/discovery.ts","../../src/core/fs.ts","../../src/core/specLayout.ts","../../src/core/ids.ts","../../src/core/traceability.ts","../../src/core/gherkin/parse.ts","../../src/core/scenarioModel.ts","../../src/core/version.ts","../../src/core/validators/contracts.ts","../../src/core/contracts.ts","../../src/core/validators/delta.ts","../../src/core/validators/ids.ts","../../src/core/contractIndex.ts","../../src/core/parse/markdown.ts","../../src/core/parse/spec.ts","../../src/core/validators/scenario.ts","../../src/core/validators/spec.ts","../../src/core/validators/traceability.ts","../../src/core/validate.ts","../../src/cli/commands/validate.ts","../../src/cli/lib/failOn.ts","../../src/cli/lib/args.ts","../../src/cli/main.ts","../../src/cli/index.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport { copyTemplateTree } from \"../lib/fs.js\";\nimport { getInitAssetsDir } from \"../lib/assets.js\";\nimport { info } from \"../lib/logger.js\";\n\nexport type InitOptions = {\n dir: string;\n force: boolean;\n dryRun: boolean;\n yes: boolean;\n};\n\nexport async function runInit(options: InitOptions): Promise<void> {\n const assetsRoot = getInitAssetsDir();\n const rootAssets = path.join(assetsRoot, \"root\");\n const qfaiAssets = path.join(assetsRoot, \".qfai\");\n\n const destRoot = path.resolve(options.dir);\n const destQfai = path.join(destRoot, \".qfai\");\n\n const rootResult = await copyTemplateTree(rootAssets, destRoot, {\n force: options.force,\n dryRun: options.dryRun,\n });\n const qfaiResult = await copyTemplateTree(qfaiAssets, destQfai, {\n force: options.force,\n dryRun: options.dryRun,\n });\n\n report(\n [...rootResult.copied, ...qfaiResult.copied],\n [...rootResult.skipped, ...qfaiResult.skipped],\n options.dryRun,\n \"init\",\n );\n}\n\nfunction report(\n copied: string[],\n skipped: string[],\n dryRun: boolean,\n label: string,\n): void {\n info(`qfai ${label}: ${dryRun ? \"dry-run\" : \"done\"}`);\n if (copied.length > 0) {\n info(` created: ${copied.length}`);\n }\n if (skipped.length > 0) {\n info(` skipped: ${skipped.length}`);\n }\n}\n","import { access, copyFile, mkdir, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type CopyOptions = {\n force: boolean;\n dryRun: boolean;\n};\n\nexport type CopyResult = {\n copied: string[];\n skipped: string[];\n};\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const files = await collectTemplateFiles(sourceRoot);\n return copyFiles(files, sourceRoot, destRoot, options);\n}\n\nexport async function copyTemplatePaths(\n sourceRoot: string,\n destRoot: string,\n relativePaths: string[],\n options: CopyOptions,\n): Promise<CopyResult> {\n const allFiles: string[] = [];\n for (const relPath of relativePaths) {\n const fullPath = path.join(sourceRoot, relPath);\n const files = await collectTemplateFiles(fullPath);\n allFiles.push(...files);\n }\n\n return copyFiles(allFiles, sourceRoot, destRoot, options);\n}\n\nasync function copyFiles(\n files: string[],\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const copied: string[] = [];\n const skipped: string[] = [];\n const conflicts: string[] = [];\n\n if (!options.force) {\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n const dest = path.join(destRoot, relative);\n if (!(await shouldWrite(dest, options.force))) {\n conflicts.push(dest);\n }\n }\n\n if (conflicts.length > 0) {\n throw new Error(formatConflictMessage(conflicts));\n }\n }\n\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n const dest = path.join(destRoot, relative);\n\n if (!(await shouldWrite(dest, options.force))) {\n skipped.push(dest);\n continue;\n }\n\n if (!options.dryRun) {\n await mkdir(path.dirname(dest), { recursive: true });\n await copyFile(file, dest);\n }\n copied.push(dest);\n }\n\n return { copied, skipped };\n}\n\nfunction formatConflictMessage(conflicts: string[]): string {\n return [\n \"既存ファイルと衝突しました。安全のため停止します。\",\n \"\",\n \"衝突ファイル:\",\n ...conflicts.map((conflict) => `- ${conflict}`),\n \"\",\n \"上書きして続行する場合は --force を付けて再実行してください。\",\n ].join(\"\\n\");\n}\n\nasync function collectTemplateFiles(root: string): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const items = await readdir(root, { withFileTypes: true });\n for (const item of items) {\n const fullPath = path.join(root, item.name);\n if (item.isDirectory()) {\n const nested = await collectTemplateFiles(fullPath);\n entries.push(...nested);\n continue;\n }\n if (item.isFile()) {\n entries.push(fullPath);\n }\n }\n\n return entries;\n}\n\nasync function shouldWrite(target: string, force: boolean): Promise<boolean> {\n if (force) {\n return true;\n }\n return !(await exists(target));\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function getInitAssetsDir(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n const baseDir = path.dirname(basePath);\n // src/cli/lib と dist/cli/lib からの解決を想定する。\n const candidates = [\n path.resolve(baseDir, \"../../../assets/init\"),\n path.resolve(baseDir, \"../../assets/init\"),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n [\n \"init 用テンプレートが見つかりません。Template assets not found.\",\n \"確認したパス / Checked paths:\",\n ...candidates.map((candidate) => `- ${candidate}`),\n ].join(\"\\n\"),\n );\n}\n","export function info(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function warn(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function error(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { loadConfig, resolvePath } from \"../../core/config.js\";\nimport {\n createReportData,\n formatReportJson,\n formatReportMarkdown,\n} from \"../../core/report.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\nimport { error, info } from \"../lib/logger.js\";\n\nexport type ReportOptions = {\n root: string;\n format: \"md\" | \"json\";\n outPath?: string;\n};\n\nexport async function runReport(options: ReportOptions): Promise<void> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const input = configResult.config.output.validateJsonPath;\n const inputPath = path.isAbsolute(input) ? input : path.resolve(root, input);\n let validation: ValidationResult;\n try {\n validation = await readValidationResult(inputPath);\n } catch (err) {\n if (isMissingFileError(err)) {\n error(\n [\n `qfai report: 入力ファイルが見つかりません: ${inputPath}`,\n \"\",\n \"まず qfai validate を実行してください。例:\",\n \" qfai validate\",\n \"(デフォルトの出力先: .qfai/out/validate.json)\",\n \"\",\n \"GitHub Actions テンプレを使っている場合は、workflow の validate ジョブを先に実行してください。\",\n ].join(\"\\n\"),\n );\n process.exitCode = 2;\n return;\n }\n throw err;\n }\n\n const data = await createReportData(root, validation, configResult);\n const output =\n options.format === \"json\"\n ? formatReportJson(data)\n : formatReportMarkdown(data);\n\n const outRoot = resolvePath(root, configResult.config, \"outDir\");\n const defaultOut =\n options.format === \"json\"\n ? path.join(outRoot, \"report.json\")\n : path.join(outRoot, \"report.md\");\n const out = options.outPath ?? defaultOut;\n const outPath = path.isAbsolute(out) ? out : path.resolve(root, out);\n\n await mkdir(path.dirname(outPath), { recursive: true });\n await writeFile(outPath, `${output}\\n`, \"utf-8\");\n\n info(\n `report: info=${validation.counts.info} warning=${validation.counts.warning} error=${validation.counts.error}`,\n );\n info(`wrote report: ${outPath}`);\n}\n\nasync function readValidationResult(\n inputPath: string,\n): Promise<ValidationResult> {\n const raw = await readFile(inputPath, \"utf-8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!isValidationResult(parsed)) {\n throw new Error(`validate.json の形式が不正です: ${inputPath}`);\n }\n return parsed;\n}\n\nfunction isValidationResult(value: unknown): value is ValidationResult {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.toolVersion !== \"string\") {\n return false;\n }\n if (!Array.isArray(record.issues)) {\n return false;\n }\n const counts = record.counts as Record<string, unknown> | undefined;\n if (!counts) {\n return false;\n }\n return (\n typeof counts.info === \"number\" &&\n typeof counts.warning === \"number\" &&\n typeof counts.error === \"number\"\n );\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n const record = error as { code?: string };\n return record.code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { Issue } from \"./types.js\";\n\nexport type FailOn = \"never\" | \"warning\" | \"error\";\nexport type OutputFormat = \"text\" | \"github\";\nexport type TraceabilitySeverity = \"warning\" | \"error\";\n\nexport type QfaiPaths = {\n contractsDir: string;\n specsDir: string;\n rulesDir: string;\n outDir: string;\n promptsDir: string;\n srcDir: string;\n testsDir: string;\n};\n\nexport type QfaiValidationConfig = {\n failOn: FailOn;\n require: {\n specSections: string[];\n };\n traceability: {\n brMustHaveSc: boolean;\n scMustTouchContracts: boolean;\n scMustHaveTest: boolean;\n testFileGlobs: string[];\n testFileExcludeGlobs: string[];\n scNoTestSeverity: TraceabilitySeverity;\n allowOrphanContracts: boolean;\n unknownContractIdSeverity: TraceabilitySeverity;\n };\n};\n\nexport type QfaiOutputConfig = {\n validateJsonPath: string;\n};\n\nexport type QfaiConfig = {\n paths: QfaiPaths;\n validation: QfaiValidationConfig;\n output: QfaiOutputConfig;\n};\n\nexport type ConfigPathKey = keyof QfaiPaths;\n\nexport type ConfigLoadResult = {\n config: QfaiConfig;\n issues: Issue[];\n configPath: string;\n};\n\nexport const defaultConfig: QfaiConfig = {\n paths: {\n contractsDir: \".qfai/contracts\",\n specsDir: \".qfai/specs\",\n rulesDir: \".qfai/rules\",\n outDir: \".qfai/out\",\n promptsDir: \".qfai/prompts\",\n srcDir: \"src\",\n testsDir: \"tests\",\n },\n validation: {\n failOn: \"error\",\n require: {\n specSections: [\n \"背景\",\n \"スコープ\",\n \"非ゴール\",\n \"用語\",\n \"前提\",\n \"決定事項\",\n \"業務ルール\",\n ],\n },\n traceability: {\n brMustHaveSc: true,\n scMustTouchContracts: true,\n scMustHaveTest: true,\n testFileGlobs: [],\n testFileExcludeGlobs: [],\n scNoTestSeverity: \"error\",\n allowOrphanContracts: false,\n unknownContractIdSeverity: \"error\",\n },\n },\n output: {\n validateJsonPath: \".qfai/out/validate.json\",\n },\n};\n\nexport function getConfigPath(root: string): string {\n return path.join(root, \"qfai.config.yaml\");\n}\n\nexport async function loadConfig(root: string): Promise<ConfigLoadResult> {\n const configPath = getConfigPath(root);\n const issues: Issue[] = [];\n\n let parsed: unknown;\n try {\n const raw = await readFile(configPath, \"utf-8\");\n parsed = parseYaml(raw);\n } catch (error) {\n if (isMissingFile(error)) {\n return { config: defaultConfig, issues, configPath };\n }\n issues.push(configIssue(configPath, formatError(error)));\n return { config: defaultConfig, issues, configPath };\n }\n\n const normalized = normalizeConfig(parsed, configPath, issues);\n return { config: normalized, issues, configPath };\n}\n\nexport function resolvePath(\n root: string,\n config: QfaiConfig,\n key: ConfigPathKey,\n): string {\n return path.resolve(root, config.paths[key]);\n}\n\nfunction normalizeConfig(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiConfig {\n if (!isRecord(raw)) {\n issues.push(configIssue(configPath, \"設定ファイルの形式が不正です。\"));\n return defaultConfig;\n }\n\n return {\n paths: normalizePaths(raw.paths, configPath, issues),\n validation: normalizeValidation(raw.validation, configPath, issues),\n output: normalizeOutput(raw.output, configPath, issues),\n };\n}\n\nfunction normalizePaths(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiPaths {\n const base = defaultConfig.paths;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"paths はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n contractsDir: readString(\n raw.contractsDir,\n base.contractsDir,\n \"paths.contractsDir\",\n configPath,\n issues,\n ),\n specsDir: readString(\n raw.specsDir,\n base.specsDir,\n \"paths.specsDir\",\n configPath,\n issues,\n ),\n rulesDir: readString(\n raw.rulesDir,\n base.rulesDir,\n \"paths.rulesDir\",\n configPath,\n issues,\n ),\n outDir: readString(\n raw.outDir,\n base.outDir,\n \"paths.outDir\",\n configPath,\n issues,\n ),\n promptsDir: readString(\n raw.promptsDir,\n base.promptsDir,\n \"paths.promptsDir\",\n configPath,\n issues,\n ),\n srcDir: readString(\n raw.srcDir,\n base.srcDir,\n \"paths.srcDir\",\n configPath,\n issues,\n ),\n testsDir: readString(\n raw.testsDir,\n base.testsDir,\n \"paths.testsDir\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction normalizeValidation(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiValidationConfig {\n const base = defaultConfig.validation;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(\n configPath,\n \"validation はオブジェクトである必要があります。\",\n ),\n );\n return base;\n }\n\n let requireRaw: Record<string, unknown> | undefined;\n if (raw.require === undefined) {\n requireRaw = undefined;\n } else if (isRecord(raw.require)) {\n requireRaw = raw.require;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.require はオブジェクトである必要があります。\",\n ),\n );\n requireRaw = undefined;\n }\n\n let traceabilityRaw: Record<string, unknown> | undefined;\n if (raw.traceability === undefined) {\n traceabilityRaw = undefined;\n } else if (isRecord(raw.traceability)) {\n traceabilityRaw = raw.traceability;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.traceability はオブジェクトである必要があります。\",\n ),\n );\n traceabilityRaw = undefined;\n }\n\n return {\n failOn: readFailOn(\n raw.failOn,\n base.failOn,\n \"validation.failOn\",\n configPath,\n issues,\n ),\n require: {\n specSections: readStringArray(\n requireRaw?.specSections,\n base.require.specSections,\n \"validation.require.specSections\",\n configPath,\n issues,\n ),\n },\n traceability: {\n brMustHaveSc: readBoolean(\n traceabilityRaw?.brMustHaveSc,\n base.traceability.brMustHaveSc,\n \"validation.traceability.brMustHaveSc\",\n configPath,\n issues,\n ),\n scMustTouchContracts: readBoolean(\n traceabilityRaw?.scMustTouchContracts,\n base.traceability.scMustTouchContracts,\n \"validation.traceability.scMustTouchContracts\",\n configPath,\n issues,\n ),\n scMustHaveTest: readBoolean(\n traceabilityRaw?.scMustHaveTest,\n base.traceability.scMustHaveTest,\n \"validation.traceability.scMustHaveTest\",\n configPath,\n issues,\n ),\n testFileGlobs: readStringArray(\n traceabilityRaw?.testFileGlobs,\n base.traceability.testFileGlobs,\n \"validation.traceability.testFileGlobs\",\n configPath,\n issues,\n ),\n testFileExcludeGlobs: readStringArray(\n traceabilityRaw?.testFileExcludeGlobs,\n base.traceability.testFileExcludeGlobs,\n \"validation.traceability.testFileExcludeGlobs\",\n configPath,\n issues,\n ),\n scNoTestSeverity: readTraceabilitySeverity(\n traceabilityRaw?.scNoTestSeverity,\n base.traceability.scNoTestSeverity,\n \"validation.traceability.scNoTestSeverity\",\n configPath,\n issues,\n ),\n allowOrphanContracts: readBoolean(\n traceabilityRaw?.allowOrphanContracts,\n base.traceability.allowOrphanContracts,\n \"validation.traceability.allowOrphanContracts\",\n configPath,\n issues,\n ),\n unknownContractIdSeverity: readTraceabilitySeverity(\n traceabilityRaw?.unknownContractIdSeverity,\n base.traceability.unknownContractIdSeverity,\n \"validation.traceability.unknownContractIdSeverity\",\n configPath,\n issues,\n ),\n },\n };\n}\n\nfunction normalizeOutput(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiOutputConfig {\n const base = defaultConfig.output;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"output はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n validateJsonPath: readString(\n raw.validateJsonPath,\n base.validateJsonPath,\n \"output.validateJsonPath\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction readString(\n value: unknown,\n fallback: string,\n label: string,\n configPath: string,\n issues: Issue[],\n): string {\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readStringArray(\n value: unknown,\n fallback: string[],\n label: string,\n configPath: string,\n issues: Issue[],\n): string[] {\n if (Array.isArray(value) && value.every((item) => typeof item === \"string\")) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列配列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readBoolean(\n value: unknown,\n fallback: boolean,\n label: string,\n configPath: string,\n issues: Issue[],\n): boolean {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は真偽値である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readFailOn(\n value: unknown,\n fallback: FailOn,\n label: string,\n configPath: string,\n issues: Issue[],\n): FailOn {\n if (value === \"never\" || value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は never|warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction readTraceabilitySeverity(\n value: unknown,\n fallback: TraceabilitySeverity,\n label: string,\n configPath: string,\n issues: Issue[],\n): TraceabilitySeverity {\n if (value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction configIssue(file: string, message: string): Issue {\n return {\n code: \"QFAI_CONFIG_INVALID\",\n severity: \"error\",\n message,\n file,\n rule: \"config.invalid\",\n };\n}\n\nfunction isMissingFile(error: unknown): boolean {\n if (error && typeof error === \"object\" && \"code\" in error) {\n return (error as { code?: string }).code === \"ENOENT\";\n }\n return false;\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport {\n collectContractFiles,\n collectScenarioFiles,\n collectSpecFiles,\n} from \"./discovery.js\";\nimport { collectFiles } from \"./fs.js\";\nimport { extractAllIds, extractIds, type IdPrefix } from \"./ids.js\";\nimport {\n buildScCoverage,\n collectScIdsFromScenarioFiles,\n collectScIdSourcesFromScenarioFiles,\n collectScTestReferences,\n type ScCoverage,\n type TestFileScan,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { validateProject } from \"./validate.js\";\nimport { resolveToolVersion } from \"./version.js\";\n\nexport type ReportSummary = {\n specs: number;\n scenarios: number;\n contracts: {\n api: number;\n ui: number;\n db: number;\n };\n counts: ValidationCounts;\n};\n\nexport type ReportIds = {\n spec: string[];\n br: string[];\n sc: string[];\n ui: string[];\n api: string[];\n data: string[];\n};\n\nexport type ReportTraceability = {\n upstreamIdsFound: number;\n referencedInCodeOrTests: boolean;\n sc: ScCoverage;\n scSources: Record<string, string[]>;\n testFiles: TestFileScan;\n};\n\nexport type ReportData = {\n tool: \"qfai\";\n version: string;\n generatedAt: string;\n root: string;\n configPath: string;\n summary: ReportSummary;\n ids: ReportIds;\n traceability: ReportTraceability;\n issues: Issue[];\n};\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DATA\"];\n\nexport async function createReportData(\n root: string,\n validation?: ValidationResult,\n configResult?: ConfigLoadResult,\n): Promise<ReportData> {\n const resolved = configResult ?? (await loadConfig(root));\n const config = resolved.config;\n const configPath = resolved.configPath;\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const dbRoot = path.join(contractsRoot, \"db\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const {\n api: apiFiles,\n ui: uiFiles,\n db: dbFiles,\n } = await collectContractFiles(uiRoot, apiRoot, dbRoot);\n\n const idsByPrefix = await collectIds([\n ...specFiles,\n ...scenarioFiles,\n ...apiFiles,\n ...uiFiles,\n ...dbFiles,\n ]);\n\n const upstreamIds = await collectUpstreamIds([\n ...specFiles,\n ...scenarioFiles,\n ]);\n const traceability = await evaluateTraceability(\n upstreamIds,\n srcRoot,\n testsRoot,\n );\n const scIds = await collectScIdsFromScenarioFiles(scenarioFiles);\n const scRefsResult = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scCoverage =\n validation?.traceability?.sc ?? buildScCoverage(scIds, scRefsResult.refs);\n const testFiles = validation?.traceability?.testFiles ?? scRefsResult.scan;\n const scSources = await collectScIdSourcesFromScenarioFiles(scenarioFiles);\n const scSourceRecord = mapToSortedRecord(scSources);\n\n const resolvedValidation =\n validation ?? (await validateProject(root, resolved));\n const version = await resolveToolVersion();\n\n return {\n tool: \"qfai\",\n version,\n generatedAt: new Date().toISOString(),\n root,\n configPath,\n summary: {\n specs: specFiles.length,\n scenarios: scenarioFiles.length,\n contracts: {\n api: apiFiles.length,\n ui: uiFiles.length,\n db: dbFiles.length,\n },\n counts: resolvedValidation.counts,\n },\n ids: {\n spec: idsByPrefix.SPEC,\n br: idsByPrefix.BR,\n sc: idsByPrefix.SC,\n ui: idsByPrefix.UI,\n api: idsByPrefix.API,\n data: idsByPrefix.DATA,\n },\n traceability: {\n upstreamIdsFound: upstreamIds.size,\n referencedInCodeOrTests: traceability,\n sc: scCoverage,\n scSources: scSourceRecord,\n testFiles,\n },\n issues: resolvedValidation.issues,\n };\n}\n\nexport function formatReportMarkdown(data: ReportData): string {\n const lines: string[] = [];\n\n lines.push(\"# QFAI Report\");\n lines.push(`- 生成日時: ${data.generatedAt}`);\n lines.push(`- ルート: ${data.root}`);\n lines.push(`- 設定: ${data.configPath}`);\n lines.push(`- 版: ${data.version}`);\n lines.push(\"\");\n\n lines.push(\"## 概要\");\n lines.push(`- specs: ${data.summary.specs}`);\n lines.push(`- scenarios: ${data.summary.scenarios}`);\n lines.push(\n `- contracts: api ${data.summary.contracts.api} / ui ${data.summary.contracts.ui} / db ${data.summary.contracts.db}`,\n );\n lines.push(\n `- issues: info ${data.summary.counts.info} / warning ${data.summary.counts.warning} / error ${data.summary.counts.error}`,\n );\n lines.push(\"\");\n\n lines.push(\"## ID集計\");\n lines.push(formatIdLine(\"SPEC\", data.ids.spec));\n lines.push(formatIdLine(\"BR\", data.ids.br));\n lines.push(formatIdLine(\"SC\", data.ids.sc));\n lines.push(formatIdLine(\"UI\", data.ids.ui));\n lines.push(formatIdLine(\"API\", data.ids.api));\n lines.push(formatIdLine(\"DATA\", data.ids.data));\n lines.push(\"\");\n\n lines.push(\"## トレーサビリティ\");\n lines.push(`- 上流ID検出数: ${data.traceability.upstreamIdsFound}`);\n lines.push(\n `- コード/テスト参照: ${data.traceability.referencedInCodeOrTests ? \"あり\" : \"なし\"}`,\n );\n lines.push(\"\");\n\n lines.push(\"## SCカバレッジ\");\n lines.push(`- total: ${data.traceability.sc.total}`);\n lines.push(`- covered: ${data.traceability.sc.covered}`);\n lines.push(`- missing: ${data.traceability.sc.missing}`);\n lines.push(\n `- testFileGlobs: ${formatList(data.traceability.testFiles.globs)}`,\n );\n lines.push(\n `- testFileExcludeGlobs: ${formatList(\n data.traceability.testFiles.excludeGlobs,\n )}`,\n );\n lines.push(\n `- testFileCount: ${data.traceability.testFiles.matchedFileCount}`,\n );\n if (data.traceability.sc.missingIds.length === 0) {\n lines.push(\"- missingIds: (none)\");\n } else {\n const sources = data.traceability.scSources;\n const missingWithSources = data.traceability.sc.missingIds.map((id) => {\n const files = sources[id] ?? [];\n if (files.length === 0) {\n return id;\n }\n return `${id} (${files.join(\", \")})`;\n });\n lines.push(`- missingIds: ${missingWithSources.join(\", \")}`);\n }\n lines.push(\"\");\n\n lines.push(\"## SC→参照テスト\");\n const scRefs = data.traceability.sc.refs;\n const scIds = Object.keys(scRefs).sort((a, b) => a.localeCompare(b));\n if (scIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const scId of scIds) {\n const refs = scRefs[scId] ?? [];\n if (refs.length === 0) {\n lines.push(`- ${scId}: (none)`);\n } else {\n lines.push(`- ${scId}: ${refs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Spec:SC=1:1 違反\");\n const specScIssues = data.issues.filter(\n (item) => item.code === \"QFAI-TRACE-012\",\n );\n if (specScIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of specScIssues) {\n const location = item.file ?? \"(unknown)\";\n const refs =\n item.refs && item.refs.length > 0 ? item.refs.join(\", \") : item.message;\n lines.push(`- ${location}: ${refs}`);\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Hotspots\");\n const hotspots = buildHotspots(data.issues);\n if (hotspots.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const spot of hotspots) {\n lines.push(\n `- ${spot.file}: total ${spot.total} (error ${spot.error} / warning ${spot.warning} / info ${spot.info})`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## トレーサビリティ(検証)\");\n const traceIssues = data.issues.filter(\n (item) =>\n item.rule?.startsWith(\"traceability.\") ||\n item.code.startsWith(\"QFAI_TRACE\") ||\n item.code.startsWith(\"QFAI-TRACE-\") ||\n item.code === \"QFAI_CONTRACT_ORPHAN\",\n );\n if (traceIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of traceIssues) {\n const location = item.file ? ` (${item.file})` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## 検証結果\");\n if (data.issues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of data.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}${refs}`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatReportJson(data: ReportData): string {\n return JSON.stringify(data, null, 2);\n}\n\nasync function collectIds(\n files: string[],\n): Promise<Record<IdPrefix, string[]>> {\n const result: Record<IdPrefix, Set<string>> = {\n SPEC: new Set(),\n BR: new Set(),\n SC: new Set(),\n UI: new Set(),\n API: new Set(),\n DATA: new Set(),\n };\n\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n for (const prefix of ID_PREFIXES) {\n const ids = extractIds(text, prefix);\n ids.forEach((id) => result[prefix].add(id));\n }\n }\n\n return {\n SPEC: toSortedArray(result.SPEC),\n BR: toSortedArray(result.BR),\n SC: toSortedArray(result.SC),\n UI: toSortedArray(result.UI),\n API: toSortedArray(result.API),\n DATA: toSortedArray(result.DATA),\n };\n}\n\nasync function collectUpstreamIds(files: string[]): Promise<Set<string>> {\n const ids = new Set<string>();\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => ids.add(id));\n }\n return ids;\n}\n\nasync function evaluateTraceability(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<boolean> {\n if (upstreamIds.size === 0) {\n return false;\n }\n\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n return false;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction formatIdLine(label: string, values: string[]): string {\n if (values.length === 0) {\n return `- ${label}: (none)`;\n }\n return `- ${label}: ${values.join(\", \")}`;\n}\n\nfunction formatList(values: string[]): string {\n if (values.length === 0) {\n return \"(none)\";\n }\n return values.join(\", \");\n}\n\nfunction toSortedArray(values: Set<string>): string[] {\n return Array.from(values).sort((a, b) => a.localeCompare(b));\n}\n\nfunction mapToSortedRecord(\n values: Map<string, Set<string>>,\n): Record<string, string[]> {\n const record: Record<string, string[]> = {};\n for (const [key, files] of values.entries()) {\n record[key] = Array.from(files).sort((a, b) => a.localeCompare(b));\n }\n return record;\n}\n\ntype Hotspot = {\n file: string;\n total: number;\n error: number;\n warning: number;\n info: number;\n};\n\nfunction buildHotspots(issues: Issue[]): Hotspot[] {\n const map = new Map<string, Hotspot>();\n for (const issue of issues) {\n if (!issue.file) {\n continue;\n }\n const current =\n map.get(issue.file) ??\n ({\n file: issue.file,\n total: 0,\n error: 0,\n warning: 0,\n info: 0,\n } satisfies Hotspot);\n current.total += 1;\n current[issue.severity] += 1;\n map.set(issue.file, current);\n }\n\n return Array.from(map.values()).sort((a, b) =>\n b.total !== a.total ? b.total - a.total : a.file.localeCompare(b.file),\n );\n}\n","import { access } from \"node:fs/promises\";\n\nimport { collectFiles } from \"./fs.js\";\nimport { collectSpecEntries } from \"./specLayout.js\";\n\nexport type ContractFiles = {\n api: string[];\n ui: string[];\n db: string[];\n};\n\nexport async function collectSpecPackDirs(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return entries.map((entry) => entry.dir);\n}\n\nexport async function collectSpecFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.specPath));\n}\n\nexport async function collectDeltaFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.deltaPath));\n}\n\nexport async function collectScenarioFiles(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.scenarioPath));\n}\n\nexport async function collectUiContractFiles(\n uiRoot: string,\n): Promise<string[]> {\n return collectFiles(uiRoot, { extensions: [\".yaml\", \".yml\"] });\n}\n\nexport async function collectApiContractFiles(\n apiRoot: string,\n): Promise<string[]> {\n return collectFiles(apiRoot, { extensions: [\".yaml\", \".yml\", \".json\"] });\n}\n\nexport async function collectDataContractFiles(\n dataRoot: string,\n): Promise<string[]> {\n return collectFiles(dataRoot, { extensions: [\".sql\"] });\n}\n\nexport async function collectContractFiles(\n uiRoot: string,\n apiRoot: string,\n dataRoot: string,\n): Promise<ContractFiles> {\n const [ui, api, db] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDataContractFiles(dataRoot),\n ]);\n return { ui, api, db };\n}\n\nasync function filterExisting(files: string[]): Promise<string[]> {\n const existing: string[] = [];\n for (const file of files) {\n if (await exists(file)) {\n existing.push(file);\n }\n }\n return existing;\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { access, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport fg from \"fast-glob\";\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \".pnpm\",\n \"tmp\",\n \".mcp-tools\",\n]);\n\nexport type CollectFilesOptions = {\n extensions?: string[];\n ignoreDirs?: string[];\n};\n\nexport type CollectFilesByGlobOptions = {\n globs: string[];\n ignore?: string[];\n};\n\nexport async function collectFiles(\n root: string,\n options: CollectFilesOptions = {},\n): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const ignoreDirs = new Set([\n ...DEFAULT_IGNORE_DIRS,\n ...(options.ignoreDirs ?? []),\n ]);\n const extensions = options.extensions?.map((ext) => ext.toLowerCase()) ?? [];\n\n await walk(root, root, ignoreDirs, extensions, entries);\n return entries;\n}\n\nexport async function collectFilesByGlobs(\n root: string,\n options: CollectFilesByGlobOptions,\n): Promise<string[]> {\n if (options.globs.length === 0) {\n return [];\n }\n return fg(options.globs, {\n cwd: root,\n ignore: options.ignore ?? [],\n onlyFiles: true,\n absolute: true,\n unique: true,\n });\n}\n\nasync function walk(\n base: string,\n current: string,\n ignoreDirs: Set<string>,\n extensions: string[],\n out: string[],\n): Promise<void> {\n const items = await readdir(current, { withFileTypes: true });\n\n for (const item of items) {\n const fullPath = path.join(current, item.name);\n\n if (item.isDirectory()) {\n if (ignoreDirs.has(item.name)) {\n continue;\n }\n await walk(base, fullPath, ignoreDirs, extensions, out);\n continue;\n }\n\n if (item.isFile()) {\n if (extensions.length > 0) {\n const ext = path.extname(item.name).toLowerCase();\n if (!extensions.includes(ext)) {\n continue;\n }\n }\n out.push(fullPath);\n }\n }\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst SPEC_DIR_RE = /^spec-\\d{4}$/;\n\nexport type SpecEntry = {\n dir: string;\n specPath: string;\n deltaPath: string;\n scenarioPath: string;\n};\n\nexport async function collectSpecEntries(\n specsRoot: string,\n): Promise<SpecEntry[]> {\n const dirs = await listSpecDirs(specsRoot);\n const entries = dirs.map((dir) => ({\n dir,\n specPath: path.join(dir, \"spec.md\"),\n deltaPath: path.join(dir, \"delta.md\"),\n scenarioPath: path.join(dir, \"scenario.md\"),\n }));\n return entries.sort((a, b) => a.dir.localeCompare(b.dir));\n}\n\nasync function listSpecDirs(specsRoot: string): Promise<string[]> {\n try {\n const items = await readdir(specsRoot, { withFileTypes: true });\n return items\n .filter((item) => item.isDirectory())\n .map((item) => item.name)\n .filter((name) => SPEC_DIR_RE.test(name.toLowerCase()))\n .map((name) => path.join(specsRoot, name));\n } catch (error) {\n if (isMissingFileError(error)) {\n return [];\n }\n throw error;\n }\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","export type IdPrefix = \"SPEC\" | \"BR\" | \"SC\" | \"UI\" | \"API\" | \"DATA\";\nexport type IdFormatPrefix = IdPrefix | \"ADR\";\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DATA\"];\n\nconst STRICT_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-\\d{4}\\b/g,\n BR: /\\bBR-\\d{4}\\b/g,\n SC: /\\bSC-\\d{4}\\b/g,\n UI: /\\bUI-\\d{4}\\b/g,\n API: /\\bAPI-\\d{4}\\b/g,\n DATA: /\\bDATA-\\d{4}\\b/g,\n ADR: /\\bADR-\\d{4}\\b/g,\n};\n\nconst LOOSE_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-[A-Za-z0-9_-]+\\b/gi,\n BR: /\\bBR-[A-Za-z0-9_-]+\\b/gi,\n SC: /\\bSC-[A-Za-z0-9_-]+\\b/gi,\n UI: /\\bUI-[A-Za-z0-9_-]+\\b/gi,\n API: /\\bAPI-[A-Za-z0-9_-]+\\b/gi,\n DATA: /\\bDATA-[A-Za-z0-9_-]+\\b/gi,\n ADR: /\\bADR-[A-Za-z0-9_-]+\\b/gi,\n};\n\nexport function extractIds(text: string, prefix: IdPrefix): string[] {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const matches = text.match(pattern);\n return unique(matches ?? []);\n}\n\nexport function extractAllIds(text: string): string[] {\n const all: string[] = [];\n ID_PREFIXES.forEach((prefix) => {\n all.push(...extractIds(text, prefix));\n });\n return unique(all);\n}\n\nexport function extractInvalidIds(\n text: string,\n prefixes: IdFormatPrefix[],\n): string[] {\n const invalid: string[] = [];\n for (const prefix of prefixes) {\n const candidates = text.match(LOOSE_ID_PATTERNS[prefix]) ?? [];\n for (const candidate of candidates) {\n if (!isValidId(candidate, prefix)) {\n invalid.push(candidate);\n }\n }\n }\n return unique(invalid);\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction isValidId(value: string, prefix: IdFormatPrefix): boolean {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const strict = new RegExp(pattern.source);\n return strict.test(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { collectFilesByGlobs } from \"./fs.js\";\nimport { parseScenarioDocument } from \"./scenarioModel.js\";\n\nexport const SC_TAG_RE = /^SC-\\d{4}$/;\nexport const SC_TEST_ANNOTATION_RE = /\\bQFAI:SC-(\\d{4})\\b/g;\nexport const DEFAULT_TEST_FILE_EXCLUDE_GLOBS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/.qfai/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/.next/**\",\n \"**/out/**\",\n];\n\nexport type ScCoverage = {\n total: number;\n covered: number;\n missing: number;\n missingIds: string[];\n refs: Record<string, string[]>;\n};\n\nexport type TestFileScan = {\n globs: string[];\n excludeGlobs: string[];\n matchedFileCount: number;\n};\n\nexport type ScTestReferenceResult = {\n refs: Map<string, Set<string>>;\n scan: TestFileScan;\n error?: string;\n};\n\nexport function extractAnnotatedScIds(text: string): string[] {\n const ids = new Set<string>();\n for (const match of text.matchAll(SC_TEST_ANNOTATION_RE)) {\n const suffix = match[1];\n if (suffix) {\n ids.add(`SC-${suffix}`);\n }\n }\n return Array.from(ids);\n}\n\nexport async function collectScIdsFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Set<string>> {\n const scIds = new Set<string>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n scIds.add(tag);\n }\n }\n }\n }\n return scIds;\n}\n\nexport async function collectScIdSourcesFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Map<string, Set<string>>> {\n const sources = new Map<string, Set<string>>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (!SC_TAG_RE.test(tag)) {\n continue;\n }\n const current = sources.get(tag) ?? new Set<string>();\n current.add(file);\n sources.set(tag, current);\n }\n }\n }\n return sources;\n}\n\nexport async function collectScTestReferences(\n root: string,\n globs: string[],\n excludeGlobs: string[],\n): Promise<ScTestReferenceResult> {\n const refs = new Map<string, Set<string>>();\n const normalizedGlobs = normalizeGlobs(globs);\n const normalizedExcludeGlobs = normalizeGlobs(excludeGlobs);\n const mergedExcludeGlobs = Array.from(\n new Set([...DEFAULT_TEST_FILE_EXCLUDE_GLOBS, ...normalizedExcludeGlobs]),\n );\n if (normalizedGlobs.length === 0) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n };\n }\n\n let files: string[] = [];\n try {\n files = await collectFilesByGlobs(root, {\n globs: normalizedGlobs,\n ignore: mergedExcludeGlobs,\n });\n } catch (error) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n error: formatError(error),\n };\n }\n\n const normalizedFiles = Array.from(\n new Set(files.map((file) => path.normalize(file))),\n );\n for (const file of normalizedFiles) {\n const text = await readFile(file, \"utf-8\");\n const scIds = extractAnnotatedScIds(text);\n if (scIds.length === 0) {\n continue;\n }\n for (const scId of scIds) {\n const current = refs.get(scId) ?? new Set<string>();\n current.add(file);\n refs.set(scId, current);\n }\n }\n\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: normalizedFiles.length,\n },\n };\n}\n\nexport function buildScCoverage(\n scIds: Iterable<string>,\n refs: Map<string, Set<string>>,\n): ScCoverage {\n const sortedScIds = toSortedArray(scIds);\n const refsRecord: Record<string, string[]> = {};\n const missingIds: string[] = [];\n let covered = 0;\n\n for (const scId of sortedScIds) {\n const files = refs.get(scId);\n const sortedFiles = files ? toSortedArray(files) : [];\n refsRecord[scId] = sortedFiles;\n if (sortedFiles.length === 0) {\n missingIds.push(scId);\n } else {\n covered += 1;\n }\n }\n\n return {\n total: sortedScIds.length,\n covered,\n missing: missingIds.length,\n missingIds,\n refs: refsRecord,\n };\n}\n\nfunction toSortedArray(values: Iterable<string>): string[] {\n return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));\n}\n\nfunction normalizeGlobs(globs: string[]): string[] {\n return globs.map((glob) => glob.trim()).filter((glob) => glob.length > 0);\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import {\n AstBuilder,\n GherkinClassicTokenMatcher,\n Parser,\n} from \"@cucumber/gherkin\";\nimport type { GherkinDocument } from \"@cucumber/messages\";\nimport { randomUUID } from \"node:crypto\";\n\nexport type ParsedGherkin = {\n gherkinDocument: GherkinDocument | null;\n errors: string[];\n};\n\nexport function parseGherkin(source: string, uri: string): ParsedGherkin {\n const errors: string[] = [];\n const uuidFn = () => randomUUID();\n const builder = new AstBuilder(uuidFn);\n const matcher = new GherkinClassicTokenMatcher();\n const parser = new Parser(builder, matcher);\n\n try {\n const gherkinDocument = parser.parse(source);\n gherkinDocument.uri = uri;\n return { gherkinDocument, errors };\n } catch (error) {\n errors.push(formatError(error));\n return { gherkinDocument: null, errors };\n }\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import type * as Messages from \"@cucumber/messages\";\n\nimport { parseGherkin } from \"./gherkin/parse.js\";\nimport { extractIds } from \"./ids.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\nconst UI_TAG_RE = /^UI-\\d{4}$/;\nconst API_TAG_RE = /^API-\\d{4}$/;\nconst DATA_TAG_RE = /^DATA-\\d{4}$/;\n\nexport type ScenarioKind = \"Scenario\" | \"ScenarioOutline\";\n\nexport type ScenarioNode = {\n name: string;\n kind: ScenarioKind;\n line?: number;\n tags: string[];\n steps: readonly Messages.Step[];\n};\n\nexport type ScenarioDocument = {\n uri: string;\n featureName?: string;\n featureTags: string[];\n scenarios: ScenarioNode[];\n};\n\nexport type ScenarioParseResult = {\n document: ScenarioDocument | null;\n errors: string[];\n};\n\nexport type ScenarioAtom = {\n uri: string;\n featureName: string;\n scenarioName: string;\n kind: ScenarioKind;\n specId?: string;\n scId?: string;\n brIds: string[];\n contractIds: string[];\n line?: number;\n};\n\nexport function parseScenarioDocument(\n text: string,\n uri: string,\n): ScenarioParseResult {\n const { gherkinDocument, errors } = parseGherkin(text, uri);\n if (!gherkinDocument) {\n return { document: null, errors };\n }\n\n const feature = gherkinDocument.feature;\n if (!feature) {\n return {\n document: { uri, featureTags: [], scenarios: [] },\n errors,\n };\n }\n\n const featureTags = collectTagNames(feature.tags);\n const scenarios = collectScenarioNodes(feature, featureTags);\n return {\n document: {\n uri,\n featureName: feature.name,\n featureTags,\n scenarios,\n },\n errors,\n };\n}\n\nexport function buildScenarioAtoms(document: ScenarioDocument): ScenarioAtom[] {\n return document.scenarios.map((scenario) => {\n const specIds = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const scIds = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n const brIds = unique(scenario.tags.filter((tag) => BR_TAG_RE.test(tag)));\n\n const contractIds = new Set<string>();\n scenario.tags.forEach((tag) => {\n if (\n UI_TAG_RE.test(tag) ||\n API_TAG_RE.test(tag) ||\n DATA_TAG_RE.test(tag)\n ) {\n contractIds.add(tag);\n }\n });\n\n for (const step of scenario.steps) {\n for (const text of collectStepTexts(step)) {\n extractIds(text, \"UI\").forEach((id) => contractIds.add(id));\n extractIds(text, \"API\").forEach((id) => contractIds.add(id));\n extractIds(text, \"DATA\").forEach((id) => contractIds.add(id));\n }\n }\n\n const atom: ScenarioAtom = {\n uri: document.uri,\n featureName: document.featureName ?? \"\",\n scenarioName: scenario.name,\n kind: scenario.kind,\n brIds,\n contractIds: Array.from(contractIds).sort(),\n };\n\n if (scenario.line !== undefined) {\n atom.line = scenario.line;\n }\n if (specIds.length === 1) {\n const specId = specIds[0];\n if (specId) {\n atom.specId = specId;\n }\n }\n if (scIds.length === 1) {\n const scId = scIds[0];\n if (scId) {\n atom.scId = scId;\n }\n }\n\n return atom;\n });\n}\n\nfunction collectScenarioNodes(\n feature: Messages.Feature,\n featureTags: string[],\n): ScenarioNode[] {\n const scenarios: ScenarioNode[] = [];\n\n for (const child of feature.children) {\n if (child.scenario) {\n scenarios.push(buildScenarioNode(child.scenario, featureTags, []));\n }\n if (child.rule) {\n const ruleTags = collectTagNames(child.rule.tags);\n for (const ruleChild of child.rule.children) {\n if (ruleChild.scenario) {\n scenarios.push(\n buildScenarioNode(ruleChild.scenario, featureTags, ruleTags),\n );\n }\n }\n }\n }\n\n return scenarios;\n}\n\nfunction buildScenarioNode(\n scenario: Messages.Scenario,\n featureTags: string[],\n ruleTags: string[],\n): ScenarioNode {\n const tags = [...featureTags, ...ruleTags, ...collectTagNames(scenario.tags)];\n const kind: ScenarioKind =\n scenario.examples.length > 0 ? \"ScenarioOutline\" : \"Scenario\";\n return {\n name: scenario.name,\n kind,\n line: scenario.location?.line,\n tags,\n steps: scenario.steps,\n };\n}\n\nfunction collectTagNames(tags: readonly Messages.Tag[]): string[] {\n return tags.map((tag) => tag.name.replace(/^@/, \"\"));\n}\n\nfunction collectStepTexts(step: Messages.Step): string[] {\n const texts: string[] = [];\n if (step.text) {\n texts.push(step.text);\n }\n if (step.docString?.content) {\n texts.push(step.docString.content);\n }\n if (step.dataTable?.rows) {\n for (const row of step.dataTable.rows) {\n for (const cell of row.cells) {\n texts.push(cell.value);\n }\n }\n }\n return texts;\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ndeclare const __QFAI_TOOL_VERSION__: string | undefined;\n\nexport async function resolveToolVersion(): Promise<string> {\n if (\n typeof __QFAI_TOOL_VERSION__ === \"string\" &&\n __QFAI_TOOL_VERSION__.length > 0\n ) {\n return __QFAI_TOOL_VERSION__;\n }\n\n try {\n const packagePath = resolvePackageJsonPath();\n const raw = await readFile(packagePath, \"utf-8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n const version = typeof parsed.version === \"string\" ? parsed.version : \"\";\n return version.length > 0 ? version : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction resolvePackageJsonPath(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n return path.resolve(path.dirname(basePath), \"../../package.json\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport {\n extractApiContractIds,\n extractUiContractIds,\n parseStructuredContract,\n} from \"../contracts.js\";\nimport {\n collectApiContractFiles,\n collectDataContractFiles,\n collectUiContractFiles,\n} from \"../discovery.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SQL_DANGEROUS_PATTERNS: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /\\bDROP\\s+TABLE\\b/i, label: \"DROP TABLE\" },\n { pattern: /\\bDROP\\s+DATABASE\\b/i, label: \"DROP DATABASE\" },\n { pattern: /\\bTRUNCATE\\b/i, label: \"TRUNCATE\" },\n {\n pattern: /\\bALTER\\s+TABLE\\b[\\s\\S]*\\bDROP\\b/i,\n label: \"ALTER TABLE ... DROP\",\n },\n];\n\nexport async function validateContracts(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n\n issues.push(...(await validateUiContracts(path.join(contractsRoot, \"ui\"))));\n issues.push(...(await validateApiContracts(path.join(contractsRoot, \"api\"))));\n issues.push(...(await validateDataContracts(path.join(contractsRoot, \"db\"))));\n\n return issues;\n}\n\nasync function validateUiContracts(uiRoot: string): Promise<Issue[]> {\n const files = await collectUiContractFiles(uiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-UI-000\",\n \"UI 契約ファイルが見つかりません。\",\n \"info\",\n uiRoot,\n \"contracts.ui.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DATA\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n let doc: Record<string, unknown>;\n try {\n doc = parseStructuredContract(file, text);\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `UI 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.ui.parse\",\n ),\n );\n continue;\n }\n const uiIds = extractUiContractIds(doc);\n if (uiIds.length === 0) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-002\",\n `UI 契約に ID(UI-xxxx) が見つかりません: ${file}`,\n \"error\",\n file,\n \"contracts.ui.id\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateApiContracts(apiRoot: string): Promise<Issue[]> {\n const files = await collectApiContractFiles(apiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-API-000\",\n \"API 契約ファイルが見つかりません。\",\n \"info\",\n apiRoot,\n \"contracts.api.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DATA\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n let doc: Record<string, unknown>;\n try {\n doc = parseStructuredContract(file, text);\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `API 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.api.parse\",\n ),\n );\n continue;\n }\n\n if (!hasOpenApi(doc)) {\n issues.push(\n issue(\n \"QFAI-API-001\",\n \"OpenAPI 定義が見つかりません。\",\n \"error\",\n file,\n \"contracts.api.openapi\",\n ),\n );\n }\n const apiIds = extractApiContractIds(doc);\n if (apiIds.length === 0) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-002\",\n `API 契約に ID(API-xxxx) が見つかりません: ${file}`,\n \"error\",\n file,\n \"contracts.api.id\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateDataContracts(dataRoot: string): Promise<Issue[]> {\n const files = await collectDataContractFiles(dataRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-DATA-000\",\n \"DATA 契約ファイルが見つかりません。\",\n \"info\",\n dataRoot,\n \"contracts.data.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DATA\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n issues.push(...lintSql(text, file));\n }\n\n return issues;\n}\n\nexport function lintSql(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n for (const { pattern, label } of SQL_DANGEROUS_PATTERNS) {\n if (pattern.test(text)) {\n issues.push(\n issue(\n \"QFAI-DATA-001\",\n `危険な SQL 操作が含まれています: ${label}`,\n \"warning\",\n file,\n \"contracts.data.sql\",\n ),\n );\n }\n }\n return issues;\n}\n\nfunction hasOpenApi(doc: Record<string, unknown>): boolean {\n return typeof doc.openapi === \"string\" && doc.openapi.length > 0;\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport { extractIds } from \"./ids.js\";\n\nexport function parseStructuredContract(\n file: string,\n text: string,\n): Record<string, unknown> {\n const ext = path.extname(file).toLowerCase();\n if (ext === \".json\") {\n return JSON.parse(text) as Record<string, unknown>;\n }\n return parseYaml(text) as Record<string, unknown>;\n}\n\nexport function extractUiContractIds(doc: Record<string, unknown>): string[] {\n const id = typeof doc.id === \"string\" ? doc.id : \"\";\n return extractIds(id, \"UI\");\n}\n\nexport function extractApiContractIds(doc: Record<string, unknown>): string[] {\n const operationIds = new Set<string>();\n collectOperationIds(doc, operationIds);\n\n const ids = new Set<string>();\n for (const operationId of operationIds) {\n extractIds(operationId, \"API\").forEach((id) => ids.add(id));\n }\n return Array.from(ids);\n}\n\nexport function collectOperationIds(value: unknown, out: Set<string>): void {\n if (!value || typeof value !== \"object\") {\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectOperationIds(item, out);\n }\n return;\n }\n\n for (const [key, entry] of Object.entries(value)) {\n if (key === \"operationId\" && typeof entry === \"string\") {\n out.add(entry);\n continue;\n }\n collectOperationIds(entry, out);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { collectSpecPackDirs } from \"../discovery.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SECTION_RE = /^##\\s+変更区分/m;\nconst COMPAT_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Change\\/Improvement\\b/m;\nconst COMPAT_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Change\\/Improvement\\b/m;\n\nexport async function validateDeltas(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const packs = await collectSpecPackDirs(specsRoot);\n if (packs.length === 0) {\n return [];\n }\n\n const issues: Issue[] = [];\n for (const pack of packs) {\n const deltaPath = path.join(pack, \"delta.md\");\n let text: string;\n try {\n text = await readFile(deltaPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-DELTA-001\",\n \"delta.md が見つかりません。\",\n \"error\",\n deltaPath,\n \"delta.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n\n const hasSection = SECTION_RE.test(text);\n const hasCompatibility = COMPAT_LINE_RE.test(text);\n const hasChange = CHANGE_LINE_RE.test(text);\n if (!hasSection || !hasCompatibility || !hasChange) {\n issues.push(\n issue(\n \"QFAI-DELTA-002\",\n \"delta.md の変更区分が不足しています。\",\n \"error\",\n deltaPath,\n \"delta.section\",\n ),\n );\n continue;\n }\n\n const compatibilityChecked = COMPAT_CHECKED_RE.test(text);\n const changeChecked = CHANGE_CHECKED_RE.test(text);\n if (compatibilityChecked === changeChecked) {\n issues.push(\n issue(\n \"QFAI-DELTA-003\",\n \"delta.md の変更区分はどちらか1つだけ選択してください(両方ON/両方OFFは無効です)。\",\n \"error\",\n deltaPath,\n \"delta.classification\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SC_TAG_RE = /^SC-\\d{4}$/;\n\nexport async function validateDefinedIds(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const defined = new Map<string, Set<string>>();\n\n await collectSpecDefinitionIds(specFiles, defined);\n await collectScenarioDefinitionIds(scenarioFiles, defined);\n const contractIndex = await buildContractIndex(root, config);\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n for (const file of files) {\n recordId(defined, id, file);\n }\n }\n\n for (const [id, files] of defined.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sorted = Array.from(files).sort();\n issues.push(\n issue(\n \"QFAI-ID-001\",\n `ID が重複しています: ${id} (${formatFileList(sorted, root)})`,\n \"error\",\n sorted[0],\n \"id.duplicate\",\n ),\n );\n }\n\n return issues;\n}\n\nasync function collectSpecDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n recordId(out, parsed.specId, file);\n }\n parsed.brs.forEach((br) => recordId(out, br.id, file));\n }\n}\n\nasync function collectScenarioDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n recordId(out, tag, file);\n }\n }\n }\n }\n}\n\nfunction recordId(\n out: Map<string, Set<string>>,\n id: string,\n file: string,\n): void {\n const current = out.get(id) ?? new Set<string>();\n current.add(file);\n out.set(id, current);\n}\n\nfunction formatFileList(files: string[], root: string): string {\n return files\n .map((file) => {\n const relative = path.relative(root, file);\n return relative.length > 0 ? relative : file;\n })\n .join(\", \");\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"./config.js\";\nimport { resolvePath } from \"./config.js\";\nimport {\n collectApiContractFiles,\n collectDataContractFiles,\n collectUiContractFiles,\n} from \"./discovery.js\";\nimport {\n extractApiContractIds,\n extractUiContractIds,\n parseStructuredContract,\n} from \"./contracts.js\";\nimport { extractIds } from \"./ids.js\";\n\nexport type ContractIndex = {\n ids: Set<string>;\n idToFiles: Map<string, Set<string>>;\n files: { ui: string[]; api: string[]; data: string[] };\n structuredParseFailedFiles: Set<string>;\n};\n\nexport async function buildContractIndex(\n root: string,\n config: QfaiConfig,\n): Promise<ContractIndex> {\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const dataRoot = path.join(contractsRoot, \"db\");\n\n const [uiFiles, apiFiles, dataFiles] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDataContractFiles(dataRoot),\n ]);\n\n const index: ContractIndex = {\n ids: new Set<string>(),\n idToFiles: new Map<string, Set<string>>(),\n files: { ui: uiFiles, api: apiFiles, data: dataFiles },\n structuredParseFailedFiles: new Set<string>(),\n };\n\n await indexUiContracts(uiFiles, index);\n await indexApiContracts(apiFiles, index);\n await indexDataContracts(dataFiles, index);\n\n return index;\n}\n\nasync function indexUiContracts(\n files: string[],\n index: ContractIndex,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n try {\n const doc = parseStructuredContract(file, text);\n extractUiContractIds(doc).forEach((id) => record(index, id, file));\n } catch {\n index.structuredParseFailedFiles.add(file);\n extractIds(text, \"UI\").forEach((id) => record(index, id, file));\n }\n }\n}\n\nasync function indexApiContracts(\n files: string[],\n index: ContractIndex,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n try {\n const doc = parseStructuredContract(file, text);\n extractApiContractIds(doc).forEach((id) => record(index, id, file));\n } catch {\n index.structuredParseFailedFiles.add(file);\n extractIds(text, \"API\").forEach((id) => record(index, id, file));\n }\n }\n}\n\nasync function indexDataContracts(\n files: string[],\n index: ContractIndex,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractIds(text, \"DATA\").forEach((id) => record(index, id, file));\n }\n}\n\nfunction record(index: ContractIndex, id: string, file: string): void {\n index.ids.add(id);\n const current = index.idToFiles.get(id) ?? new Set<string>();\n current.add(file);\n index.idToFiles.set(id, current);\n}\n","export type Heading = { level: number; title: string; line: number };\n\nexport type H2Section = {\n title: string;\n startLine: number;\n endLine: number;\n body: string;\n};\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\nexport function parseHeadings(md: string): Heading[] {\n const lines = md.split(/\\r?\\n/);\n const headings: Heading[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const match = line.match(HEADING_RE);\n if (!match) continue;\n const levelToken = match[1];\n const title = match[2];\n if (!levelToken || !title) continue;\n headings.push({\n level: levelToken.length,\n title: title.trim(),\n line: i + 1,\n });\n }\n return headings;\n}\n\nexport function extractH2Sections(md: string): Map<string, H2Section> {\n const lines = md.split(/\\r?\\n/);\n const headings = parseHeadings(md).filter((heading) => heading.level === 2);\n const sections = new Map<string, H2Section>();\n\n for (let i = 0; i < headings.length; i++) {\n const current = headings[i];\n if (!current) continue;\n const next = headings[i + 1];\n const startLine = current.line + 1;\n const endLine = (next?.line ?? lines.length + 1) - 1;\n const body =\n startLine <= endLine\n ? lines.slice(startLine - 1, endLine).join(\"\\n\")\n : \"\";\n\n sections.set(current.title.trim(), {\n title: current.title.trim(),\n startLine,\n endLine,\n body,\n });\n }\n\n return sections;\n}\n","import { extractH2Sections, parseHeadings } from \"./markdown.js\";\n\nexport type BrPriority = \"P0\" | \"P1\" | \"P2\" | \"P3\";\n\nexport type ParsedBr = {\n id: string;\n priority: BrPriority;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithoutPriority = {\n id: string;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithInvalidPriority = {\n id: string;\n priority: string;\n text: string;\n line: number;\n};\n\nexport type ParsedSpec = {\n file: string;\n specId?: string;\n sections: Set<string>;\n brs: ParsedBr[];\n brsWithoutPriority: ParsedBrWithoutPriority[];\n brsWithInvalidPriority: ParsedBrWithInvalidPriority[];\n};\n\nconst SPEC_ID_RE = /\\bSPEC-\\d{4}\\b/;\nconst BR_LINE_RE = /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[0-3])\\]\\s*(.+)$/;\nconst BR_LINE_ANY_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[^\\]]+)\\]\\s*(.+)$/;\nconst BR_LINE_NO_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\](?!\\s*\\[P)\\s*(.*\\S.*)$/;\n\nconst BR_SECTION_TITLE = \"業務ルール\";\nconst VALID_PRIORITIES = new Set<BrPriority>([\"P0\", \"P1\", \"P2\", \"P3\"]);\n\nexport function parseSpec(md: string, file: string): ParsedSpec {\n const headings = parseHeadings(md);\n const h1 = headings.find((heading) => heading.level === 1);\n const specId = h1?.title.match(SPEC_ID_RE)?.[0];\n\n const sections = extractH2Sections(md);\n const sectionNames = new Set(Array.from(sections.keys()));\n const brSection = sections.get(BR_SECTION_TITLE);\n const brLines = brSection ? brSection.body.split(/\\r?\\n/) : [];\n const startLine = brSection?.startLine ?? 1;\n\n const brs: ParsedBr[] = [];\n const brsWithoutPriority: ParsedBrWithoutPriority[] = [];\n const brsWithInvalidPriority: ParsedBrWithInvalidPriority[] = [];\n\n for (let i = 0; i < brLines.length; i++) {\n const lineText = brLines[i] ?? \"\";\n const lineNumber = startLine + i;\n\n const validMatch = lineText.match(BR_LINE_RE);\n if (validMatch) {\n const id = validMatch[1];\n const priority = validMatch[2];\n const text = validMatch[3];\n if (!id || !priority || !text) continue;\n brs.push({\n id,\n priority: priority as BrPriority,\n text: text.trim(),\n line: lineNumber,\n });\n continue;\n }\n\n const anyPriorityMatch = lineText.match(BR_LINE_ANY_PRIORITY_RE);\n if (anyPriorityMatch) {\n const id = anyPriorityMatch[1];\n const priority = anyPriorityMatch[2];\n const text = anyPriorityMatch[3];\n if (!id || !priority || !text) continue;\n if (!VALID_PRIORITIES.has(priority as BrPriority)) {\n brsWithInvalidPriority.push({\n id,\n priority,\n text: text.trim(),\n line: lineNumber,\n });\n }\n continue;\n }\n\n const noPriorityMatch = lineText.match(BR_LINE_NO_PRIORITY_RE);\n if (noPriorityMatch) {\n const id = noPriorityMatch[1];\n const text = noPriorityMatch[2];\n if (!id || !text) continue;\n brsWithoutPriority.push({\n id,\n text: text.trim(),\n line: lineNumber,\n });\n }\n }\n\n const parsed: ParsedSpec = {\n file,\n sections: sectionNames,\n brs,\n brsWithoutPriority,\n brsWithInvalidPriority,\n };\n if (specId) {\n parsed.specId = specId;\n }\n return parsed;\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst GIVEN_PATTERN = /\\bGiven\\b/;\nconst WHEN_PATTERN = /\\bWhen\\b/;\nconst THEN_PATTERN = /\\bThen\\b/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\n\nexport async function validateScenarios(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/scenario.md\";\n const legacy = \"spec-001/scenario.md\";\n return [\n issue(\n \"QFAI-SC-000\",\n `Scenario ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"scenario.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.scenarioPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SC-001\",\n \"scenario.md が見つかりません。\",\n \"error\",\n entry.scenarioPath,\n \"scenario.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(...validateScenarioContent(text, entry.scenarioPath));\n }\n\n return issues;\n}\n\nexport function validateScenarioContent(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DATA\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-010\",\n `Gherkin の解析に失敗しました: ${errors.join(\", \") || \"unknown\"}`,\n \"error\",\n file,\n \"scenario.parse\",\n ),\n );\n return issues;\n }\n\n const featureSpecTags = document.featureTags.filter((tag) =>\n SPEC_TAG_RE.test(tag),\n );\n if (featureSpecTags.length > 1) {\n issues.push(\n issue(\n \"QFAI-SC-009\",\n `Feature の SPEC タグが複数あります: ${featureSpecTags.join(\", \")}`,\n \"error\",\n file,\n \"scenario.featureSpec\",\n featureSpecTags,\n ),\n );\n }\n\n const missingStructure: string[] = [];\n if (!document.featureName) missingStructure.push(\"Feature\");\n if (document.scenarios.length === 0) missingStructure.push(\"Scenario\");\n if (missingStructure.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-006\",\n `Scenario ファイルに必要な構造がありません: ${missingStructure.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"scenario.structure\",\n ),\n );\n }\n\n for (const scenario of document.scenarios) {\n if (scenario.tags.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-007\",\n `Scenario タグが見つかりません: ${scenario.name}`,\n \"error\",\n file,\n \"scenario.tags\",\n ),\n );\n continue;\n }\n\n const missingTags: string[] = [];\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n if (scTags.length === 0) {\n missingTags.push(\"SC(0件)\");\n } else if (scTags.length > 1) {\n missingTags.push(`SC(${scTags.length}件/1件必須)`);\n }\n if (missingTags.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-008\",\n `Scenario タグに不足があります: ${missingTags.join(\", \")} (${\n scenario.name\n })`,\n \"error\",\n file,\n \"scenario.tagIds\",\n ),\n );\n }\n }\n\n for (const scenario of document.scenarios) {\n const missingSteps: string[] = [];\n const keywords = scenario.steps.map((step) => step.keyword.trim());\n if (!keywords.some((keyword) => GIVEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Given\");\n }\n if (!keywords.some((keyword) => WHEN_PATTERN.test(keyword))) {\n missingSteps.push(\"When\");\n }\n if (!keywords.some((keyword) => THEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Then\");\n }\n if (missingSteps.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-005\",\n `Given/When/Then が不足しています: ${missingSteps.join(\", \")} (${\n scenario.name\n })`,\n \"warning\",\n file,\n \"scenario.steps\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractIds, extractInvalidIds } from \"../ids.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nexport async function validateSpecs(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/spec.md\";\n const legacy = \"spec-001/spec.md\";\n return [\n issue(\n \"QFAI-SPEC-000\",\n `Spec ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"spec.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.specPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SPEC-005\",\n \"spec.md が見つかりません。\",\n \"error\",\n entry.specPath,\n \"spec.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(\n ...validateSpecContent(\n text,\n entry.specPath,\n config.validation.require.specSections,\n ),\n );\n }\n\n return issues;\n}\n\nexport function validateSpecContent(\n text: string,\n file: string,\n requiredSections: string[],\n): Issue[] {\n const issues: Issue[] = [];\n\n const parsed = parseSpec(text, file);\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DATA\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n if (!parsed.specId) {\n issues.push(\n issue(\n \"QFAI-SPEC-001\",\n \"SPEC ID が見つかりません。\",\n \"error\",\n file,\n \"spec.id\",\n ),\n );\n }\n\n if (parsed.brs.length === 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-002\",\n \"BR ID が見つかりません。\",\n \"error\",\n file,\n \"spec.br\",\n ),\n );\n }\n\n for (const br of parsed.brsWithoutPriority) {\n issues.push(\n issue(\n \"QFAI-BR-001\",\n `BR 行に Priority がありません: ${br.id}`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n for (const br of parsed.brsWithInvalidPriority) {\n issues.push(\n issue(\n \"QFAI-BR-002\",\n `BR Priority が不正です: ${br.id} (${br.priority})`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n const scIds = extractIds(text, \"SC\");\n if (scIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-003\",\n \"Spec は SC を参照しないルールです。\",\n \"warning\",\n file,\n \"spec.noSc\",\n scIds,\n ),\n );\n }\n\n for (const section of requiredSections) {\n if (!parsed.sections.has(section)) {\n issues.push(\n issue(\n \"QFAI-SPEC-004\",\n `必須セクションが不足しています: ${section}`,\n \"error\",\n file,\n \"spec.requiredSection\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { collectFiles } from \"../fs.js\";\nimport { extractAllIds } from \"../ids.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { buildScenarioAtoms, parseScenarioDocument } from \"../scenarioModel.js\";\nimport { SC_TAG_RE, collectScTestReferences } from \"../traceability.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\n\nexport async function validateTraceability(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const upstreamIds = new Set<string>();\n const specIds = new Set<string>();\n const brIdsInSpecs = new Set<string>();\n const brIdsInScenarios = new Set<string>();\n const scIdsInScenarios = new Set<string>();\n const scenarioContractIds = new Set<string>();\n const scWithContracts = new Set<string>();\n const specToBrIds = new Map<string, Set<string>>();\n const contractIndex = await buildContractIndex(root, config);\n const contractIds = contractIndex.ids;\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n specIds.add(parsed.specId);\n }\n\n const brIds = parsed.brs.map((br) => br.id);\n brIds.forEach((id) => brIdsInSpecs.add(id));\n\n if (parsed.specId) {\n const current = specToBrIds.get(parsed.specId) ?? new Set<string>();\n brIds.forEach((id) => current.add(id));\n specToBrIds.set(parsed.specId, current);\n }\n }\n\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n const atoms = buildScenarioAtoms(document);\n const scIdsInFile = new Set<string>();\n\n for (const [index, scenario] of document.scenarios.entries()) {\n const atom = atoms[index];\n if (!atom) {\n continue;\n }\n\n const specTags = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const brTags = scenario.tags.filter((tag) => BR_TAG_RE.test(tag));\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n\n if (specTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-014\",\n `Scenario が SPEC タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioSpecRequired\",\n ),\n );\n }\n if (brTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-015\",\n `Scenario が BR タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioBrRequired\",\n ),\n );\n }\n\n brTags.forEach((id) => brIdsInScenarios.add(id));\n scTags.forEach((id) => {\n scIdsInScenarios.add(id);\n scIdsInFile.add(id);\n });\n atom.contractIds.forEach((id) => scenarioContractIds.add(id));\n\n if (atom.contractIds.length > 0) {\n scTags.forEach((id) => scWithContracts.add(id));\n }\n\n const unknownSpecIds = specTags.filter((id) => !specIds.has(id));\n if (unknownSpecIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-005\",\n `Scenario が存在しない SPEC を参照しています: ${unknownSpecIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioSpecExists\",\n unknownSpecIds,\n ),\n );\n }\n\n const unknownBrIds = brTags.filter((id) => !brIdsInSpecs.has(id));\n if (unknownBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-006\",\n `Scenario が存在しない BR を参照しています: ${unknownBrIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrExists\",\n unknownBrIds,\n ),\n );\n }\n\n const unknownContractIds = atom.contractIds.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-008\",\n `Scenario が存在しない契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )} (${scenario.name})`,\n config.validation.traceability.unknownContractIdSeverity,\n file,\n \"traceability.scenarioContractExists\",\n unknownContractIds,\n ),\n );\n }\n\n if (specTags.length > 0 && brTags.length > 0) {\n const allowedBrIds = new Set<string>();\n for (const specId of specTags) {\n const brIdsForSpec = specToBrIds.get(specId);\n if (!brIdsForSpec) {\n continue;\n }\n brIdsForSpec.forEach((id) => allowedBrIds.add(id));\n }\n const invalidBrIds = brTags.filter((id) => !allowedBrIds.has(id));\n if (invalidBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-007\",\n `Scenario の BR が参照 SPEC に属していません: ${invalidBrIds.join(\n \", \",\n )} (SPEC: ${specTags.join(\", \")}) (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrUnderSpec\",\n invalidBrIds,\n ),\n );\n }\n }\n }\n\n if (scIdsInFile.size !== 1) {\n const invalidScIds = Array.from(scIdsInFile).sort((a, b) =>\n a.localeCompare(b),\n );\n const detail =\n invalidScIds.length === 0\n ? \"SC が見つかりません\"\n : `複数の SC が存在します: ${invalidScIds.join(\", \")}`;\n issues.push(\n issue(\n \"QFAI-TRACE-012\",\n `Spec entry が Spec:SC=1:1 を満たしていません: ${detail}`,\n \"error\",\n file,\n \"traceability.specScOneToOne\",\n invalidScIds,\n ),\n );\n }\n }\n\n if (upstreamIds.size === 0) {\n return [\n issue(\n \"QFAI-TRACE-000\",\n \"上流 ID が見つかりません。\",\n \"info\",\n specsRoot,\n \"traceability.upstream\",\n ),\n ];\n }\n\n if (config.validation.traceability.brMustHaveSc && brIdsInSpecs.size > 0) {\n const orphanBrIds = Array.from(brIdsInSpecs).filter(\n (id) => !brIdsInScenarios.has(id),\n );\n if (orphanBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_TRACE_BR_ORPHAN\",\n `BR が SC に紐づいていません: ${orphanBrIds.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.brMustHaveSc\",\n orphanBrIds,\n ),\n );\n }\n }\n\n if (\n config.validation.traceability.scMustTouchContracts &&\n scIdsInScenarios.size > 0\n ) {\n const scWithoutContracts = Array.from(scIdsInScenarios).filter(\n (id) => !scWithContracts.has(id),\n );\n if (scWithoutContracts.length > 0) {\n issues.push(\n issue(\n \"QFAI_TRACE_SC_NO_CONTRACT\",\n `SC が契約(UI/API/DATA)に接続していません: ${scWithoutContracts.join(\n \", \",\n )}`,\n \"error\",\n specsRoot,\n \"traceability.scMustTouchContracts\",\n scWithoutContracts,\n ),\n );\n }\n }\n\n const scRefsResult = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scTestRefs = scRefsResult.refs;\n const testFileScan = scRefsResult.scan;\n const hasScenarios = scIdsInScenarios.size > 0;\n const hasGlobConfig = testFileScan.globs.length > 0;\n const hasMatchedTests = testFileScan.matchedFileCount > 0;\n\n if (\n hasScenarios &&\n (!hasGlobConfig || !hasMatchedTests || scRefsResult.error)\n ) {\n const detail = scRefsResult.error ? `(詳細: ${scRefsResult.error})` : \"\";\n issues.push(\n issue(\n \"QFAI-TRACE-013\",\n `テスト探索 glob が未設定/不正/一致ファイル0のため SC→Test を判定できません。${detail}`,\n \"error\",\n testsRoot,\n \"traceability.testFileGlobs\",\n ),\n );\n } else {\n if (\n config.validation.traceability.scMustHaveTest &&\n scIdsInScenarios.size\n ) {\n const scWithoutTests = Array.from(scIdsInScenarios).filter((id) => {\n const refs = scTestRefs.get(id);\n return !refs || refs.size === 0;\n });\n if (scWithoutTests.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-010\",\n `SC がテストで参照されていません: ${scWithoutTests.join(\n \", \",\n )}。testFileGlobs に一致するテストファイルへ QFAI:SC-xxxx を記載してください。`,\n config.validation.traceability.scNoTestSeverity,\n testsRoot,\n \"traceability.scMustHaveTest\",\n scWithoutTests,\n ),\n );\n }\n }\n\n const unknownScIds = Array.from(scTestRefs.keys()).filter(\n (id) => !scIdsInScenarios.has(id),\n );\n if (unknownScIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-011\",\n `テストが未知の SC をアノテーション参照しています: ${unknownScIds.join(\n \", \",\n )}`,\n \"error\",\n testsRoot,\n \"traceability.scUnknownInTests\",\n unknownScIds,\n ),\n );\n }\n }\n\n if (!config.validation.traceability.allowOrphanContracts) {\n if (contractIds.size > 0) {\n const orphanContracts = Array.from(contractIds).filter(\n (id) => !scenarioContractIds.has(id),\n );\n if (orphanContracts.length > 0) {\n issues.push(\n issue(\n \"QFAI_CONTRACT_ORPHAN\",\n `契約が SC から参照されていません: ${orphanContracts.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.allowOrphanContracts\",\n orphanContracts,\n ),\n );\n }\n }\n }\n\n issues.push(\n ...(await validateCodeReferences(upstreamIds, srcRoot, testsRoot)),\n );\n return issues;\n}\n\nasync function validateCodeReferences(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-001\",\n \"参照対象のコード/テストが見つかりません。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n return issues;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n let found = false;\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n issues.push(\n issue(\n \"QFAI-TRACE-002\",\n \"上流 ID がコード/テストに参照されていません(参考情報)。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n }\n\n return issues;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport { collectScenarioFiles } from \"./discovery.js\";\nimport {\n buildScCoverage,\n collectScIdsFromScenarioFiles,\n collectScTestReferences,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { resolveToolVersion } from \"./version.js\";\nimport { validateContracts } from \"./validators/contracts.js\";\nimport { validateDeltas } from \"./validators/delta.js\";\nimport { validateDefinedIds } from \"./validators/ids.js\";\nimport { validateScenarios } from \"./validators/scenario.js\";\nimport { validateSpecs } from \"./validators/spec.js\";\nimport { validateTraceability } from \"./validators/traceability.js\";\n\nexport async function validateProject(\n root: string,\n configResult?: ConfigLoadResult,\n): Promise<ValidationResult> {\n const resolved = configResult ?? (await loadConfig(root));\n const { config, issues: configIssues } = resolved;\n const issues = [\n ...configIssues,\n ...(await validateSpecs(root, config)),\n ...(await validateDeltas(root, config)),\n ...(await validateScenarios(root, config)),\n ...(await validateContracts(root, config)),\n ...(await validateDefinedIds(root, config)),\n ...(await validateTraceability(root, config)),\n ];\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const scIds = await collectScIdsFromScenarioFiles(scenarioFiles);\n const { refs: scTestRefs, scan: testFiles } = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scCoverage = buildScCoverage(scIds, scTestRefs);\n\n const toolVersion = await resolveToolVersion();\n return {\n toolVersion,\n issues,\n counts: countIssues(issues),\n traceability: {\n sc: scCoverage,\n testFiles,\n },\n };\n}\n\nfunction countIssues(issues: Issue[]): ValidationCounts {\n return issues.reduce<ValidationCounts>(\n (acc, issue) => {\n acc[issue.severity] += 1;\n return acc;\n },\n { info: 0, warning: 0, error: 0 },\n );\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { FailOn, OutputFormat } from \"../../core/config.js\";\nimport { loadConfig } from \"../../core/config.js\";\nimport type { Issue, ValidationResult } from \"../../core/types.js\";\nimport { validateProject } from \"../../core/validate.js\";\nimport { shouldFail } from \"../lib/failOn.js\";\n\nexport type ValidateOptions = {\n root: string;\n strict: boolean;\n failOn?: FailOn;\n format?: OutputFormat;\n};\n\nexport async function runValidate(options: ValidateOptions): Promise<number> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const result = await validateProject(root, configResult);\n\n const format = options.format ?? \"text\";\n if (format === \"text\") {\n emitText(result);\n }\n if (format === \"github\") {\n result.issues.forEach(emitGitHub);\n }\n await emitJson(result, root, configResult.config.output.validateJsonPath);\n\n const failOn = resolveFailOn(options, configResult.config.validation.failOn);\n return shouldFail(result, failOn) ? 1 : 0;\n}\n\nfunction resolveFailOn(options: ValidateOptions, fallback: FailOn): FailOn {\n if (options.failOn) {\n return options.failOn;\n }\n if (options.strict) {\n return \"warning\";\n }\n return fallback;\n}\n\nfunction emitText(result: ValidationResult): void {\n for (const item of result.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n process.stdout.write(\n `[${item.severity}] ${item.code} ${item.message}${location}${refs}\\n`,\n );\n }\n process.stdout.write(\n `counts: info=${result.counts.info} warning=${result.counts.warning} error=${result.counts.error}\\n`,\n );\n}\n\nfunction emitGitHub(issue: Issue): void {\n const level =\n issue.severity === \"error\"\n ? \"error\"\n : issue.severity === \"warning\"\n ? \"warning\"\n : \"notice\";\n const file = issue.file ? `file=${issue.file}` : \"\";\n const line = issue.loc?.line ? `,line=${issue.loc.line}` : \"\";\n const column = issue.loc?.column ? `,col=${issue.loc.column}` : \"\";\n const location = file ? ` ${file}${line}${column}` : \"\";\n process.stdout.write(\n `::${level}${location}::${issue.code}: ${issue.message}\\n`,\n );\n}\n\nasync function emitJson(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n): Promise<void> {\n const abs = path.isAbsolute(jsonPath)\n ? jsonPath\n : path.resolve(root, jsonPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\n","import type { FailOn } from \"../../core/config.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\n\nexport type { FailOn };\n\nexport function shouldFail(result: ValidationResult, failOn: FailOn): boolean {\n if (failOn === \"never\") {\n return false;\n }\n if (failOn === \"error\") {\n return result.counts.error > 0;\n }\n return result.counts.error + result.counts.warning > 0;\n}\n","export type ParsedArgs = {\n command: string | null;\n options: {\n root: string;\n dir: string;\n force: boolean;\n yes: boolean;\n dryRun: boolean;\n reportFormat: \"md\" | \"json\";\n reportOut?: string;\n validateFormat: \"text\" | \"github\";\n strict: boolean;\n failOn?: \"never\" | \"warning\" | \"error\";\n help: boolean;\n };\n};\n\nexport function parseArgs(argv: string[], cwd: string): ParsedArgs {\n const options: ParsedArgs[\"options\"] = {\n root: cwd,\n dir: cwd,\n force: false,\n yes: false,\n dryRun: false,\n reportFormat: \"md\",\n validateFormat: \"text\",\n strict: false,\n help: false,\n };\n\n const args = [...argv];\n let command = args.shift() ?? null;\n\n if (command === \"--help\" || command === \"-h\") {\n options.help = true;\n command = null;\n }\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n switch (arg) {\n case \"--root\":\n options.root = args[i + 1] ?? options.root;\n i += 1;\n break;\n case \"--dir\":\n options.dir = args[i + 1] ?? options.dir;\n i += 1;\n break;\n case \"--force\":\n options.force = true;\n break;\n case \"--yes\":\n options.yes = true;\n break;\n case \"--dry-run\":\n options.dryRun = true;\n break;\n case \"--format\": {\n const next = args[i + 1];\n applyFormatOption(command, next, options);\n i += 1;\n break;\n }\n case \"--strict\":\n options.strict = true;\n break;\n case \"--fail-on\": {\n const next = args[i + 1];\n if (next === \"never\" || next === \"warning\" || next === \"error\") {\n options.failOn = next;\n }\n i += 1;\n break;\n }\n case \"--out\":\n {\n const next = args[i + 1];\n if (next) {\n options.reportOut = next;\n }\n }\n i += 1;\n break;\n case \"--help\":\n case \"-h\":\n options.help = true;\n break;\n default:\n break;\n }\n }\n\n return { command, options };\n}\n\nfunction applyFormatOption(\n command: string | null,\n value: string | undefined,\n options: ParsedArgs[\"options\"],\n): void {\n if (!value) {\n return;\n }\n if (command === \"report\") {\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n return;\n }\n if (command === \"validate\") {\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n return;\n }\n\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n}\n","import { runInit } from \"./commands/init.js\";\nimport { runReport } from \"./commands/report.js\";\nimport { runValidate } from \"./commands/validate.js\";\nimport { parseArgs } from \"./lib/args.js\";\nimport { error, info } from \"./lib/logger.js\";\n\nexport async function run(argv: string[], cwd: string): Promise<void> {\n const { command, options } = parseArgs(argv, cwd);\n\n if (!command || options.help) {\n info(usage());\n return;\n }\n\n switch (command) {\n case \"init\":\n await runInit({\n dir: options.dir,\n force: options.force,\n dryRun: options.dryRun,\n yes: options.yes,\n });\n return;\n case \"validate\":\n process.exitCode = await runValidate({\n root: options.root,\n strict: options.strict,\n format: options.validateFormat,\n ...(options.failOn !== undefined ? { failOn: options.failOn } : {}),\n });\n return;\n case \"report\":\n await runReport({\n root: options.root,\n format: options.reportFormat,\n ...(options.reportOut !== undefined\n ? { outPath: options.reportOut }\n : {}),\n });\n return;\n default:\n error(`Unknown command: ${command}`);\n info(usage());\n return;\n }\n}\n\nfunction usage(): string {\n return `qfai <command> [options]\n\nCommands:\n init テンプレを生成\n validate 仕様/契約/参照の検査\n report 検証結果と集計を出力\n\nOptions:\n --root <path> 対象ディレクトリ\n --dir <path> init の出力先\n --force 既存ファイルを上書き\n --yes init: 予約フラグ(現状は非対話のため挙動差なし。将来の対話導入時に自動Yes)\n --dry-run 変更を行わず表示のみ\n --format <text|github> validate の出力形式\n --format <md|json> report の出力形式\n --strict validate: warning 以上で exit 1\n --fail-on <error|warning|never> validate: 失敗条件\n --out <path> report: 出力先\n -h, --help ヘルプ表示\n`;\n}\n","#!/usr/bin/env node\nimport { run } from \"./main.js\";\n\nrun(process.argv.slice(2), process.cwd()).catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":";;;AAAA,OAAOA,WAAU;;;ACAjB,SAAS,QAAQ,UAAU,OAAO,eAAe;AACjD,OAAO,UAAU;AAYjB,eAAsB,iBACpB,YACA,UACA,SACqB;AACrB,QAAM,QAAQ,MAAM,qBAAqB,UAAU;AACnD,SAAO,UAAU,OAAO,YAAY,UAAU,OAAO;AACvD;AAkBA,eAAe,UACb,OACA,YACA,UACA,SACqB;AACrB,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAoB,CAAC;AAC3B,QAAM,YAAsB,CAAC;AAE7B,MAAI,CAAC,QAAQ,OAAO;AAClB,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,KAAK,SAAS,YAAY,IAAI;AAC/C,YAAM,OAAO,KAAK,KAAK,UAAU,QAAQ;AACzC,UAAI,CAAE,MAAM,YAAY,MAAM,QAAQ,KAAK,GAAI;AAC7C,kBAAU,KAAK,IAAI;AAAA,MACrB;AAAA,IACF;AAEA,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,IAAI,MAAM,sBAAsB,SAAS,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,KAAK,SAAS,YAAY,IAAI;AAC/C,UAAM,OAAO,KAAK,KAAK,UAAU,QAAQ;AAEzC,QAAI,CAAE,MAAM,YAAY,MAAM,QAAQ,KAAK,GAAI;AAC7C,cAAQ,KAAK,IAAI;AACjB;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,QAAQ;AACnB,YAAM,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,YAAM,SAAS,MAAM,IAAI;AAAA,IAC3B;AACA,WAAO,KAAK,IAAI;AAAA,EAClB;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEA,SAAS,sBAAsB,WAA6B;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,UAAU,IAAI,CAAC,aAAa,KAAK,QAAQ,EAAE;AAAA,IAC9C;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,eAAe,qBAAqB,MAAiC;AACnE,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAE,MAAM,OAAO,IAAI,GAAI;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AACzD,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,KAAK,KAAK,MAAM,KAAK,IAAI;AAC1C,QAAI,KAAK,YAAY,GAAG;AACtB,YAAM,SAAS,MAAM,qBAAqB,QAAQ;AAClD,cAAQ,KAAK,GAAG,MAAM;AACtB;AAAA,IACF;AACA,QAAI,KAAK,OAAO,GAAG;AACjB,cAAQ,KAAK,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,YAAY,QAAgB,OAAkC;AAC3E,MAAI,OAAO;AACT,WAAO;AAAA,EACT;AACA,SAAO,CAAE,MAAM,OAAO,MAAM;AAC9B;AAEA,eAAe,OAAO,QAAkC;AACtD,MAAI;AACF,UAAM,OAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AChIA,SAAS,kBAAkB;AAC3B,OAAOC,WAAU;AACjB,SAAS,qBAAqB;AAEvB,SAAS,mBAA2B;AACzC,QAAM,OAAO,YAAY;AACzB,QAAM,WAAW,KAAK,WAAW,OAAO,IAAI,cAAc,IAAI,IAAI;AAClE,QAAM,UAAUA,MAAK,QAAQ,QAAQ;AAErC,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,SAAS,sBAAsB;AAAA,IAC5CA,MAAK,QAAQ,SAAS,mBAAmB;AAAA,EAC3C;AAEA,aAAW,aAAa,YAAY;AAClC,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA;AAAA,MACA,GAAG,WAAW,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;AAAA,IACnD,EAAE,KAAK,IAAI;AAAA,EACb;AACF;;;AC3BO,SAAS,KAAK,SAAuB;AAC1C,UAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACrC;AAMO,SAAS,MAAM,SAAuB;AAC3C,UAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACrC;;;AHGA,eAAsB,QAAQ,SAAqC;AACjE,QAAM,aAAa,iBAAiB;AACpC,QAAM,aAAaC,MAAK,KAAK,YAAY,MAAM;AAC/C,QAAM,aAAaA,MAAK,KAAK,YAAY,OAAO;AAEhD,QAAM,WAAWA,MAAK,QAAQ,QAAQ,GAAG;AACzC,QAAM,WAAWA,MAAK,KAAK,UAAU,OAAO;AAE5C,QAAM,aAAa,MAAM,iBAAiB,YAAY,UAAU;AAAA,IAC9D,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACD,QAAM,aAAa,MAAM,iBAAiB,YAAY,UAAU;AAAA,IAC9D,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED;AAAA,IACE,CAAC,GAAG,WAAW,QAAQ,GAAG,WAAW,MAAM;AAAA,IAC3C,CAAC,GAAG,WAAW,SAAS,GAAG,WAAW,OAAO;AAAA,IAC7C,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,OACP,QACA,SACA,QACA,OACM;AACN,OAAK,QAAQ,KAAK,KAAK,SAAS,YAAY,MAAM,EAAE;AACpD,MAAI,OAAO,SAAS,GAAG;AACrB,SAAK,cAAc,OAAO,MAAM,EAAE;AAAA,EACpC;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,SAAK,cAAc,QAAQ,MAAM,EAAE;AAAA,EACrC;AACF;;;AInDA,SAAS,SAAAC,QAAO,YAAAC,YAAU,iBAAiB;AAC3C,OAAOC,YAAU;;;ACDjB,SAAS,gBAAgB;AACzB,OAAOC,WAAU;AAEjB,SAAS,SAAS,iBAAiB;AAqD5B,IAAM,gBAA4B;AAAA,EACvC,OAAO;AAAA,IACL,cAAc;AAAA,IACd,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,cAAc;AAAA,MACd,sBAAsB;AAAA,MACtB,gBAAgB;AAAA,MAChB,eAAe,CAAC;AAAA,MAChB,sBAAsB,CAAC;AAAA,MACvB,kBAAkB;AAAA,MAClB,sBAAsB;AAAA,MACtB,2BAA2B;AAAA,IAC7B;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,kBAAkB;AAAA,EACpB;AACF;AAEO,SAAS,cAAc,MAAsB;AAClD,SAAOA,MAAK,KAAK,MAAM,kBAAkB;AAC3C;AAEA,eAAsB,WAAW,MAAyC;AACxE,QAAM,aAAa,cAAc,IAAI;AACrC,QAAM,SAAkB,CAAC;AAEzB,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,YAAY,OAAO;AAC9C,aAAS,UAAU,GAAG;AAAA,EACxB,SAASC,QAAO;AACd,QAAI,cAAcA,MAAK,GAAG;AACxB,aAAO,EAAE,QAAQ,eAAe,QAAQ,WAAW;AAAA,IACrD;AACA,WAAO,KAAK,YAAY,YAAY,YAAYA,MAAK,CAAC,CAAC;AACvD,WAAO,EAAE,QAAQ,eAAe,QAAQ,WAAW;AAAA,EACrD;AAEA,QAAM,aAAa,gBAAgB,QAAQ,YAAY,MAAM;AAC7D,SAAO,EAAE,QAAQ,YAAY,QAAQ,WAAW;AAClD;AAEO,SAAS,YACd,MACA,QACA,KACQ;AACR,SAAOD,MAAK,QAAQ,MAAM,OAAO,MAAM,GAAG,CAAC;AAC7C;AAEA,SAAS,gBACP,KACA,YACA,QACY;AACZ,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO,KAAK,YAAY,YAAY,4FAAiB,CAAC;AACtD,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,OAAO,eAAe,IAAI,OAAO,YAAY,MAAM;AAAA,IACnD,YAAY,oBAAoB,IAAI,YAAY,YAAY,MAAM;AAAA,IAClE,QAAQ,gBAAgB,IAAI,QAAQ,YAAY,MAAM;AAAA,EACxD;AACF;AAEA,SAAS,eACP,KACA,YACA,QACW;AACX,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,MACL,YAAY,YAAY,oHAA0B;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,MACZ,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,oBACP,KACA,YACA,QACsB;AACtB,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI,IAAI,YAAY,QAAW;AAC7B,iBAAa;AAAA,EACf,WAAW,SAAS,IAAI,OAAO,GAAG;AAChC,iBAAa,IAAI;AAAA,EACnB,OAAO;AACL,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,iBAAa;AAAA,EACf;AAEA,MAAI;AACJ,MAAI,IAAI,iBAAiB,QAAW;AAClC,sBAAkB;AAAA,EACpB,WAAW,SAAS,IAAI,YAAY,GAAG;AACrC,sBAAkB,IAAI;AAAA,EACxB,OAAO;AACL,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,sBAAkB;AAAA,EACpB;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,cAAc;AAAA,QACZ,YAAY;AAAA,QACZ,KAAK,QAAQ;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,cAAc;AAAA,QACZ,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,QACpB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,gBAAgB;AAAA,QACd,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe;AAAA,QACb,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,QACpB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,kBAAkB;AAAA,QAChB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,QACpB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,2BAA2B;AAAA,QACzB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gBACP,KACA,YACA,QACkB;AAClB,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,MACL,YAAY,YAAY,qHAA2B;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,kBAAkB;AAAA,MAChB,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WACP,OACA,UACA,OACA,YACA,QACQ;AACR,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,YAAY,YAAY,GAAG,KAAK,6FAAkB;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBACP,OACA,UACA,OACA,YACA,QACU;AACV,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AAC3E,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,YAAY,YAAY,GAAG,KAAK,yGAAoB;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YACP,OACA,UACA,OACA,YACA,QACS;AACT,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,YAAY,YAAY,GAAG,KAAK,6FAAkB;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WACP,OACA,UACA,OACA,YACA,QACQ;AACR,MAAI,UAAU,WAAW,UAAU,aAAa,UAAU,SAAS;AACjE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,GAAG,KAAK;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBACP,OACA,UACA,OACA,YACA,QACsB;AACtB,MAAI,UAAU,aAAa,UAAU,SAAS;AAC5C,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,GAAG,KAAK;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAAc,SAAwB;AACzD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,cAAcC,QAAyB;AAC9C,MAAIA,UAAS,OAAOA,WAAU,YAAY,UAAUA,QAAO;AACzD,WAAQA,OAA4B,SAAS;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,YAAYA,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;ACzeA,SAAS,YAAAC,kBAAgB;AACzB,OAAOC,YAAU;;;ACDjB,SAAS,UAAAC,eAAc;;;ACAvB,SAAS,UAAAC,SAAQ,WAAAC,gBAAe;AAChC,OAAOC,WAAU;AAEjB,OAAO,QAAQ;AAEf,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAYD,eAAsB,aACpB,MACA,UAA+B,CAAC,GACb;AACnB,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAE,MAAMC,QAAO,IAAI,GAAI;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,oBAAI,IAAI;AAAA,IACzB,GAAG;AAAA,IACH,GAAI,QAAQ,cAAc,CAAC;AAAA,EAC7B,CAAC;AACD,QAAM,aAAa,QAAQ,YAAY,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,KAAK,CAAC;AAE3E,QAAM,KAAK,MAAM,MAAM,YAAY,YAAY,OAAO;AACtD,SAAO;AACT;AAEA,eAAsB,oBACpB,MACA,SACmB;AACnB,MAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,WAAO,CAAC;AAAA,EACV;AACA,SAAO,GAAG,QAAQ,OAAO;AAAA,IACvB,KAAK;AAAA,IACL,QAAQ,QAAQ,UAAU,CAAC;AAAA,IAC3B,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,eAAe,KACb,MACA,SACA,YACA,YACA,KACe;AACf,QAAM,QAAQ,MAAMF,SAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AAE5D,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAWC,MAAK,KAAK,SAAS,KAAK,IAAI;AAE7C,QAAI,KAAK,YAAY,GAAG;AACtB,UAAI,WAAW,IAAI,KAAK,IAAI,GAAG;AAC7B;AAAA,MACF;AACA,YAAM,KAAK,MAAM,UAAU,YAAY,YAAY,GAAG;AACtD;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,GAAG;AACjB,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,MAAMA,MAAK,QAAQ,KAAK,IAAI,EAAE,YAAY;AAChD,YAAI,CAAC,WAAW,SAAS,GAAG,GAAG;AAC7B;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;AAEA,eAAeC,QAAO,QAAkC;AACtD,MAAI;AACF,UAAMH,QAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClGA,SAAS,WAAAI,gBAAe;AACxB,OAAOC,WAAU;AAEjB,IAAM,cAAc;AASpB,eAAsB,mBACpB,WACsB;AACtB,QAAM,OAAO,MAAM,aAAa,SAAS;AACzC,QAAM,UAAU,KAAK,IAAI,CAAC,SAAS;AAAA,IACjC;AAAA,IACA,UAAUA,MAAK,KAAK,KAAK,SAAS;AAAA,IAClC,WAAWA,MAAK,KAAK,KAAK,UAAU;AAAA,IACpC,cAAcA,MAAK,KAAK,KAAK,aAAa;AAAA,EAC5C,EAAE;AACF,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,cAAc,EAAE,GAAG,CAAC;AAC1D;AAEA,eAAe,aAAa,WAAsC;AAChE,MAAI;AACF,UAAM,QAAQ,MAAMD,SAAQ,WAAW,EAAE,eAAe,KAAK,CAAC;AAC9D,WAAO,MACJ,OAAO,CAAC,SAAS,KAAK,YAAY,CAAC,EACnC,IAAI,CAAC,SAAS,KAAK,IAAI,EACvB,OAAO,CAAC,SAAS,YAAY,KAAK,KAAK,YAAY,CAAC,CAAC,EACrD,IAAI,CAAC,SAASC,MAAK,KAAK,WAAW,IAAI,CAAC;AAAA,EAC7C,SAASC,QAAO;AACd,QAAI,mBAAmBA,MAAK,GAAG;AAC7B,aAAO,CAAC;AAAA,IACV;AACA,UAAMA;AAAA,EACR;AACF;AAEA,SAAS,mBAAmBA,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;;;AFnCA,eAAsB,oBACpB,WACmB;AACnB,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAClD,SAAO,QAAQ,IAAI,CAAC,UAAU,MAAM,GAAG;AACzC;AAEA,eAAsB,iBAAiB,WAAsC;AAC3E,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAClD,SAAO,eAAe,QAAQ,IAAI,CAAC,UAAU,MAAM,QAAQ,CAAC;AAC9D;AAOA,eAAsB,qBACpB,WACmB;AACnB,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAClD,SAAO,eAAe,QAAQ,IAAI,CAAC,UAAU,MAAM,YAAY,CAAC;AAClE;AAEA,eAAsB,uBACpB,QACmB;AACnB,SAAO,aAAa,QAAQ,EAAE,YAAY,CAAC,SAAS,MAAM,EAAE,CAAC;AAC/D;AAEA,eAAsB,wBACpB,SACmB;AACnB,SAAO,aAAa,SAAS,EAAE,YAAY,CAAC,SAAS,QAAQ,OAAO,EAAE,CAAC;AACzE;AAEA,eAAsB,yBACpB,UACmB;AACnB,SAAO,aAAa,UAAU,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC;AACxD;AAEA,eAAsB,qBACpB,QACA,SACA,UACwB;AACxB,QAAM,CAAC,IAAI,KAAK,EAAE,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtC,uBAAuB,MAAM;AAAA,IAC7B,wBAAwB,OAAO;AAAA,IAC/B,yBAAyB,QAAQ;AAAA,EACnC,CAAC;AACD,SAAO,EAAE,IAAI,KAAK,GAAG;AACvB;AAEA,eAAe,eAAe,OAAoC;AAChE,QAAM,WAAqB,CAAC;AAC5B,aAAW,QAAQ,OAAO;AACxB,QAAI,MAAMC,QAAO,IAAI,GAAG;AACtB,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAeA,QAAO,QAAkC;AACtD,MAAI;AACF,UAAMC,QAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AGhFA,IAAM,cAA0B,CAAC,QAAQ,MAAM,MAAM,MAAM,OAAO,MAAM;AAExE,IAAM,qBAAqD;AAAA,EACzD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AACP;AAEA,IAAM,oBAAoD;AAAA,EACxD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AACP;AAEO,SAAS,WAAW,MAAc,QAA4B;AACnE,QAAM,UAAU,mBAAmB,MAAM;AACzC,QAAM,UAAU,KAAK,MAAM,OAAO;AAClC,SAAO,OAAO,WAAW,CAAC,CAAC;AAC7B;AAEO,SAAS,cAAc,MAAwB;AACpD,QAAM,MAAgB,CAAC;AACvB,cAAY,QAAQ,CAAC,WAAW;AAC9B,QAAI,KAAK,GAAG,WAAW,MAAM,MAAM,CAAC;AAAA,EACtC,CAAC;AACD,SAAO,OAAO,GAAG;AACnB;AAEO,SAAS,kBACd,MACA,UACU;AACV,QAAM,UAAoB,CAAC;AAC3B,aAAW,UAAU,UAAU;AAC7B,UAAM,aAAa,KAAK,MAAM,kBAAkB,MAAM,CAAC,KAAK,CAAC;AAC7D,eAAW,aAAa,YAAY;AAClC,UAAI,CAAC,UAAU,WAAW,MAAM,GAAG;AACjC,gBAAQ,KAAK,SAAS;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO,OAAO;AACvB;AAEA,SAAS,OAAO,QAA4B;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AACnC;AAEA,SAAS,UAAU,OAAe,QAAiC;AACjE,QAAM,UAAU,mBAAmB,MAAM;AACzC,QAAM,SAAS,IAAI,OAAO,QAAQ,MAAM;AACxC,SAAO,OAAO,KAAK,KAAK;AAC1B;;;AC/DA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,WAAU;;;ACDjB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;AAOpB,SAAS,aAAa,QAAgB,KAA4B;AACvE,QAAM,SAAmB,CAAC;AAC1B,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,UAAU,IAAI,WAAW,MAAM;AACrC,QAAM,UAAU,IAAI,2BAA2B;AAC/C,QAAM,SAAS,IAAI,OAAO,SAAS,OAAO;AAE1C,MAAI;AACF,UAAM,kBAAkB,OAAO,MAAM,MAAM;AAC3C,oBAAgB,MAAM;AACtB,WAAO,EAAE,iBAAiB,OAAO;AAAA,EACnC,SAASC,QAAO;AACd,WAAO,KAAKC,aAAYD,MAAK,CAAC;AAC9B,WAAO,EAAE,iBAAiB,MAAM,OAAO;AAAA,EACzC;AACF;AAEA,SAASC,aAAYD,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;;;AC9BA,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,aAAa;AACnB,IAAM,cAAc;AAoCb,SAAS,sBACd,MACA,KACqB;AACrB,QAAM,EAAE,iBAAiB,OAAO,IAAI,aAAa,MAAM,GAAG;AAC1D,MAAI,CAAC,iBAAiB;AACpB,WAAO,EAAE,UAAU,MAAM,OAAO;AAAA,EAClC;AAEA,QAAM,UAAU,gBAAgB;AAChC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,UAAU,EAAE,KAAK,aAAa,CAAC,GAAG,WAAW,CAAC,EAAE;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,gBAAgB,QAAQ,IAAI;AAChD,QAAM,YAAY,qBAAqB,SAAS,WAAW;AAC3D,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,MACA,aAAa,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,UAA4C;AAC7E,SAAO,SAAS,UAAU,IAAI,CAAC,aAAa;AAC1C,UAAM,UAAU,SAAS,KAAK,OAAO,CAAC,QAAQ,YAAY,KAAK,GAAG,CAAC;AACnE,UAAM,QAAQ,SAAS,KAAK,OAAO,CAAC,QAAQ,UAAU,KAAK,GAAG,CAAC;AAC/D,UAAM,QAAQE,QAAO,SAAS,KAAK,OAAO,CAAC,QAAQ,UAAU,KAAK,GAAG,CAAC,CAAC;AAEvE,UAAM,cAAc,oBAAI,IAAY;AACpC,aAAS,KAAK,QAAQ,CAAC,QAAQ;AAC7B,UACE,UAAU,KAAK,GAAG,KAClB,WAAW,KAAK,GAAG,KACnB,YAAY,KAAK,GAAG,GACpB;AACA,oBAAY,IAAI,GAAG;AAAA,MACrB;AAAA,IACF,CAAC;AAED,eAAW,QAAQ,SAAS,OAAO;AACjC,iBAAW,QAAQ,iBAAiB,IAAI,GAAG;AACzC,mBAAW,MAAM,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAC1D,mBAAW,MAAM,KAAK,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAC3D,mBAAW,MAAM,MAAM,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAAA,MAC9D;AAAA,IACF;AAEA,UAAM,OAAqB;AAAA,MACzB,KAAK,SAAS;AAAA,MACd,aAAa,SAAS,eAAe;AAAA,MACrC,cAAc,SAAS;AAAA,MACvB,MAAM,SAAS;AAAA,MACf;AAAA,MACA,aAAa,MAAM,KAAK,WAAW,EAAE,KAAK;AAAA,IAC5C;AAEA,QAAI,SAAS,SAAS,QAAW;AAC/B,WAAK,OAAO,SAAS;AAAA,IACvB;AACA,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,SAAS,QAAQ,CAAC;AACxB,UAAI,QAAQ;AACV,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AACA,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,MAAM;AACR,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,qBACP,SACA,aACgB;AAChB,QAAM,YAA4B,CAAC;AAEnC,aAAW,SAAS,QAAQ,UAAU;AACpC,QAAI,MAAM,UAAU;AAClB,gBAAU,KAAK,kBAAkB,MAAM,UAAU,aAAa,CAAC,CAAC,CAAC;AAAA,IACnE;AACA,QAAI,MAAM,MAAM;AACd,YAAM,WAAW,gBAAgB,MAAM,KAAK,IAAI;AAChD,iBAAW,aAAa,MAAM,KAAK,UAAU;AAC3C,YAAI,UAAU,UAAU;AACtB,oBAAU;AAAA,YACR,kBAAkB,UAAU,UAAU,aAAa,QAAQ;AAAA,UAC7D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,UACA,aACA,UACc;AACd,QAAM,OAAO,CAAC,GAAG,aAAa,GAAG,UAAU,GAAG,gBAAgB,SAAS,IAAI,CAAC;AAC5E,QAAM,OACJ,SAAS,SAAS,SAAS,IAAI,oBAAoB;AACrD,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf;AAAA,IACA,MAAM,SAAS,UAAU;AAAA,IACzB;AAAA,IACA,OAAO,SAAS;AAAA,EAClB;AACF;AAEA,SAAS,gBAAgB,MAAyC;AAChE,SAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,KAAK,QAAQ,MAAM,EAAE,CAAC;AACrD;AAEA,SAAS,iBAAiB,MAA+B;AACvD,QAAM,QAAkB,CAAC;AACzB,MAAI,KAAK,MAAM;AACb,UAAM,KAAK,KAAK,IAAI;AAAA,EACtB;AACA,MAAI,KAAK,WAAW,SAAS;AAC3B,UAAM,KAAK,KAAK,UAAU,OAAO;AAAA,EACnC;AACA,MAAI,KAAK,WAAW,MAAM;AACxB,eAAW,OAAO,KAAK,UAAU,MAAM;AACrC,iBAAW,QAAQ,IAAI,OAAO;AAC5B,cAAM,KAAK,KAAK,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAASA,QAAO,QAA4B;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AACnC;;;AF9LO,IAAMC,aAAY;AAClB,IAAM,wBAAwB;AAC9B,IAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsBO,SAAS,sBAAsB,MAAwB;AAC5D,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,SAAS,KAAK,SAAS,qBAAqB,GAAG;AACxD,UAAM,SAAS,MAAM,CAAC;AACtB,QAAI,QAAQ;AACV,UAAI,IAAI,MAAM,MAAM,EAAE;AAAA,IACxB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;AAEA,eAAsB,8BACpB,eACsB;AACtB,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AAEA,eAAW,YAAY,SAAS,WAAW;AACzC,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAID,WAAU,KAAK,GAAG,GAAG;AACvB,gBAAM,IAAI,GAAG;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,oCACpB,eACmC;AACnC,QAAM,UAAU,oBAAI,IAAyB;AAC7C,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AAEA,eAAW,YAAY,SAAS,WAAW;AACzC,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAI,CAACD,WAAU,KAAK,GAAG,GAAG;AACxB;AAAA,QACF;AACA,cAAM,UAAU,QAAQ,IAAI,GAAG,KAAK,oBAAI,IAAY;AACpD,gBAAQ,IAAI,IAAI;AAChB,gBAAQ,IAAI,KAAK,OAAO;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,wBACpB,MACA,OACA,cACgC;AAChC,QAAM,OAAO,oBAAI,IAAyB;AAC1C,QAAM,kBAAkB,eAAe,KAAK;AAC5C,QAAM,yBAAyB,eAAe,YAAY;AAC1D,QAAM,qBAAqB,MAAM;AAAA,IAC/B,oBAAI,IAAI,CAAC,GAAG,iCAAiC,GAAG,sBAAsB,CAAC;AAAA,EACzE;AACA,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,cAAc;AAAA,QACd,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAkB,CAAC;AACvB,MAAI;AACF,YAAQ,MAAM,oBAAoB,MAAM;AAAA,MACtC,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,CAAC;AAAA,EACH,SAASE,QAAO;AACd,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,cAAc;AAAA,QACd,kBAAkB;AAAA,MACpB;AAAA,MACA,OAAOC,aAAYD,MAAK;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAAA,IAC5B,IAAI,IAAI,MAAM,IAAI,CAAC,SAASE,MAAK,UAAU,IAAI,CAAC,CAAC;AAAA,EACnD;AACA,aAAW,QAAQ,iBAAiB;AAClC,UAAM,OAAO,MAAMH,UAAS,MAAM,OAAO;AACzC,UAAM,QAAQ,sBAAsB,IAAI;AACxC,QAAI,MAAM,WAAW,GAAG;AACtB;AAAA,IACF;AACA,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,IAAI,IAAI,KAAK,oBAAI,IAAY;AAClD,cAAQ,IAAI,IAAI;AAChB,WAAK,IAAI,MAAM,OAAO;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,cAAc;AAAA,MACd,kBAAkB,gBAAgB;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,gBACd,OACA,MACY;AACZ,QAAM,cAAc,cAAc,KAAK;AACvC,QAAM,aAAuC,CAAC;AAC9C,QAAM,aAAuB,CAAC;AAC9B,MAAI,UAAU;AAEd,aAAW,QAAQ,aAAa;AAC9B,UAAM,QAAQ,KAAK,IAAI,IAAI;AAC3B,UAAM,cAAc,QAAQ,cAAc,KAAK,IAAI,CAAC;AACpD,eAAW,IAAI,IAAI;AACnB,QAAI,YAAY,WAAW,GAAG;AAC5B,iBAAW,KAAK,IAAI;AAAA,IACtB,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,YAAY;AAAA,IACnB;AAAA,IACA,SAAS,WAAW;AAAA,IACpB;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,cAAc,QAAoC;AACzD,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AACtE;AAEA,SAAS,eAAe,OAA2B;AACjD,SAAO,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AAC1E;AAEA,SAASE,aAAYD,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;;;AG7MA,SAAS,YAAAG,iBAAgB;AACzB,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAI9B,eAAsB,qBAAsC;AAC1D,MAEE,QAAsB,SAAS,GAC/B;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,cAAc,uBAAuB;AAC3C,UAAM,MAAM,MAAMF,UAAS,aAAa,OAAO;AAC/C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,WAAO,QAAQ,SAAS,IAAI,UAAU;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,yBAAiC;AACxC,QAAM,OAAO,YAAY;AACzB,QAAM,WAAW,KAAK,WAAW,OAAO,IAAIE,eAAc,IAAI,IAAI;AAClE,SAAOD,MAAK,QAAQA,MAAK,QAAQ,QAAQ,GAAG,oBAAoB;AAClE;;;AC7BA,SAAS,YAAAE,iBAAgB;AACzB,OAAOC,YAAU;;;ACDjB,OAAOC,WAAU;AAEjB,SAAS,SAASC,kBAAiB;AAI5B,SAAS,wBACd,MACA,MACyB;AACzB,QAAM,MAAMC,MAAK,QAAQ,IAAI,EAAE,YAAY;AAC3C,MAAI,QAAQ,SAAS;AACnB,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AACA,SAAOC,WAAU,IAAI;AACvB;AAEO,SAAS,qBAAqB,KAAwC;AAC3E,QAAM,KAAK,OAAO,IAAI,OAAO,WAAW,IAAI,KAAK;AACjD,SAAO,WAAW,IAAI,IAAI;AAC5B;AAEO,SAAS,sBAAsB,KAAwC;AAC5E,QAAM,eAAe,oBAAI,IAAY;AACrC,sBAAoB,KAAK,YAAY;AAErC,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,eAAe,cAAc;AACtC,eAAW,aAAa,KAAK,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;AAAA,EAC5D;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;AAEO,SAAS,oBAAoB,OAAgB,KAAwB;AAC1E,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC;AAAA,EACF;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAW,QAAQ,OAAO;AACxB,0BAAoB,MAAM,GAAG;AAAA,IAC/B;AACA;AAAA,EACF;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,QAAQ,iBAAiB,OAAO,UAAU,UAAU;AACtD,UAAI,IAAI,KAAK;AACb;AAAA,IACF;AACA,wBAAoB,OAAO,GAAG;AAAA,EAChC;AACF;;;ADjCA,IAAM,yBAAoE;AAAA,EACxE,EAAE,SAAS,qBAAqB,OAAO,aAAa;AAAA,EACpD,EAAE,SAAS,wBAAwB,OAAO,gBAAgB;AAAA,EAC1D,EAAE,SAAS,iBAAiB,OAAO,WAAW;AAAA,EAC9C;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,MACA,QACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,gBAAgB,YAAY,MAAM,QAAQ,cAAc;AAE9D,SAAO,KAAK,GAAI,MAAM,oBAAoBC,OAAK,KAAK,eAAe,IAAI,CAAC,CAAE;AAC1E,SAAO,KAAK,GAAI,MAAM,qBAAqBA,OAAK,KAAK,eAAe,KAAK,CAAC,CAAE;AAC5E,SAAO,KAAK,GAAI,MAAM,sBAAsBA,OAAK,KAAK,eAAe,IAAI,CAAC,CAAE;AAE5E,SAAO;AACT;AAEA,eAAe,oBAAoB,QAAkC;AACnE,QAAM,QAAQ,MAAM,uBAAuB,MAAM;AACjD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,aAAa,kBAAkB,MAAM;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,YAAM,wBAAwB,MAAM,IAAI;AAAA,IAC1C,SAASC,QAAO;AACd,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,wGAAwB,IAAI,KAAKC,aAAYD,MAAK,CAAC;AAAA,UACnD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AACA,UAAM,QAAQ,qBAAqB,GAAG;AACtC,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,uFAAgC,IAAI;AAAA,UACpC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,qBAAqB,SAAmC;AACrE,QAAM,QAAQ,MAAM,wBAAwB,OAAO;AACnD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMD,UAAS,MAAM,OAAO;AACzC,UAAM,aAAa,kBAAkB,MAAM;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,YAAM,wBAAwB,MAAM,IAAI;AAAA,IAC1C,SAASC,QAAO;AACd,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,yGAAyB,IAAI,KAAKC,aAAYD,MAAK,CAAC;AAAA,UACpD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,CAAC,WAAW,GAAG,GAAG;AACpB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,sBAAsB,GAAG;AACxC,QAAI,OAAO,WAAW,GAAG;AACvB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,yFAAkC,IAAI;AAAA,UACtC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,sBAAsB,UAAoC;AACvE,QAAM,QAAQ,MAAM,yBAAyB,QAAQ;AACrD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMD,UAAS,MAAM,OAAO;AACzC,UAAM,aAAa,kBAAkB,MAAM;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,GAAG,QAAQ,MAAM,IAAI,CAAC;AAAA,EACpC;AAEA,SAAO;AACT;AAEO,SAAS,QAAQ,MAAc,MAAuB;AAC3D,QAAM,SAAkB,CAAC;AACzB,aAAW,EAAE,SAAS,MAAM,KAAK,wBAAwB;AACvD,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,wFAAuB,KAAK;AAAA,UAC5B;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,KAAuC;AACzD,SAAO,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,SAAS;AACjE;AAEA,SAASE,aAAYD,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;AAEA,SAAS,MACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAME,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;AElSA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,YAAU;AAOjB,IAAM,aAAa;AACnB,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAE1B,eAAsB,eACpB,MACA,QACkB;AAClB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,QAAQ,MAAM,oBAAoB,SAAS;AACjD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAYC,OAAK,KAAK,MAAM,UAAU;AAC5C,QAAI;AACJ,QAAI;AACF,aAAO,MAAMC,UAAS,WAAW,OAAO;AAAA,IAC1C,SAASC,QAAO;AACd,UAAIC,oBAAmBD,MAAK,GAAG;AAC7B,eAAO;AAAA,UACLE;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAMF;AAAA,IACR;AAEA,UAAM,aAAa,WAAW,KAAK,IAAI;AACvC,UAAM,mBAAmB,eAAe,KAAK,IAAI;AACjD,UAAM,YAAY,eAAe,KAAK,IAAI;AAC1C,QAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,WAAW;AAClD,aAAO;AAAA,QACLE;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,uBAAuB,kBAAkB,KAAK,IAAI;AACxD,UAAM,gBAAgB,kBAAkB,KAAK,IAAI;AACjD,QAAI,yBAAyB,eAAe;AAC1C,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASD,oBAAmBD,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;AAEA,SAASE,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;AC9GA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,YAAU;;;ACDjB,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,YAAU;AAuBjB,eAAsB,mBACpB,MACA,QACwB;AACxB,QAAM,gBAAgB,YAAY,MAAM,QAAQ,cAAc;AAC9D,QAAM,SAASC,OAAK,KAAK,eAAe,IAAI;AAC5C,QAAM,UAAUA,OAAK,KAAK,eAAe,KAAK;AAC9C,QAAM,WAAWA,OAAK,KAAK,eAAe,IAAI;AAE9C,QAAM,CAAC,SAAS,UAAU,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvD,uBAAuB,MAAM;AAAA,IAC7B,wBAAwB,OAAO;AAAA,IAC/B,yBAAyB,QAAQ;AAAA,EACnC,CAAC;AAED,QAAM,QAAuB;AAAA,IAC3B,KAAK,oBAAI,IAAY;AAAA,IACrB,WAAW,oBAAI,IAAyB;AAAA,IACxC,OAAO,EAAE,IAAI,SAAS,KAAK,UAAU,MAAM,UAAU;AAAA,IACrD,4BAA4B,oBAAI,IAAY;AAAA,EAC9C;AAEA,QAAM,iBAAiB,SAAS,KAAK;AACrC,QAAM,kBAAkB,UAAU,KAAK;AACvC,QAAM,mBAAmB,WAAW,KAAK;AAEzC,SAAO;AACT;AAEA,eAAe,iBACb,OACA,OACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,QAAI;AACF,YAAM,MAAM,wBAAwB,MAAM,IAAI;AAC9C,2BAAqB,GAAG,EAAE,QAAQ,CAAC,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC;AAAA,IACnE,QAAQ;AACN,YAAM,2BAA2B,IAAI,IAAI;AACzC,iBAAW,MAAM,IAAI,EAAE,QAAQ,CAAC,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC;AAAA,IAChE;AAAA,EACF;AACF;AAEA,eAAe,kBACb,OACA,OACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMA,UAAS,MAAM,OAAO;AACzC,QAAI;AACF,YAAM,MAAM,wBAAwB,MAAM,IAAI;AAC9C,4BAAsB,GAAG,EAAE,QAAQ,CAAC,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC;AAAA,IACpE,QAAQ;AACN,YAAM,2BAA2B,IAAI,IAAI;AACzC,iBAAW,MAAM,KAAK,EAAE,QAAQ,CAAC,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC;AAAA,IACjE;AAAA,EACF;AACF;AAEA,eAAe,mBACb,OACA,OACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMA,UAAS,MAAM,OAAO;AACzC,eAAW,MAAM,MAAM,EAAE,QAAQ,CAAC,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC;AAAA,EAClE;AACF;AAEA,SAAS,OAAO,OAAsB,IAAY,MAAoB;AACpE,QAAM,IAAI,IAAI,EAAE;AAChB,QAAM,UAAU,MAAM,UAAU,IAAI,EAAE,KAAK,oBAAI,IAAY;AAC3D,UAAQ,IAAI,IAAI;AAChB,QAAM,UAAU,IAAI,IAAI,OAAO;AACjC;;;AC3FA,IAAM,aAAa;AAEZ,SAAS,cAAc,IAAuB;AACnD,QAAM,QAAQ,GAAG,MAAM,OAAO;AAC9B,QAAM,WAAsB,CAAC;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC,KAAK;AACzB,UAAM,QAAQ,KAAK,MAAM,UAAU;AACnC,QAAI,CAAC,MAAO;AACZ,UAAM,aAAa,MAAM,CAAC;AAC1B,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,CAAC,cAAc,CAAC,MAAO;AAC3B,aAAS,KAAK;AAAA,MACZ,OAAO,WAAW;AAAA,MAClB,OAAO,MAAM,KAAK;AAAA,MAClB,MAAM,IAAI;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,IAAoC;AACpE,QAAM,QAAQ,GAAG,MAAM,OAAO;AAC9B,QAAM,WAAW,cAAc,EAAE,EAAE,OAAO,CAAC,YAAY,QAAQ,UAAU,CAAC;AAC1E,QAAM,WAAW,oBAAI,IAAuB;AAE5C,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,UAAU,SAAS,CAAC;AAC1B,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,SAAS,IAAI,CAAC;AAC3B,UAAM,YAAY,QAAQ,OAAO;AACjC,UAAM,WAAW,MAAM,QAAQ,MAAM,SAAS,KAAK;AACnD,UAAM,OACJ,aAAa,UACT,MAAM,MAAM,YAAY,GAAG,OAAO,EAAE,KAAK,IAAI,IAC7C;AAEN,aAAS,IAAI,QAAQ,MAAM,KAAK,GAAG;AAAA,MACjC,OAAO,QAAQ,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACtBA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,0BACJ;AACF,IAAM,yBACJ;AAEF,IAAM,mBAAmB;AACzB,IAAM,mBAAmB,oBAAI,IAAgB,CAAC,MAAM,MAAM,MAAM,IAAI,CAAC;AAE9D,SAAS,UAAU,IAAY,MAA0B;AAC9D,QAAM,WAAW,cAAc,EAAE;AACjC,QAAM,KAAK,SAAS,KAAK,CAAC,YAAY,QAAQ,UAAU,CAAC;AACzD,QAAM,SAAS,IAAI,MAAM,MAAM,UAAU,IAAI,CAAC;AAE9C,QAAM,WAAW,kBAAkB,EAAE;AACrC,QAAM,eAAe,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,CAAC,CAAC;AACxD,QAAM,YAAY,SAAS,IAAI,gBAAgB;AAC/C,QAAM,UAAU,YAAY,UAAU,KAAK,MAAM,OAAO,IAAI,CAAC;AAC7D,QAAM,YAAY,WAAW,aAAa;AAE1C,QAAM,MAAkB,CAAC;AACzB,QAAM,qBAAgD,CAAC;AACvD,QAAM,yBAAwD,CAAC;AAE/D,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,WAAW,QAAQ,CAAC,KAAK;AAC/B,UAAM,aAAa,YAAY;AAE/B,UAAM,aAAa,SAAS,MAAM,UAAU;AAC5C,QAAI,YAAY;AACd,YAAM,KAAK,WAAW,CAAC;AACvB,YAAM,WAAW,WAAW,CAAC;AAC7B,YAAM,OAAO,WAAW,CAAC;AACzB,UAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAM;AAC/B,UAAI,KAAK;AAAA,QACP;AAAA,QACA;AAAA,QACA,MAAM,KAAK,KAAK;AAAA,QAChB,MAAM;AAAA,MACR,CAAC;AACD;AAAA,IACF;AAEA,UAAM,mBAAmB,SAAS,MAAM,uBAAuB;AAC/D,QAAI,kBAAkB;AACpB,YAAM,KAAK,iBAAiB,CAAC;AAC7B,YAAM,WAAW,iBAAiB,CAAC;AACnC,YAAM,OAAO,iBAAiB,CAAC;AAC/B,UAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAM;AAC/B,UAAI,CAAC,iBAAiB,IAAI,QAAsB,GAAG;AACjD,+BAAuB,KAAK;AAAA,UAC1B;AAAA,UACA;AAAA,UACA,MAAM,KAAK,KAAK;AAAA,UAChB,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,UAAM,kBAAkB,SAAS,MAAM,sBAAsB;AAC7D,QAAI,iBAAiB;AACnB,YAAM,KAAK,gBAAgB,CAAC;AAC5B,YAAM,OAAO,gBAAgB,CAAC;AAC9B,UAAI,CAAC,MAAM,CAAC,KAAM;AAClB,yBAAmB,KAAK;AAAA,QACtB;AAAA,QACA,MAAM,KAAK,KAAK;AAAA,QAChB,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,QAAQ;AACV,WAAO,SAAS;AAAA,EAClB;AACA,SAAO;AACT;;;AH3GA,IAAMC,aAAY;AAElB,eAAsB,mBACpB,MACA,QACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AAEtD,QAAM,YAAY,MAAM,iBAAiB,SAAS;AAClD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAE1D,QAAM,UAAU,oBAAI,IAAyB;AAE7C,QAAM,yBAAyB,WAAW,OAAO;AACjD,QAAM,6BAA6B,eAAe,OAAO;AACzD,QAAM,gBAAgB,MAAM,mBAAmB,MAAM,MAAM;AAC3D,aAAW,CAAC,IAAI,KAAK,KAAK,cAAc,UAAU,QAAQ,GAAG;AAC3D,eAAW,QAAQ,OAAO;AACxB,eAAS,SAAS,IAAI,IAAI;AAAA,IAC5B;AAAA,EACF;AAEA,aAAW,CAAC,IAAI,KAAK,KAAK,QAAQ,QAAQ,GAAG;AAC3C,QAAI,MAAM,QAAQ,GAAG;AACnB;AAAA,IACF;AACA,UAAM,SAAS,MAAM,KAAK,KAAK,EAAE,KAAK;AACtC,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,wDAAgB,EAAE,KAAK,eAAe,QAAQ,IAAI,CAAC;AAAA,QACnD;AAAA,QACA,OAAO,CAAC;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,yBACb,OACA,KACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,SAAS,UAAU,MAAM,IAAI;AACnC,QAAI,OAAO,QAAQ;AACjB,eAAS,KAAK,OAAO,QAAQ,IAAI;AAAA,IACnC;AACA,WAAO,IAAI,QAAQ,CAAC,OAAO,SAAS,KAAK,GAAG,IAAI,IAAI,CAAC;AAAA,EACvD;AACF;AAEA,eAAe,6BACb,OACA,KACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMA,UAAS,MAAM,OAAO;AACzC,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AACA,eAAW,YAAY,SAAS,WAAW;AACzC,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAIF,WAAU,KAAK,GAAG,GAAG;AACvB,mBAAS,KAAK,KAAK,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,SACP,KACA,IACA,MACM;AACN,QAAM,UAAU,IAAI,IAAI,EAAE,KAAK,oBAAI,IAAY;AAC/C,UAAQ,IAAI,IAAI;AAChB,MAAI,IAAI,IAAI,OAAO;AACrB;AAEA,SAAS,eAAe,OAAiB,MAAsB;AAC7D,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,UAAM,WAAWG,OAAK,SAAS,MAAM,IAAI;AACzC,WAAO,SAAS,SAAS,IAAI,WAAW;AAAA,EAC1C,CAAC,EACA,KAAK,IAAI;AACd;AAEA,SAASF,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;AIjIA,SAAS,YAAAG,iBAAgB;AASzB,IAAM,gBAAgB;AACtB,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAMC,aAAY;AAClB,IAAMC,eAAc;AAEpB,eAAsB,kBACpB,MACA,QACkB;AAClB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAElD,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,WAAW;AACjB,UAAM,SAAS;AACf,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,oHAA+B,OAAO,MAAM,QAAQ,4CAAc,QAAQ,KAAK,MAAM;AAAA,QACrF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,QAAI;AACJ,QAAI;AACF,aAAO,MAAMC,UAAS,MAAM,cAAc,OAAO;AAAA,IACnD,SAASC,QAAO;AACd,UAAIC,oBAAmBD,MAAK,GAAG;AAC7B,eAAO;AAAA,UACLF;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAME;AAAA,IACR;AACA,WAAO,KAAK,GAAG,wBAAwB,MAAM,MAAM,YAAY,CAAC;AAAA,EAClE;AAEA,SAAO;AACT;AAEO,SAAS,wBAAwB,MAAc,MAAuB;AAC3E,QAAM,SAAkB,CAAC;AAEzB,QAAM,aAAa,kBAAkB,MAAM;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO;AAAA,MACLF;AAAA,QACE;AAAA,QACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,MAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,yEAAuB,OAAO,KAAK,IAAI,KAAK,SAAS;AAAA,QACrD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,SAAS,YAAY;AAAA,IAAO,CAAC,QACnDD,aAAY,KAAK,GAAG;AAAA,EACtB;AACA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,+EAA6B,gBAAgB,KAAK,IAAI,CAAC;AAAA,QACvD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAA6B,CAAC;AACpC,MAAI,CAAC,SAAS,YAAa,kBAAiB,KAAK,SAAS;AAC1D,MAAI,SAAS,UAAU,WAAW,EAAG,kBAAiB,KAAK,UAAU;AACrE,MAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,8GAA8B,iBAAiB;AAAA,UAC7C;AAAA,QACF,CAAC;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,YAAY,SAAS,WAAW;AACzC,QAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,0EAAwB,SAAS,IAAI;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,cAAwB,CAAC;AAC/B,UAAM,SAAS,SAAS,KAAK,OAAO,CAAC,QAAQF,WAAU,KAAK,GAAG,CAAC;AAChE,QAAI,OAAO,WAAW,GAAG;AACvB,kBAAY,KAAK,aAAQ;AAAA,IAC3B,WAAW,OAAO,SAAS,GAAG;AAC5B,kBAAY,KAAK,MAAM,OAAO,MAAM,6BAAS;AAAA,IAC/C;AACA,QAAI,YAAY,SAAS,GAAG;AAC1B,aAAO;AAAA,QACLE;AAAA,UACE;AAAA,UACA,0EAAwB,YAAY,KAAK,IAAI,CAAC,KAC5C,SAAS,IACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,YAAY,SAAS,WAAW;AACzC,UAAM,eAAyB,CAAC;AAChC,UAAM,WAAW,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,QAAQ,KAAK,CAAC;AACjE,QAAI,CAAC,SAAS,KAAK,CAAC,YAAY,cAAc,KAAK,OAAO,CAAC,GAAG;AAC5D,mBAAa,KAAK,OAAO;AAAA,IAC3B;AACA,QAAI,CAAC,SAAS,KAAK,CAAC,YAAY,aAAa,KAAK,OAAO,CAAC,GAAG;AAC3D,mBAAa,KAAK,MAAM;AAAA,IAC1B;AACA,QAAI,CAAC,SAAS,KAAK,CAAC,YAAY,aAAa,KAAK,OAAO,CAAC,GAAG;AAC3D,mBAAa,KAAK,MAAM;AAAA,IAC1B;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,qEAA6B,aAAa,KAAK,IAAI,CAAC,KAClD,SAAS,IACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASA,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;AAEA,SAASG,oBAAmBD,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;;;ACtOA,SAAS,YAAAE,iBAAgB;AAQzB,eAAsB,cACpB,MACA,QACkB;AAClB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAElD,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,WAAW;AACjB,UAAM,SAAS;AACf,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,gHAA2B,OAAO,MAAM,QAAQ,4CAAc,QAAQ,KAAK,MAAM;AAAA,QACjF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,QAAI;AACJ,QAAI;AACF,aAAO,MAAMC,UAAS,MAAM,UAAU,OAAO;AAAA,IAC/C,SAASC,QAAO;AACd,UAAIC,oBAAmBD,MAAK,GAAG;AAC7B,eAAO;AAAA,UACLF;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAME;AAAA,IACR;AACA,WAAO;AAAA,MACL,GAAG;AAAA,QACD;AAAA,QACA,MAAM;AAAA,QACN,OAAO,WAAW,QAAQ;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,oBACd,MACA,MACA,kBACS;AACT,QAAM,SAAkB,CAAC;AAEzB,QAAM,SAAS,UAAU,MAAM,IAAI;AAEnC,QAAM,aAAa,kBAAkB,MAAM;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO;AAAA,MACLF;AAAA,QACE;AAAA,QACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,IAAI,WAAW,GAAG;AAC3B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,OAAO,oBAAoB;AAC1C,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,kEAA0B,GAAG,EAAE;AAAA,QAC/B;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,GAAG,EAAE;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,OAAO,wBAAwB;AAC9C,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,+CAAsB,GAAG,EAAE,KAAK,GAAG,QAAQ;AAAA,QAC3C;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,GAAG,EAAE;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,WAAW,kBAAkB;AACtC,QAAI,CAAC,OAAO,SAAS,IAAI,OAAO,GAAG;AACjC,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,+FAAoB,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASA,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;AAEA,SAASG,oBAAmBD,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;;;AC3MA,SAAS,YAAAE,kBAAgB;AAazB,IAAMC,eAAc;AACpB,IAAMC,aAAY;AAElB,eAAsB,qBACpB,MACA,QACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,UAAU,YAAY,MAAM,QAAQ,QAAQ;AAClD,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AAEtD,QAAM,YAAY,MAAM,iBAAiB,SAAS;AAClD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAE1D,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,sBAAsB,oBAAI,IAAY;AAC5C,QAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAM,cAAc,oBAAI,IAAyB;AACjD,QAAM,gBAAgB,MAAM,mBAAmB,MAAM,MAAM;AAC3D,QAAM,cAAc,cAAc;AAElC,aAAW,QAAQ,WAAW;AAC5B,UAAM,OAAO,MAAMC,WAAS,MAAM,OAAO;AACzC,kBAAc,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAEvD,UAAM,SAAS,UAAU,MAAM,IAAI;AACnC,QAAI,OAAO,QAAQ;AACjB,cAAQ,IAAI,OAAO,MAAM;AAAA,IAC3B;AAEA,UAAM,QAAQ,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE;AAC1C,UAAM,QAAQ,CAAC,OAAO,aAAa,IAAI,EAAE,CAAC;AAE1C,QAAI,OAAO,QAAQ;AACjB,YAAM,UAAU,YAAY,IAAI,OAAO,MAAM,KAAK,oBAAI,IAAY;AAClE,YAAM,QAAQ,CAAC,OAAO,QAAQ,IAAI,EAAE,CAAC;AACrC,kBAAY,IAAI,OAAO,QAAQ,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAMA,WAAS,MAAM,OAAO;AACzC,kBAAc,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAEvD,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AAEA,UAAM,QAAQ,mBAAmB,QAAQ;AACzC,UAAM,cAAc,oBAAI,IAAY;AAEpC,eAAW,CAAC,OAAO,QAAQ,KAAK,SAAS,UAAU,QAAQ,GAAG;AAC5D,YAAM,OAAO,MAAM,KAAK;AACxB,UAAI,CAAC,MAAM;AACT;AAAA,MACF;AAEA,YAAM,WAAW,SAAS,KAAK,OAAO,CAAC,QAAQF,aAAY,KAAK,GAAG,CAAC;AACpE,YAAM,SAAS,SAAS,KAAK,OAAO,CAAC,QAAQC,WAAU,KAAK,GAAG,CAAC;AAChE,YAAM,SAAS,SAAS,KAAK,OAAO,CAAC,QAAQE,WAAU,KAAK,GAAG,CAAC;AAEhE,UAAI,SAAS,WAAW,GAAG;AACzB,eAAO;AAAA,UACLC;AAAA,YACE;AAAA,YACA,sFAA+B,SAAS,IAAI;AAAA,YAC5C;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,OAAO,WAAW,GAAG;AACvB,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,oFAA6B,SAAS,IAAI;AAAA,YAC1C;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,QAAQ,CAAC,OAAO,iBAAiB,IAAI,EAAE,CAAC;AAC/C,aAAO,QAAQ,CAAC,OAAO;AACrB,yBAAiB,IAAI,EAAE;AACvB,oBAAY,IAAI,EAAE;AAAA,MACpB,CAAC;AACD,WAAK,YAAY,QAAQ,CAAC,OAAO,oBAAoB,IAAI,EAAE,CAAC;AAE5D,UAAI,KAAK,YAAY,SAAS,GAAG;AAC/B,eAAO,QAAQ,CAAC,OAAO,gBAAgB,IAAI,EAAE,CAAC;AAAA,MAChD;AAEA,YAAM,iBAAiB,SAAS,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAC/D,UAAI,eAAe,SAAS,GAAG;AAC7B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,wGAAkC,eAAe;AAAA,cAC/C;AAAA,YACF,CAAC,KAAK,SAAS,IAAI;AAAA,YACnB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,eAAe,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;AAChE,UAAI,aAAa,SAAS,GAAG;AAC3B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,sGAAgC,aAAa;AAAA,cAC3C;AAAA,YACF,CAAC,KAAK,SAAS,IAAI;AAAA,YACnB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,qBAAqB,KAAK,YAAY;AAAA,QAC1C,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;AAAA,MAC7B;AACA,UAAI,mBAAmB,SAAS,GAAG;AACjC,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,kHAAkC,mBAAmB;AAAA,cACnD;AAAA,YACF,CAAC,KAAK,SAAS,IAAI;AAAA,YACnB,OAAO,WAAW,aAAa;AAAA,YAC/B;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS,SAAS,KAAK,OAAO,SAAS,GAAG;AAC5C,cAAM,eAAe,oBAAI,IAAY;AACrC,mBAAW,UAAU,UAAU;AAC7B,gBAAM,eAAe,YAAY,IAAI,MAAM;AAC3C,cAAI,CAAC,cAAc;AACjB;AAAA,UACF;AACA,uBAAa,QAAQ,CAAC,OAAO,aAAa,IAAI,EAAE,CAAC;AAAA,QACnD;AACA,cAAM,eAAe,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;AAChE,YAAI,aAAa,SAAS,GAAG;AAC3B,iBAAO;AAAA,YACLA;AAAA,cACE;AAAA,cACA,gGAAoC,aAAa;AAAA,gBAC/C;AAAA,cACF,CAAC,WAAW,SAAS,KAAK,IAAI,CAAC,MAAM,SAAS,IAAI;AAAA,cAClD;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,eAAe,MAAM,KAAK,WAAW,EAAE;AAAA,QAAK,CAAC,GAAG,MACpD,EAAE,cAAc,CAAC;AAAA,MACnB;AACA,YAAM,SACJ,aAAa,WAAW,IACpB,wDACA,+DAAkB,aAAa,KAAK,IAAI,CAAC;AAC/C,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,yFAAuC,MAAM;AAAA,UAC7C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,aAAa,gBAAgB,aAAa,OAAO,GAAG;AACxE,UAAM,cAAc,MAAM,KAAK,YAAY,EAAE;AAAA,MAC3C,CAAC,OAAO,CAAC,iBAAiB,IAAI,EAAE;AAAA,IAClC;AACA,QAAI,YAAY,SAAS,GAAG;AAC1B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,wEAAsB,YAAY,KAAK,IAAI,CAAC;AAAA,UAC5C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MACE,OAAO,WAAW,aAAa,wBAC/B,iBAAiB,OAAO,GACxB;AACA,UAAM,qBAAqB,MAAM,KAAK,gBAAgB,EAAE;AAAA,MACtD,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE;AAAA,IACjC;AACA,QAAI,mBAAmB,SAAS,GAAG;AACjC,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,6FAAiC,mBAAmB;AAAA,YAClD;AAAA,UACF,CAAC;AAAA,UACD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA,OAAO,WAAW,aAAa;AAAA,IAC/B,OAAO,WAAW,aAAa;AAAA,EACjC;AACA,QAAM,aAAa,aAAa;AAChC,QAAM,eAAe,aAAa;AAClC,QAAM,eAAe,iBAAiB,OAAO;AAC7C,QAAM,gBAAgB,aAAa,MAAM,SAAS;AAClD,QAAM,kBAAkB,aAAa,mBAAmB;AAExD,MACE,iBACC,CAAC,iBAAiB,CAAC,mBAAmB,aAAa,QACpD;AACA,UAAM,SAAS,aAAa,QAAQ,uBAAQ,aAAa,KAAK,WAAM;AACpE,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,wMAAkD,MAAM;AAAA,QACxD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,QACE,OAAO,WAAW,aAAa,kBAC/B,iBAAiB,MACjB;AACA,YAAM,iBAAiB,MAAM,KAAK,gBAAgB,EAAE,OAAO,CAAC,OAAO;AACjE,cAAM,OAAO,WAAW,IAAI,EAAE;AAC9B,eAAO,CAAC,QAAQ,KAAK,SAAS;AAAA,MAChC,CAAC;AACD,UAAI,eAAe,SAAS,GAAG;AAC7B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,4FAAsB,eAAe;AAAA,cACnC;AAAA,YACF,CAAC;AAAA,YACD,OAAO,WAAW,aAAa;AAAA,YAC/B;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,KAAK,WAAW,KAAK,CAAC,EAAE;AAAA,MACjD,CAAC,OAAO,CAAC,iBAAiB,IAAI,EAAE;AAAA,IAClC;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,6IAA+B,aAAa;AAAA,YAC1C;AAAA,UACF,CAAC;AAAA,UACD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,WAAW,aAAa,sBAAsB;AACxD,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,kBAAkB,MAAM,KAAK,WAAW,EAAE;AAAA,QAC9C,CAAC,OAAO,CAAC,oBAAoB,IAAI,EAAE;AAAA,MACrC;AACA,UAAI,gBAAgB,SAAS,GAAG;AAC9B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,6FAAuB,gBAAgB,KAAK,IAAI,CAAC;AAAA,YACjD;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAI,MAAM,uBAAuB,aAAa,SAAS,SAAS;AAAA,EAClE;AACA,SAAO;AACT;AAEA,eAAe,uBACb,aACA,SACA,WACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,YAAY,MAAM,aAAa,SAAS;AAAA,IAC5C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,YAAY,MAAM,aAAa,WAAW;AAAA,IAC9C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,cAAc,CAAC,GAAG,WAAW,GAAG,SAAS;AAE/C,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,eAAe,MAAM,KAAK,WAAW,CAAC;AACtD,MAAI,QAAQ;AAEZ,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,MAAMF,WAAS,MAAM,OAAO;AACzC,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,cAAQ;AACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACLE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,KAAuB;AAC7C,QAAM,UAAU,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,uBAAuB,MAAM,CAAC;AACzE,SAAO,IAAI,OAAO,OAAO,QAAQ,KAAK,GAAG,CAAC,MAAM;AAClD;AAEA,SAASA,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;ACzaA,eAAsB,gBACpB,MACA,cAC2B;AAC3B,QAAM,WAAW,gBAAiB,MAAM,WAAW,IAAI;AACvD,QAAM,EAAE,QAAQ,QAAQ,aAAa,IAAI;AACzC,QAAM,SAAS;AAAA,IACb,GAAG;AAAA,IACH,GAAI,MAAM,cAAc,MAAM,MAAM;AAAA,IACpC,GAAI,MAAM,eAAe,MAAM,MAAM;AAAA,IACrC,GAAI,MAAM,kBAAkB,MAAM,MAAM;AAAA,IACxC,GAAI,MAAM,kBAAkB,MAAM,MAAM;AAAA,IACxC,GAAI,MAAM,mBAAmB,MAAM,MAAM;AAAA,IACzC,GAAI,MAAM,qBAAqB,MAAM,MAAM;AAAA,EAC7C;AAEA,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAC1D,QAAM,QAAQ,MAAM,8BAA8B,aAAa;AAC/D,QAAM,EAAE,MAAM,YAAY,MAAM,UAAU,IAAI,MAAM;AAAA,IAClD;AAAA,IACA,OAAO,WAAW,aAAa;AAAA,IAC/B,OAAO,WAAW,aAAa;AAAA,EACjC;AACA,QAAM,aAAa,gBAAgB,OAAO,UAAU;AAEpD,QAAM,cAAc,MAAM,mBAAmB;AAC7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,YAAY,MAAM;AAAA,IAC1B,cAAc;AAAA,MACZ,IAAI;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,QAAmC;AACtD,SAAO,OAAO;AAAA,IACZ,CAAC,KAAKC,WAAU;AACd,UAAIA,OAAM,QAAQ,KAAK;AACvB,aAAO;AAAA,IACT;AAAA,IACA,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,EAAE;AAAA,EAClC;AACF;;;AnBAA,IAAMC,eAA0B,CAAC,QAAQ,MAAM,MAAM,MAAM,OAAO,MAAM;AAExE,eAAsB,iBACpB,MACA,YACA,cACqB;AACrB,QAAM,WAAW,gBAAiB,MAAM,WAAW,IAAI;AACvD,QAAM,SAAS,SAAS;AACxB,QAAM,aAAa,SAAS;AAE5B,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,gBAAgB,YAAY,MAAM,QAAQ,cAAc;AAC9D,QAAM,UAAUC,OAAK,KAAK,eAAe,KAAK;AAC9C,QAAM,SAASA,OAAK,KAAK,eAAe,IAAI;AAC5C,QAAM,SAASA,OAAK,KAAK,eAAe,IAAI;AAC5C,QAAM,UAAU,YAAY,MAAM,QAAQ,QAAQ;AAClD,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AAEtD,QAAM,YAAY,MAAM,iBAAiB,SAAS;AAClD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAC1D,QAAM;AAAA,IACJ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,EACN,IAAI,MAAM,qBAAqB,QAAQ,SAAS,MAAM;AAEtD,QAAM,cAAc,MAAM,WAAW;AAAA,IACnC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AAED,QAAM,cAAc,MAAM,mBAAmB;AAAA,IAC3C,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AACD,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ,MAAM,8BAA8B,aAAa;AAC/D,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA,OAAO,WAAW,aAAa;AAAA,IAC/B,OAAO,WAAW,aAAa;AAAA,EACjC;AACA,QAAM,aACJ,YAAY,cAAc,MAAM,gBAAgB,OAAO,aAAa,IAAI;AAC1E,QAAM,YAAY,YAAY,cAAc,aAAa,aAAa;AACtE,QAAM,YAAY,MAAM,oCAAoC,aAAa;AACzE,QAAM,iBAAiB,kBAAkB,SAAS;AAElD,QAAM,qBACJ,cAAe,MAAM,gBAAgB,MAAM,QAAQ;AACrD,QAAM,UAAU,MAAM,mBAAmB;AAEzC,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,OAAO,UAAU;AAAA,MACjB,WAAW,cAAc;AAAA,MACzB,WAAW;AAAA,QACT,KAAK,SAAS;AAAA,QACd,IAAI,QAAQ;AAAA,QACZ,IAAI,QAAQ;AAAA,MACd;AAAA,MACA,QAAQ,mBAAmB;AAAA,IAC7B;AAAA,IACA,KAAK;AAAA,MACH,MAAM,YAAY;AAAA,MAClB,IAAI,YAAY;AAAA,MAChB,IAAI,YAAY;AAAA,MAChB,IAAI,YAAY;AAAA,MAChB,KAAK,YAAY;AAAA,MACjB,MAAM,YAAY;AAAA,IACpB;AAAA,IACA,cAAc;AAAA,MACZ,kBAAkB,YAAY;AAAA,MAC9B,yBAAyB;AAAA,MACzB,IAAI;AAAA,MACJ,WAAW;AAAA,MACX;AAAA,IACF;AAAA,IACA,QAAQ,mBAAmB;AAAA,EAC7B;AACF;AAEO,SAAS,qBAAqB,MAA0B;AAC7D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,+BAAW,KAAK,WAAW,EAAE;AACxC,QAAM,KAAK,yBAAU,KAAK,IAAI,EAAE;AAChC,QAAM,KAAK,mBAAS,KAAK,UAAU,EAAE;AACrC,QAAM,KAAK,aAAQ,KAAK,OAAO,EAAE;AACjC,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,iBAAO;AAClB,QAAM,KAAK,YAAY,KAAK,QAAQ,KAAK,EAAE;AAC3C,QAAM,KAAK,gBAAgB,KAAK,QAAQ,SAAS,EAAE;AACnD,QAAM;AAAA,IACJ,oBAAoB,KAAK,QAAQ,UAAU,GAAG,SAAS,KAAK,QAAQ,UAAU,EAAE,SAAS,KAAK,QAAQ,UAAU,EAAE;AAAA,EACpH;AACA,QAAM;AAAA,IACJ,kBAAkB,KAAK,QAAQ,OAAO,IAAI,cAAc,KAAK,QAAQ,OAAO,OAAO,YAAY,KAAK,QAAQ,OAAO,KAAK;AAAA,EAC1H;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,mBAAS;AACpB,QAAM,KAAK,aAAa,QAAQ,KAAK,IAAI,IAAI,CAAC;AAC9C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,aAAa,OAAO,KAAK,IAAI,GAAG,CAAC;AAC5C,QAAM,KAAK,aAAa,QAAQ,KAAK,IAAI,IAAI,CAAC;AAC9C,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,qDAAa;AACxB,QAAM,KAAK,uCAAc,KAAK,aAAa,gBAAgB,EAAE;AAC7D,QAAM;AAAA,IACJ,wDAAgB,KAAK,aAAa,0BAA0B,iBAAO,cAAI;AAAA,EACzE;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,qCAAY;AACvB,QAAM,KAAK,YAAY,KAAK,aAAa,GAAG,KAAK,EAAE;AACnD,QAAM,KAAK,cAAc,KAAK,aAAa,GAAG,OAAO,EAAE;AACvD,QAAM,KAAK,cAAc,KAAK,aAAa,GAAG,OAAO,EAAE;AACvD,QAAM;AAAA,IACJ,oBAAoB,WAAW,KAAK,aAAa,UAAU,KAAK,CAAC;AAAA,EACnE;AACA,QAAM;AAAA,IACJ,2BAA2B;AAAA,MACzB,KAAK,aAAa,UAAU;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,QAAM;AAAA,IACJ,oBAAoB,KAAK,aAAa,UAAU,gBAAgB;AAAA,EAClE;AACA,MAAI,KAAK,aAAa,GAAG,WAAW,WAAW,GAAG;AAChD,UAAM,KAAK,sBAAsB;AAAA,EACnC,OAAO;AACL,UAAM,UAAU,KAAK,aAAa;AAClC,UAAM,qBAAqB,KAAK,aAAa,GAAG,WAAW,IAAI,CAAC,OAAO;AACrE,YAAM,QAAQ,QAAQ,EAAE,KAAK,CAAC;AAC9B,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO;AAAA,MACT;AACA,aAAO,GAAG,EAAE,KAAK,MAAM,KAAK,IAAI,CAAC;AAAA,IACnC,CAAC;AACD,UAAM,KAAK,iBAAiB,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7D;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,2CAAa;AACxB,QAAM,SAAS,KAAK,aAAa,GAAG;AACpC,QAAM,QAAQ,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AACnE,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,OAAO;AACxB,YAAM,OAAO,OAAO,IAAI,KAAK,CAAC;AAC9B,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,KAAK,KAAK,IAAI,UAAU;AAAA,MAChC,OAAO;AACL,cAAM,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,6BAAmB;AAC9B,QAAM,eAAe,KAAK,OAAO;AAAA,IAC/B,CAAC,SAAS,KAAK,SAAS;AAAA,EAC1B;AACA,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,cAAc;AAC/B,YAAM,WAAW,KAAK,QAAQ;AAC9B,YAAM,OACJ,KAAK,QAAQ,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK;AAClE,YAAM,KAAK,KAAK,QAAQ,KAAK,IAAI,EAAE;AAAA,IACrC;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,aAAa;AACxB,QAAM,WAAW,cAAc,KAAK,MAAM;AAC1C,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,UAAU;AAC3B,YAAM;AAAA,QACJ,KAAK,KAAK,IAAI,WAAW,KAAK,KAAK,WAAW,KAAK,KAAK,cAAc,KAAK,OAAO,WAAW,KAAK,IAAI;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,6EAAiB;AAC5B,QAAM,cAAc,KAAK,OAAO;AAAA,IAC9B,CAAC,SACC,KAAK,MAAM,WAAW,eAAe,KACrC,KAAK,KAAK,WAAW,YAAY,KACjC,KAAK,KAAK,WAAW,aAAa,KAClC,KAAK,SAAS;AAAA,EAClB;AACA,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,aAAa;AAC9B,YAAM,WAAW,KAAK,OAAO,KAAK,KAAK,IAAI,MAAM;AACjD,YAAM;AAAA,QACJ,KAAK,KAAK,SAAS,YAAY,CAAC,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,QAAQ;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,6BAAS;AACpB,MAAI,KAAK,OAAO,WAAW,GAAG;AAC5B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,KAAK,QAAQ;AAC9B,YAAM,WAAW,KAAK,OAAO,KAAK,KAAK,IAAI,MAAM;AACjD,YAAM,OACJ,KAAK,QAAQ,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK;AACvE,YAAM;AAAA,QACJ,KAAK,KAAK,SAAS,YAAY,CAAC,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,QAAQ,GAAG,IAAI;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,iBAAiB,MAA0B;AACzD,SAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AACrC;AAEA,eAAe,WACb,OACqC;AACrC,QAAM,SAAwC;AAAA,IAC5C,MAAM,oBAAI,IAAI;AAAA,IACd,IAAI,oBAAI,IAAI;AAAA,IACZ,IAAI,oBAAI,IAAI;AAAA,IACZ,IAAI,oBAAI,IAAI;AAAA,IACZ,KAAK,oBAAI,IAAI;AAAA,IACb,MAAM,oBAAI,IAAI;AAAA,EAChB;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,WAAS,MAAM,OAAO;AACzC,eAAW,UAAUF,cAAa;AAChC,YAAM,MAAM,WAAW,MAAM,MAAM;AACnC,UAAI,QAAQ,CAAC,OAAO,OAAO,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAMG,eAAc,OAAO,IAAI;AAAA,IAC/B,IAAIA,eAAc,OAAO,EAAE;AAAA,IAC3B,IAAIA,eAAc,OAAO,EAAE;AAAA,IAC3B,IAAIA,eAAc,OAAO,EAAE;AAAA,IAC3B,KAAKA,eAAc,OAAO,GAAG;AAAA,IAC7B,MAAMA,eAAc,OAAO,IAAI;AAAA,EACjC;AACF;AAEA,eAAe,mBAAmB,OAAuC;AACvE,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMD,WAAS,MAAM,OAAO;AACzC,kBAAc,IAAI,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;AAAA,EACjD;AACA,SAAO;AACT;AAEA,eAAe,qBACb,aACA,SACA,WACkB;AAClB,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,MAAM,aAAa,SAAS;AAAA,IAC5C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,YAAY,MAAM,aAAa,WAAW;AAAA,IAC9C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,cAAc,CAAC,GAAG,WAAW,GAAG,SAAS;AAE/C,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,UAAUE,gBAAe,MAAM,KAAK,WAAW,CAAC;AAEtD,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,MAAMF,WAAS,MAAM,OAAO;AACzC,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASE,gBAAe,KAAuB;AAC7C,QAAM,UAAU,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,uBAAuB,MAAM,CAAC;AACzE,SAAO,IAAI,OAAO,OAAO,QAAQ,KAAK,GAAG,CAAC,MAAM;AAClD;AAEA,SAAS,aAAa,OAAe,QAA0B;AAC7D,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO,KAAK,KAAK,KAAK,OAAO,KAAK,IAAI,CAAC;AACzC;AAEA,SAAS,WAAW,QAA0B;AAC5C,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AACA,SAAO,OAAO,KAAK,IAAI;AACzB;AAEA,SAASD,eAAc,QAA+B;AACpD,SAAO,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAC7D;AAEA,SAAS,kBACP,QAC0B;AAC1B,QAAME,UAAmC,CAAC;AAC1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC3C,IAAAA,QAAO,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAAA,EACnE;AACA,SAAOA;AACT;AAUA,SAAS,cAAc,QAA4B;AACjD,QAAM,MAAM,oBAAI,IAAqB;AACrC,aAAWC,UAAS,QAAQ;AAC1B,QAAI,CAACA,OAAM,MAAM;AACf;AAAA,IACF;AACA,UAAM,UACJ,IAAI,IAAIA,OAAM,IAAI,KACjB;AAAA,MACC,MAAMA,OAAM;AAAA,MACZ,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACF,YAAQ,SAAS;AACjB,YAAQA,OAAM,QAAQ,KAAK;AAC3B,QAAI,IAAIA,OAAM,MAAM,OAAO;AAAA,EAC7B;AAEA,SAAO,MAAM,KAAK,IAAI,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,GAAG,MACvC,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EACvE;AACF;;;AF7aA,eAAsB,UAAU,SAAuC;AACrE,QAAM,OAAOC,OAAK,QAAQ,QAAQ,IAAI;AACtC,QAAM,eAAe,MAAM,WAAW,IAAI;AAC1C,QAAM,QAAQ,aAAa,OAAO,OAAO;AACzC,QAAM,YAAYA,OAAK,WAAW,KAAK,IAAI,QAAQA,OAAK,QAAQ,MAAM,KAAK;AAC3E,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,qBAAqB,SAAS;AAAA,EACnD,SAAS,KAAK;AACZ,QAAIC,oBAAmB,GAAG,GAAG;AAC3B;AAAA,QACE;AAAA,UACE,sGAAgC,SAAS;AAAA,UACzC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,MACb;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,iBAAiB,MAAM,YAAY,YAAY;AAClE,QAAM,SACJ,QAAQ,WAAW,SACf,iBAAiB,IAAI,IACrB,qBAAqB,IAAI;AAE/B,QAAM,UAAU,YAAY,MAAM,aAAa,QAAQ,QAAQ;AAC/D,QAAM,aACJ,QAAQ,WAAW,SACfD,OAAK,KAAK,SAAS,aAAa,IAChCA,OAAK,KAAK,SAAS,WAAW;AACpC,QAAM,MAAM,QAAQ,WAAW;AAC/B,QAAM,UAAUA,OAAK,WAAW,GAAG,IAAI,MAAMA,OAAK,QAAQ,MAAM,GAAG;AAEnE,QAAME,OAAMF,OAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,QAAM,UAAU,SAAS,GAAG,MAAM;AAAA,GAAM,OAAO;AAE/C;AAAA,IACE,gBAAgB,WAAW,OAAO,IAAI,YAAY,WAAW,OAAO,OAAO,UAAU,WAAW,OAAO,KAAK;AAAA,EAC9G;AACA,OAAK,iBAAiB,OAAO,EAAE;AACjC;AAEA,eAAe,qBACb,WAC2B;AAC3B,QAAM,MAAM,MAAMG,WAAS,WAAW,OAAO;AAC7C,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,MAAI,CAAC,mBAAmB,MAAM,GAAG;AAC/B,UAAM,IAAI,MAAM,mEAA2B,SAAS,EAAE;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAA2C;AACrE,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAMC,UAAS;AACf,MAAI,OAAOA,QAAO,gBAAgB,UAAU;AAC1C,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM,QAAQA,QAAO,MAAM,GAAG;AACjC,WAAO;AAAA,EACT;AACA,QAAM,SAASA,QAAO;AACtB,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SACE,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,YAAY,YAC1B,OAAO,OAAO,UAAU;AAE5B;AAEA,SAASH,oBAAmBI,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAMD,UAASC;AACf,SAAOD,QAAO,SAAS;AACzB;;;AsB3GA,SAAS,SAAAE,QAAO,aAAAC,kBAAiB;AACjC,OAAOC,YAAU;;;ACIV,SAAS,WAAW,QAA0B,QAAyB;AAC5E,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,SAAS;AACtB,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AACA,SAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,UAAU;AACvD;;;ADGA,eAAsB,YAAY,SAA2C;AAC3E,QAAM,OAAOC,OAAK,QAAQ,QAAQ,IAAI;AACtC,QAAM,eAAe,MAAM,WAAW,IAAI;AAC1C,QAAM,SAAS,MAAM,gBAAgB,MAAM,YAAY;AAEvD,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,WAAW,QAAQ;AACrB,aAAS,MAAM;AAAA,EACjB;AACA,MAAI,WAAW,UAAU;AACvB,WAAO,OAAO,QAAQ,UAAU;AAAA,EAClC;AACA,QAAM,SAAS,QAAQ,MAAM,aAAa,OAAO,OAAO,gBAAgB;AAExE,QAAM,SAAS,cAAc,SAAS,aAAa,OAAO,WAAW,MAAM;AAC3E,SAAO,WAAW,QAAQ,MAAM,IAAI,IAAI;AAC1C;AAEA,SAAS,cAAc,SAA0B,UAA0B;AACzE,MAAI,QAAQ,QAAQ;AAClB,WAAO,QAAQ;AAAA,EACjB;AACA,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,SAAS,QAAgC;AAChD,aAAW,QAAQ,OAAO,QAAQ;AAChC,UAAM,WAAW,KAAK,OAAO,KAAK,KAAK,IAAI,MAAM;AACjD,UAAM,OACJ,KAAK,QAAQ,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK;AACvE,YAAQ,OAAO;AAAA,MACb,IAAI,KAAK,QAAQ,KAAK,KAAK,IAAI,IAAI,KAAK,OAAO,GAAG,QAAQ,GAAG,IAAI;AAAA;AAAA,IACnE;AAAA,EACF;AACA,UAAQ,OAAO;AAAA,IACb,gBAAgB,OAAO,OAAO,IAAI,YAAY,OAAO,OAAO,OAAO,UAAU,OAAO,OAAO,KAAK;AAAA;AAAA,EAClG;AACF;AAEA,SAAS,WAAWC,QAAoB;AACtC,QAAM,QACJA,OAAM,aAAa,UACf,UACAA,OAAM,aAAa,YACjB,YACA;AACR,QAAM,OAAOA,OAAM,OAAO,QAAQA,OAAM,IAAI,KAAK;AACjD,QAAM,OAAOA,OAAM,KAAK,OAAO,SAASA,OAAM,IAAI,IAAI,KAAK;AAC3D,QAAM,SAASA,OAAM,KAAK,SAAS,QAAQA,OAAM,IAAI,MAAM,KAAK;AAChE,QAAM,WAAW,OAAO,IAAI,IAAI,GAAG,IAAI,GAAG,MAAM,KAAK;AACrD,UAAQ,OAAO;AAAA,IACb,KAAK,KAAK,GAAG,QAAQ,KAAKA,OAAM,IAAI,KAAKA,OAAM,OAAO;AAAA;AAAA,EACxD;AACF;AAEA,eAAe,SACb,QACA,MACA,UACe;AACf,QAAM,MAAMD,OAAK,WAAW,QAAQ,IAChC,WACAA,OAAK,QAAQ,MAAM,QAAQ;AAC/B,QAAME,OAAMF,OAAK,QAAQ,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAMG,WAAU,KAAK,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AACtE;;;AEnEO,SAAS,UAAU,MAAgB,KAAyB;AACjE,QAAM,UAAiC;AAAA,IACrC,MAAM;AAAA,IACN,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAEA,QAAM,OAAO,CAAC,GAAG,IAAI;AACrB,MAAI,UAAU,KAAK,MAAM,KAAK;AAE9B,MAAI,YAAY,YAAY,YAAY,MAAM;AAC5C,YAAQ,OAAO;AACf,cAAU;AAAA,EACZ;AAEA,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,MAAM,KAAK,CAAC;AAClB,YAAQ,KAAK;AAAA,MACX,KAAK;AACH,gBAAQ,OAAO,KAAK,IAAI,CAAC,KAAK,QAAQ;AACtC,aAAK;AACL;AAAA,MACF,KAAK;AACH,gBAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,QAAQ;AACrC,aAAK;AACL;AAAA,MACF,KAAK;AACH,gBAAQ,QAAQ;AAChB;AAAA,MACF,KAAK;AACH,gBAAQ,MAAM;AACd;AAAA,MACF,KAAK;AACH,gBAAQ,SAAS;AACjB;AAAA,MACF,KAAK,YAAY;AACf,cAAM,OAAO,KAAK,IAAI,CAAC;AACvB,0BAAkB,SAAS,MAAM,OAAO;AACxC,aAAK;AACL;AAAA,MACF;AAAA,MACA,KAAK;AACH,gBAAQ,SAAS;AACjB;AAAA,MACF,KAAK,aAAa;AAChB,cAAM,OAAO,KAAK,IAAI,CAAC;AACvB,YAAI,SAAS,WAAW,SAAS,aAAa,SAAS,SAAS;AAC9D,kBAAQ,SAAS;AAAA,QACnB;AACA,aAAK;AACL;AAAA,MACF;AAAA,MACA,KAAK;AACH;AACE,gBAAM,OAAO,KAAK,IAAI,CAAC;AACvB,cAAI,MAAM;AACR,oBAAQ,YAAY;AAAA,UACtB;AAAA,QACF;AACA,aAAK;AACL;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,gBAAQ,OAAO;AACf;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAEA,SAAS,kBACP,SACA,OACA,SACM;AACN,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AACA,MAAI,YAAY,UAAU;AACxB,QAAI,UAAU,QAAQ,UAAU,QAAQ;AACtC,cAAQ,eAAe;AAAA,IACzB;AACA;AAAA,EACF;AACA,MAAI,YAAY,YAAY;AAC1B,QAAI,UAAU,UAAU,UAAU,UAAU;AAC1C,cAAQ,iBAAiB;AAAA,IAC3B;AACA;AAAA,EACF;AAEA,MAAI,UAAU,QAAQ,UAAU,QAAQ;AACtC,YAAQ,eAAe;AAAA,EACzB;AACA,MAAI,UAAU,UAAU,UAAU,UAAU;AAC1C,YAAQ,iBAAiB;AAAA,EAC3B;AACF;;;ACrHA,eAAsB,IAAI,MAAgB,KAA4B;AACpE,QAAM,EAAE,SAAS,QAAQ,IAAI,UAAU,MAAM,GAAG;AAEhD,MAAI,CAAC,WAAW,QAAQ,MAAM;AAC5B,SAAK,MAAM,CAAC;AACZ;AAAA,EACF;AAEA,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,YAAM,QAAQ;AAAA,QACZ,KAAK,QAAQ;AAAA,QACb,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,QAChB,KAAK,QAAQ;AAAA,MACf,CAAC;AACD;AAAA,IACF,KAAK;AACH,cAAQ,WAAW,MAAM,YAAY;AAAA,QACnC,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACnE,CAAC;AACD;AAAA,IACF,KAAK;AACH,YAAM,UAAU;AAAA,QACd,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,GAAI,QAAQ,cAAc,SACtB,EAAE,SAAS,QAAQ,UAAU,IAC7B,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACE,YAAM,oBAAoB,OAAO,EAAE;AACnC,WAAK,MAAM,CAAC;AACZ;AAAA,EACJ;AACF;AAEA,SAAS,QAAgB;AACvB,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBT;;;ACjEA,IAAI,QAAQ,KAAK,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ;AACvD,UAAQ,OAAO,MAAM,GAAG,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC5E,UAAQ,WAAW;AACrB,CAAC;","names":["path","path","path","mkdir","readFile","path","path","error","readFile","path","access","access","readdir","path","exists","readdir","path","error","exists","access","readFile","path","error","formatError","unique","SC_TAG_RE","readFile","error","formatError","path","readFile","path","fileURLToPath","readFile","path","path","parseYaml","path","parseYaml","path","readFile","error","formatError","issue","readFile","path","path","readFile","error","isMissingFileError","issue","readFile","path","readFile","path","path","readFile","SC_TAG_RE","issue","readFile","path","readFile","SC_TAG_RE","SPEC_TAG_RE","issue","readFile","error","isMissingFileError","readFile","issue","readFile","error","isMissingFileError","readFile","SPEC_TAG_RE","BR_TAG_RE","readFile","SC_TAG_RE","issue","issue","ID_PREFIXES","path","readFile","toSortedArray","buildIdPattern","record","issue","path","isMissingFileError","mkdir","readFile","record","error","mkdir","writeFile","path","path","issue","mkdir","writeFile"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/init.ts","../../src/cli/lib/fs.ts","../../src/cli/lib/assets.ts","../../src/cli/lib/logger.ts","../../src/cli/commands/report.ts","../../src/core/config.ts","../../src/core/report.ts","../../src/core/contractIndex.ts","../../src/core/discovery.ts","../../src/core/fs.ts","../../src/core/specLayout.ts","../../src/core/contractsDecl.ts","../../src/core/ids.ts","../../src/core/parse/markdown.ts","../../src/core/parse/spec.ts","../../src/core/traceability.ts","../../src/core/gherkin/parse.ts","../../src/core/scenarioModel.ts","../../src/core/version.ts","../../src/core/validators/contracts.ts","../../src/core/contracts.ts","../../src/core/validators/delta.ts","../../src/core/validators/ids.ts","../../src/core/validators/scenario.ts","../../src/core/validators/spec.ts","../../src/core/validators/traceability.ts","../../src/core/validate.ts","../../src/cli/commands/validate.ts","../../src/cli/lib/failOn.ts","../../src/cli/lib/args.ts","../../src/cli/main.ts","../../src/cli/index.ts"],"sourcesContent":["import path from \"node:path\";\n\nimport { copyTemplateTree } from \"../lib/fs.js\";\nimport { getInitAssetsDir } from \"../lib/assets.js\";\nimport { info } from \"../lib/logger.js\";\n\nexport type InitOptions = {\n dir: string;\n force: boolean;\n dryRun: boolean;\n yes: boolean;\n};\n\nexport async function runInit(options: InitOptions): Promise<void> {\n const assetsRoot = getInitAssetsDir();\n const rootAssets = path.join(assetsRoot, \"root\");\n const qfaiAssets = path.join(assetsRoot, \".qfai\");\n\n const destRoot = path.resolve(options.dir);\n const destQfai = path.join(destRoot, \".qfai\");\n\n const rootResult = await copyTemplateTree(rootAssets, destRoot, {\n force: options.force,\n dryRun: options.dryRun,\n });\n const qfaiResult = await copyTemplateTree(qfaiAssets, destQfai, {\n force: options.force,\n dryRun: options.dryRun,\n });\n\n report(\n [...rootResult.copied, ...qfaiResult.copied],\n [...rootResult.skipped, ...qfaiResult.skipped],\n options.dryRun,\n \"init\",\n );\n}\n\nfunction report(\n copied: string[],\n skipped: string[],\n dryRun: boolean,\n label: string,\n): void {\n info(`qfai ${label}: ${dryRun ? \"dry-run\" : \"done\"}`);\n if (copied.length > 0) {\n info(` created: ${copied.length}`);\n }\n if (skipped.length > 0) {\n info(` skipped: ${skipped.length}`);\n }\n}\n","import { access, copyFile, mkdir, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type CopyOptions = {\n force: boolean;\n dryRun: boolean;\n};\n\nexport type CopyResult = {\n copied: string[];\n skipped: string[];\n};\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const files = await collectTemplateFiles(sourceRoot);\n return copyFiles(files, sourceRoot, destRoot, options);\n}\n\nexport async function copyTemplatePaths(\n sourceRoot: string,\n destRoot: string,\n relativePaths: string[],\n options: CopyOptions,\n): Promise<CopyResult> {\n const allFiles: string[] = [];\n for (const relPath of relativePaths) {\n const fullPath = path.join(sourceRoot, relPath);\n const files = await collectTemplateFiles(fullPath);\n allFiles.push(...files);\n }\n\n return copyFiles(allFiles, sourceRoot, destRoot, options);\n}\n\nasync function copyFiles(\n files: string[],\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const copied: string[] = [];\n const skipped: string[] = [];\n const conflicts: string[] = [];\n\n if (!options.force) {\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n const dest = path.join(destRoot, relative);\n if (!(await shouldWrite(dest, options.force))) {\n conflicts.push(dest);\n }\n }\n\n if (conflicts.length > 0) {\n throw new Error(formatConflictMessage(conflicts));\n }\n }\n\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n const dest = path.join(destRoot, relative);\n\n if (!(await shouldWrite(dest, options.force))) {\n skipped.push(dest);\n continue;\n }\n\n if (!options.dryRun) {\n await mkdir(path.dirname(dest), { recursive: true });\n await copyFile(file, dest);\n }\n copied.push(dest);\n }\n\n return { copied, skipped };\n}\n\nfunction formatConflictMessage(conflicts: string[]): string {\n return [\n \"既存ファイルと衝突しました。安全のため停止します。\",\n \"\",\n \"衝突ファイル:\",\n ...conflicts.map((conflict) => `- ${conflict}`),\n \"\",\n \"上書きして続行する場合は --force を付けて再実行してください。\",\n ].join(\"\\n\");\n}\n\nasync function collectTemplateFiles(root: string): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const items = await readdir(root, { withFileTypes: true });\n for (const item of items) {\n const fullPath = path.join(root, item.name);\n if (item.isDirectory()) {\n const nested = await collectTemplateFiles(fullPath);\n entries.push(...nested);\n continue;\n }\n if (item.isFile()) {\n entries.push(fullPath);\n }\n }\n\n return entries;\n}\n\nasync function shouldWrite(target: string, force: boolean): Promise<boolean> {\n if (force) {\n return true;\n }\n return !(await exists(target));\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function getInitAssetsDir(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n const baseDir = path.dirname(basePath);\n // src/cli/lib と dist/cli/lib からの解決を想定する。\n const candidates = [\n path.resolve(baseDir, \"../../../assets/init\"),\n path.resolve(baseDir, \"../../assets/init\"),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n [\n \"init 用テンプレートが見つかりません。Template assets not found.\",\n \"確認したパス / Checked paths:\",\n ...candidates.map((candidate) => `- ${candidate}`),\n ].join(\"\\n\"),\n );\n}\n","export function info(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function warn(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function error(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { loadConfig, resolvePath } from \"../../core/config.js\";\nimport {\n createReportData,\n formatReportJson,\n formatReportMarkdown,\n} from \"../../core/report.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\nimport { error, info } from \"../lib/logger.js\";\n\nexport type ReportOptions = {\n root: string;\n format: \"md\" | \"json\";\n outPath?: string;\n};\n\nexport async function runReport(options: ReportOptions): Promise<void> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const input = configResult.config.output.validateJsonPath;\n const inputPath = path.isAbsolute(input) ? input : path.resolve(root, input);\n let validation: ValidationResult;\n try {\n validation = await readValidationResult(inputPath);\n } catch (err) {\n if (isMissingFileError(err)) {\n error(\n [\n `qfai report: 入力ファイルが見つかりません: ${inputPath}`,\n \"\",\n \"まず qfai validate を実行してください。例:\",\n \" qfai validate\",\n \"(デフォルトの出力先: .qfai/out/validate.json)\",\n \"\",\n \"GitHub Actions テンプレを使っている場合は、workflow の validate ジョブを先に実行してください。\",\n ].join(\"\\n\"),\n );\n process.exitCode = 2;\n return;\n }\n throw err;\n }\n\n const data = await createReportData(root, validation, configResult);\n const output =\n options.format === \"json\"\n ? formatReportJson(data)\n : formatReportMarkdown(data);\n\n const outRoot = resolvePath(root, configResult.config, \"outDir\");\n const defaultOut =\n options.format === \"json\"\n ? path.join(outRoot, \"report.json\")\n : path.join(outRoot, \"report.md\");\n const out = options.outPath ?? defaultOut;\n const outPath = path.isAbsolute(out) ? out : path.resolve(root, out);\n\n await mkdir(path.dirname(outPath), { recursive: true });\n await writeFile(outPath, `${output}\\n`, \"utf-8\");\n\n info(\n `report: info=${validation.counts.info} warning=${validation.counts.warning} error=${validation.counts.error}`,\n );\n info(`wrote report: ${outPath}`);\n}\n\nasync function readValidationResult(\n inputPath: string,\n): Promise<ValidationResult> {\n const raw = await readFile(inputPath, \"utf-8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!isValidationResult(parsed)) {\n throw new Error(`validate.json の形式が不正です: ${inputPath}`);\n }\n return parsed;\n}\n\nfunction isValidationResult(value: unknown): value is ValidationResult {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.toolVersion !== \"string\") {\n return false;\n }\n if (!Array.isArray(record.issues)) {\n return false;\n }\n const counts = record.counts as Record<string, unknown> | undefined;\n if (!counts) {\n return false;\n }\n return (\n typeof counts.info === \"number\" &&\n typeof counts.warning === \"number\" &&\n typeof counts.error === \"number\"\n );\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n const record = error as { code?: string };\n return record.code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { Issue } from \"./types.js\";\n\nexport type FailOn = \"never\" | \"warning\" | \"error\";\nexport type OutputFormat = \"text\" | \"github\";\nexport type TraceabilitySeverity = \"warning\" | \"error\";\n\nexport type QfaiPaths = {\n contractsDir: string;\n specsDir: string;\n rulesDir: string;\n outDir: string;\n promptsDir: string;\n srcDir: string;\n testsDir: string;\n};\n\nexport type QfaiValidationConfig = {\n failOn: FailOn;\n require: {\n specSections: string[];\n };\n traceability: {\n brMustHaveSc: boolean;\n scMustHaveTest: boolean;\n testFileGlobs: string[];\n testFileExcludeGlobs: string[];\n scNoTestSeverity: TraceabilitySeverity;\n allowOrphanContracts: boolean;\n unknownContractIdSeverity: TraceabilitySeverity;\n };\n};\n\nexport type QfaiOutputConfig = {\n validateJsonPath: string;\n};\n\nexport type QfaiConfig = {\n paths: QfaiPaths;\n validation: QfaiValidationConfig;\n output: QfaiOutputConfig;\n};\n\nexport type ConfigPathKey = keyof QfaiPaths;\n\nexport type ConfigLoadResult = {\n config: QfaiConfig;\n issues: Issue[];\n configPath: string;\n};\n\nexport const defaultConfig: QfaiConfig = {\n paths: {\n contractsDir: \".qfai/contracts\",\n specsDir: \".qfai/specs\",\n rulesDir: \".qfai/rules\",\n outDir: \".qfai/out\",\n promptsDir: \".qfai/prompts\",\n srcDir: \"src\",\n testsDir: \"tests\",\n },\n validation: {\n failOn: \"error\",\n require: {\n specSections: [\n \"背景\",\n \"スコープ\",\n \"非ゴール\",\n \"用語\",\n \"前提\",\n \"決定事項\",\n \"業務ルール\",\n ],\n },\n traceability: {\n brMustHaveSc: true,\n scMustHaveTest: true,\n testFileGlobs: [],\n testFileExcludeGlobs: [],\n scNoTestSeverity: \"error\",\n allowOrphanContracts: false,\n unknownContractIdSeverity: \"error\",\n },\n },\n output: {\n validateJsonPath: \".qfai/out/validate.json\",\n },\n};\n\nexport function getConfigPath(root: string): string {\n return path.join(root, \"qfai.config.yaml\");\n}\n\nexport async function loadConfig(root: string): Promise<ConfigLoadResult> {\n const configPath = getConfigPath(root);\n const issues: Issue[] = [];\n\n let parsed: unknown;\n try {\n const raw = await readFile(configPath, \"utf-8\");\n parsed = parseYaml(raw);\n } catch (error) {\n if (isMissingFile(error)) {\n return { config: defaultConfig, issues, configPath };\n }\n issues.push(configIssue(configPath, formatError(error)));\n return { config: defaultConfig, issues, configPath };\n }\n\n const normalized = normalizeConfig(parsed, configPath, issues);\n return { config: normalized, issues, configPath };\n}\n\nexport function resolvePath(\n root: string,\n config: QfaiConfig,\n key: ConfigPathKey,\n): string {\n return path.resolve(root, config.paths[key]);\n}\n\nfunction normalizeConfig(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiConfig {\n if (!isRecord(raw)) {\n issues.push(configIssue(configPath, \"設定ファイルの形式が不正です。\"));\n return defaultConfig;\n }\n\n return {\n paths: normalizePaths(raw.paths, configPath, issues),\n validation: normalizeValidation(raw.validation, configPath, issues),\n output: normalizeOutput(raw.output, configPath, issues),\n };\n}\n\nfunction normalizePaths(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiPaths {\n const base = defaultConfig.paths;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"paths はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n contractsDir: readString(\n raw.contractsDir,\n base.contractsDir,\n \"paths.contractsDir\",\n configPath,\n issues,\n ),\n specsDir: readString(\n raw.specsDir,\n base.specsDir,\n \"paths.specsDir\",\n configPath,\n issues,\n ),\n rulesDir: readString(\n raw.rulesDir,\n base.rulesDir,\n \"paths.rulesDir\",\n configPath,\n issues,\n ),\n outDir: readString(\n raw.outDir,\n base.outDir,\n \"paths.outDir\",\n configPath,\n issues,\n ),\n promptsDir: readString(\n raw.promptsDir,\n base.promptsDir,\n \"paths.promptsDir\",\n configPath,\n issues,\n ),\n srcDir: readString(\n raw.srcDir,\n base.srcDir,\n \"paths.srcDir\",\n configPath,\n issues,\n ),\n testsDir: readString(\n raw.testsDir,\n base.testsDir,\n \"paths.testsDir\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction normalizeValidation(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiValidationConfig {\n const base = defaultConfig.validation;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(\n configPath,\n \"validation はオブジェクトである必要があります。\",\n ),\n );\n return base;\n }\n\n let requireRaw: Record<string, unknown> | undefined;\n if (raw.require === undefined) {\n requireRaw = undefined;\n } else if (isRecord(raw.require)) {\n requireRaw = raw.require;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.require はオブジェクトである必要があります。\",\n ),\n );\n requireRaw = undefined;\n }\n\n let traceabilityRaw: Record<string, unknown> | undefined;\n if (raw.traceability === undefined) {\n traceabilityRaw = undefined;\n } else if (isRecord(raw.traceability)) {\n traceabilityRaw = raw.traceability;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.traceability はオブジェクトである必要があります。\",\n ),\n );\n traceabilityRaw = undefined;\n }\n\n return {\n failOn: readFailOn(\n raw.failOn,\n base.failOn,\n \"validation.failOn\",\n configPath,\n issues,\n ),\n require: {\n specSections: readStringArray(\n requireRaw?.specSections,\n base.require.specSections,\n \"validation.require.specSections\",\n configPath,\n issues,\n ),\n },\n traceability: {\n brMustHaveSc: readBoolean(\n traceabilityRaw?.brMustHaveSc,\n base.traceability.brMustHaveSc,\n \"validation.traceability.brMustHaveSc\",\n configPath,\n issues,\n ),\n scMustHaveTest: readBoolean(\n traceabilityRaw?.scMustHaveTest,\n base.traceability.scMustHaveTest,\n \"validation.traceability.scMustHaveTest\",\n configPath,\n issues,\n ),\n testFileGlobs: readStringArray(\n traceabilityRaw?.testFileGlobs,\n base.traceability.testFileGlobs,\n \"validation.traceability.testFileGlobs\",\n configPath,\n issues,\n ),\n testFileExcludeGlobs: readStringArray(\n traceabilityRaw?.testFileExcludeGlobs,\n base.traceability.testFileExcludeGlobs,\n \"validation.traceability.testFileExcludeGlobs\",\n configPath,\n issues,\n ),\n scNoTestSeverity: readTraceabilitySeverity(\n traceabilityRaw?.scNoTestSeverity,\n base.traceability.scNoTestSeverity,\n \"validation.traceability.scNoTestSeverity\",\n configPath,\n issues,\n ),\n allowOrphanContracts: readBoolean(\n traceabilityRaw?.allowOrphanContracts,\n base.traceability.allowOrphanContracts,\n \"validation.traceability.allowOrphanContracts\",\n configPath,\n issues,\n ),\n unknownContractIdSeverity: readTraceabilitySeverity(\n traceabilityRaw?.unknownContractIdSeverity,\n base.traceability.unknownContractIdSeverity,\n \"validation.traceability.unknownContractIdSeverity\",\n configPath,\n issues,\n ),\n },\n };\n}\n\nfunction normalizeOutput(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiOutputConfig {\n const base = defaultConfig.output;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"output はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n validateJsonPath: readString(\n raw.validateJsonPath,\n base.validateJsonPath,\n \"output.validateJsonPath\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction readString(\n value: unknown,\n fallback: string,\n label: string,\n configPath: string,\n issues: Issue[],\n): string {\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readStringArray(\n value: unknown,\n fallback: string[],\n label: string,\n configPath: string,\n issues: Issue[],\n): string[] {\n if (Array.isArray(value) && value.every((item) => typeof item === \"string\")) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列配列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readBoolean(\n value: unknown,\n fallback: boolean,\n label: string,\n configPath: string,\n issues: Issue[],\n): boolean {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は真偽値である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readFailOn(\n value: unknown,\n fallback: FailOn,\n label: string,\n configPath: string,\n issues: Issue[],\n): FailOn {\n if (value === \"never\" || value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は never|warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction readTraceabilitySeverity(\n value: unknown,\n fallback: TraceabilitySeverity,\n label: string,\n configPath: string,\n issues: Issue[],\n): TraceabilitySeverity {\n if (value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction configIssue(file: string, message: string): Issue {\n return {\n code: \"QFAI_CONFIG_INVALID\",\n severity: \"error\",\n message,\n file,\n rule: \"config.invalid\",\n };\n}\n\nfunction isMissingFile(error: unknown): boolean {\n if (error && typeof error === \"object\" && \"code\" in error) {\n return (error as { code?: string }).code === \"ENOENT\";\n }\n return false;\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildContractIndex } from \"./contractIndex.js\";\nimport { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport {\n collectContractFiles,\n collectScenarioFiles,\n collectSpecFiles,\n} from \"./discovery.js\";\nimport { collectFiles } from \"./fs.js\";\nimport { extractAllIds, extractIds, type IdPrefix } from \"./ids.js\";\nimport { parseSpec } from \"./parse/spec.js\";\nimport {\n buildScCoverage,\n collectScIdsFromScenarioFiles,\n collectScIdSourcesFromScenarioFiles,\n collectScTestReferences,\n type ScCoverage,\n type TestFileScan,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { validateProject } from \"./validate.js\";\nimport { resolveToolVersion } from \"./version.js\";\n\nexport type ReportSummary = {\n specs: number;\n scenarios: number;\n contracts: {\n api: number;\n ui: number;\n db: number;\n };\n counts: ValidationCounts;\n};\n\nexport type ReportIds = {\n spec: string[];\n br: string[];\n sc: string[];\n ui: string[];\n api: string[];\n db: string[];\n};\n\nexport type ReportContractCoverage = {\n total: number;\n referenced: number;\n orphan: number;\n idToSpecs: Record<string, string[]>;\n};\n\nexport type ReportSpecCoverage = {\n contractRefMissing: number;\n specToContractIds: Record<string, string[]>;\n};\n\nexport type ReportTraceability = {\n upstreamIdsFound: number;\n referencedInCodeOrTests: boolean;\n sc: ScCoverage;\n scSources: Record<string, string[]>;\n testFiles: TestFileScan;\n contracts: ReportContractCoverage;\n specs: ReportSpecCoverage;\n};\n\nexport type ReportData = {\n tool: \"qfai\";\n version: string;\n generatedAt: string;\n root: string;\n configPath: string;\n summary: ReportSummary;\n ids: ReportIds;\n traceability: ReportTraceability;\n issues: Issue[];\n};\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DB\"];\n\nexport async function createReportData(\n root: string,\n validation?: ValidationResult,\n configResult?: ConfigLoadResult,\n): Promise<ReportData> {\n const resolved = configResult ?? (await loadConfig(root));\n const config = resolved.config;\n const configPath = resolved.configPath;\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const dbRoot = path.join(contractsRoot, \"db\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const {\n api: apiFiles,\n ui: uiFiles,\n db: dbFiles,\n } = await collectContractFiles(uiRoot, apiRoot, dbRoot);\n const contractIndex = await buildContractIndex(root, config);\n const specContractRefs = await collectSpecContractRefs(specFiles);\n const contractIdList = Array.from(contractIndex.ids);\n const referencedContracts = new Set<string>();\n for (const ids of specContractRefs.specToContractIds.values()) {\n ids.forEach((id) => referencedContracts.add(id));\n }\n const referencedContractCount = contractIdList.filter((id) =>\n referencedContracts.has(id),\n ).length;\n const orphanContractCount = contractIdList.filter(\n (id) => !referencedContracts.has(id),\n ).length;\n const contractIdToSpecsRecord = mapToSortedRecord(specContractRefs.idToSpecs);\n const specToContractIdsRecord = mapToSortedRecord(\n specContractRefs.specToContractIds,\n );\n\n const idsByPrefix = await collectIds([\n ...specFiles,\n ...scenarioFiles,\n ...apiFiles,\n ...uiFiles,\n ...dbFiles,\n ]);\n\n const upstreamIds = await collectUpstreamIds([\n ...specFiles,\n ...scenarioFiles,\n ]);\n const traceability = await evaluateTraceability(\n upstreamIds,\n srcRoot,\n testsRoot,\n );\n const scIds = await collectScIdsFromScenarioFiles(scenarioFiles);\n const scRefsResult = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scCoverage =\n validation?.traceability?.sc ?? buildScCoverage(scIds, scRefsResult.refs);\n const testFiles = validation?.traceability?.testFiles ?? scRefsResult.scan;\n const scSources = await collectScIdSourcesFromScenarioFiles(scenarioFiles);\n const scSourceRecord = mapToSortedRecord(scSources);\n\n const resolvedValidation =\n validation ?? (await validateProject(root, resolved));\n const version = await resolveToolVersion();\n\n return {\n tool: \"qfai\",\n version,\n generatedAt: new Date().toISOString(),\n root,\n configPath,\n summary: {\n specs: specFiles.length,\n scenarios: scenarioFiles.length,\n contracts: {\n api: apiFiles.length,\n ui: uiFiles.length,\n db: dbFiles.length,\n },\n counts: resolvedValidation.counts,\n },\n ids: {\n spec: idsByPrefix.SPEC,\n br: idsByPrefix.BR,\n sc: idsByPrefix.SC,\n ui: idsByPrefix.UI,\n api: idsByPrefix.API,\n db: idsByPrefix.DB,\n },\n traceability: {\n upstreamIdsFound: upstreamIds.size,\n referencedInCodeOrTests: traceability,\n sc: scCoverage,\n scSources: scSourceRecord,\n testFiles,\n contracts: {\n total: contractIdList.length,\n referenced: referencedContractCount,\n orphan: orphanContractCount,\n idToSpecs: contractIdToSpecsRecord,\n },\n specs: {\n contractRefMissing: specContractRefs.missingRefSpecs.size,\n specToContractIds: specToContractIdsRecord,\n },\n },\n issues: resolvedValidation.issues,\n };\n}\n\nexport function formatReportMarkdown(data: ReportData): string {\n const lines: string[] = [];\n\n lines.push(\"# QFAI Report\");\n lines.push(`- 生成日時: ${data.generatedAt}`);\n lines.push(`- ルート: ${data.root}`);\n lines.push(`- 設定: ${data.configPath}`);\n lines.push(`- 版: ${data.version}`);\n lines.push(\"\");\n\n lines.push(\"## 概要\");\n lines.push(`- specs: ${data.summary.specs}`);\n lines.push(`- scenarios: ${data.summary.scenarios}`);\n lines.push(\n `- contracts: api ${data.summary.contracts.api} / ui ${data.summary.contracts.ui} / db ${data.summary.contracts.db}`,\n );\n lines.push(\n `- issues: info ${data.summary.counts.info} / warning ${data.summary.counts.warning} / error ${data.summary.counts.error}`,\n );\n lines.push(\"\");\n\n lines.push(\"## ID集計\");\n lines.push(formatIdLine(\"SPEC\", data.ids.spec));\n lines.push(formatIdLine(\"BR\", data.ids.br));\n lines.push(formatIdLine(\"SC\", data.ids.sc));\n lines.push(formatIdLine(\"UI\", data.ids.ui));\n lines.push(formatIdLine(\"API\", data.ids.api));\n lines.push(formatIdLine(\"DB\", data.ids.db));\n lines.push(\"\");\n\n lines.push(\"## トレーサビリティ\");\n lines.push(`- 上流ID検出数: ${data.traceability.upstreamIdsFound}`);\n lines.push(\n `- コード/テスト参照: ${data.traceability.referencedInCodeOrTests ? \"あり\" : \"なし\"}`,\n );\n lines.push(\"\");\n\n lines.push(\"## 契約カバレッジ\");\n lines.push(`- total: ${data.traceability.contracts.total}`);\n lines.push(`- referenced: ${data.traceability.contracts.referenced}`);\n lines.push(`- orphan: ${data.traceability.contracts.orphan}`);\n lines.push(\n `- specContractRefMissing: ${data.traceability.specs.contractRefMissing}`,\n );\n lines.push(\"\");\n\n lines.push(\"## 契約→Spec\");\n const contractToSpecs = data.traceability.contracts.idToSpecs;\n const contractIds = Object.keys(contractToSpecs).sort((a, b) =>\n a.localeCompare(b),\n );\n if (contractIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const contractId of contractIds) {\n const specs = contractToSpecs[contractId] ?? [];\n if (specs.length === 0) {\n lines.push(`- ${contractId}: (none)`);\n } else {\n lines.push(`- ${contractId}: ${specs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Spec→契約\");\n const specToContracts = data.traceability.specs.specToContractIds;\n const specIds = Object.keys(specToContracts).sort((a, b) =>\n a.localeCompare(b),\n );\n if (specIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const specId of specIds) {\n const contractIds = specToContracts[specId] ?? [];\n if (contractIds.length === 0) {\n lines.push(`- ${specId}: (none)`);\n } else {\n lines.push(`- ${specId}: ${contractIds.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"## SCカバレッジ\");\n lines.push(`- total: ${data.traceability.sc.total}`);\n lines.push(`- covered: ${data.traceability.sc.covered}`);\n lines.push(`- missing: ${data.traceability.sc.missing}`);\n lines.push(\n `- testFileGlobs: ${formatList(data.traceability.testFiles.globs)}`,\n );\n lines.push(\n `- testFileExcludeGlobs: ${formatList(\n data.traceability.testFiles.excludeGlobs,\n )}`,\n );\n lines.push(\n `- testFileCount: ${data.traceability.testFiles.matchedFileCount}`,\n );\n if (data.traceability.sc.missingIds.length === 0) {\n lines.push(\"- missingIds: (none)\");\n } else {\n const sources = data.traceability.scSources;\n const missingWithSources = data.traceability.sc.missingIds.map((id) => {\n const files = sources[id] ?? [];\n if (files.length === 0) {\n return id;\n }\n return `${id} (${files.join(\", \")})`;\n });\n lines.push(`- missingIds: ${missingWithSources.join(\", \")}`);\n }\n lines.push(\"\");\n\n lines.push(\"## SC→参照テスト\");\n const scRefs = data.traceability.sc.refs;\n const scIds = Object.keys(scRefs).sort((a, b) => a.localeCompare(b));\n if (scIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const scId of scIds) {\n const refs = scRefs[scId] ?? [];\n if (refs.length === 0) {\n lines.push(`- ${scId}: (none)`);\n } else {\n lines.push(`- ${scId}: ${refs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Spec:SC=1:1 違反\");\n const specScIssues = data.issues.filter(\n (item) => item.code === \"QFAI-TRACE-012\",\n );\n if (specScIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of specScIssues) {\n const location = item.file ?? \"(unknown)\";\n const refs =\n item.refs && item.refs.length > 0 ? item.refs.join(\", \") : item.message;\n lines.push(`- ${location}: ${refs}`);\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Hotspots\");\n const hotspots = buildHotspots(data.issues);\n if (hotspots.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const spot of hotspots) {\n lines.push(\n `- ${spot.file}: total ${spot.total} (error ${spot.error} / warning ${spot.warning} / info ${spot.info})`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## トレーサビリティ(検証)\");\n const traceIssues = data.issues.filter(\n (item) =>\n item.rule?.startsWith(\"traceability.\") ||\n item.code.startsWith(\"QFAI_TRACE\") ||\n item.code.startsWith(\"QFAI-TRACE-\"),\n );\n if (traceIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of traceIssues) {\n const location = item.file ? ` (${item.file})` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## 検証結果\");\n if (data.issues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of data.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}${refs}`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatReportJson(data: ReportData): string {\n return JSON.stringify(data, null, 2);\n}\n\ntype SpecContractRefsResult = {\n specToContractIds: Map<string, Set<string>>;\n idToSpecs: Map<string, Set<string>>;\n missingRefSpecs: Set<string>;\n};\n\nasync function collectSpecContractRefs(\n specFiles: string[],\n): Promise<SpecContractRefsResult> {\n const specToContractIds = new Map<string, Set<string>>();\n const idToSpecs = new Map<string, Set<string>>();\n const missingRefSpecs = new Set<string>();\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n const specKey = parsed.specId ?? file;\n const refs = parsed.contractRefs;\n\n if (refs.lines.length === 0) {\n missingRefSpecs.add(specKey);\n }\n\n const currentContracts =\n specToContractIds.get(specKey) ?? new Set<string>();\n for (const id of refs.ids) {\n currentContracts.add(id);\n const specs = idToSpecs.get(id) ?? new Set<string>();\n specs.add(specKey);\n idToSpecs.set(id, specs);\n }\n specToContractIds.set(specKey, currentContracts);\n }\n\n return {\n specToContractIds,\n idToSpecs,\n missingRefSpecs,\n };\n}\n\nasync function collectIds(\n files: string[],\n): Promise<Record<IdPrefix, string[]>> {\n const result: Record<IdPrefix, Set<string>> = {\n SPEC: new Set(),\n BR: new Set(),\n SC: new Set(),\n UI: new Set(),\n API: new Set(),\n DB: new Set(),\n };\n\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n for (const prefix of ID_PREFIXES) {\n const ids = extractIds(text, prefix);\n ids.forEach((id) => result[prefix].add(id));\n }\n }\n\n return {\n SPEC: toSortedArray(result.SPEC),\n BR: toSortedArray(result.BR),\n SC: toSortedArray(result.SC),\n UI: toSortedArray(result.UI),\n API: toSortedArray(result.API),\n DB: toSortedArray(result.DB),\n };\n}\n\nasync function collectUpstreamIds(files: string[]): Promise<Set<string>> {\n const ids = new Set<string>();\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => ids.add(id));\n }\n return ids;\n}\n\nasync function evaluateTraceability(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<boolean> {\n if (upstreamIds.size === 0) {\n return false;\n }\n\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n return false;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction formatIdLine(label: string, values: string[]): string {\n if (values.length === 0) {\n return `- ${label}: (none)`;\n }\n return `- ${label}: ${values.join(\", \")}`;\n}\n\nfunction formatList(values: string[]): string {\n if (values.length === 0) {\n return \"(none)\";\n }\n return values.join(\", \");\n}\n\nfunction toSortedArray(values: Set<string>): string[] {\n return Array.from(values).sort((a, b) => a.localeCompare(b));\n}\n\nfunction mapToSortedRecord(\n values: Map<string, Set<string>>,\n): Record<string, string[]> {\n const record: Record<string, string[]> = {};\n for (const [key, files] of values.entries()) {\n record[key] = Array.from(files).sort((a, b) => a.localeCompare(b));\n }\n return record;\n}\n\ntype Hotspot = {\n file: string;\n total: number;\n error: number;\n warning: number;\n info: number;\n};\n\nfunction buildHotspots(issues: Issue[]): Hotspot[] {\n const map = new Map<string, Hotspot>();\n for (const issue of issues) {\n if (!issue.file) {\n continue;\n }\n const current =\n map.get(issue.file) ??\n ({\n file: issue.file,\n total: 0,\n error: 0,\n warning: 0,\n info: 0,\n } satisfies Hotspot);\n current.total += 1;\n current[issue.severity] += 1;\n map.set(issue.file, current);\n }\n\n return Array.from(map.values()).sort((a, b) =>\n b.total !== a.total ? b.total - a.total : a.file.localeCompare(b.file),\n );\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"./config.js\";\nimport { resolvePath } from \"./config.js\";\nimport {\n collectApiContractFiles,\n collectDataContractFiles,\n collectUiContractFiles,\n} from \"./discovery.js\";\nimport { extractDeclaredContractIds } from \"./contractsDecl.js\";\n\nexport type ContractIndex = {\n ids: Set<string>;\n idToFiles: Map<string, Set<string>>;\n files: { ui: string[]; api: string[]; db: string[] };\n};\n\nexport async function buildContractIndex(\n root: string,\n config: QfaiConfig,\n): Promise<ContractIndex> {\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const dbRoot = path.join(contractsRoot, \"db\");\n\n const [uiFiles, apiFiles, dbFiles] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDataContractFiles(dbRoot),\n ]);\n\n const index: ContractIndex = {\n ids: new Set<string>(),\n idToFiles: new Map<string, Set<string>>(),\n files: { ui: uiFiles, api: apiFiles, db: dbFiles },\n };\n\n await indexContractFiles(uiFiles, index);\n await indexContractFiles(apiFiles, index);\n await indexContractFiles(dbFiles, index);\n\n return index;\n}\n\nasync function indexContractFiles(\n files: string[],\n index: ContractIndex,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractDeclaredContractIds(text).forEach((id) => record(index, id, file));\n }\n}\n\nfunction record(index: ContractIndex, id: string, file: string): void {\n index.ids.add(id);\n const current = index.idToFiles.get(id) ?? new Set<string>();\n current.add(file);\n index.idToFiles.set(id, current);\n}\n","import { access } from \"node:fs/promises\";\n\nimport { collectFiles } from \"./fs.js\";\nimport { collectSpecEntries } from \"./specLayout.js\";\n\nexport type ContractFiles = {\n api: string[];\n ui: string[];\n db: string[];\n};\n\nexport async function collectSpecPackDirs(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return entries.map((entry) => entry.dir);\n}\n\nexport async function collectSpecFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.specPath));\n}\n\nexport async function collectDeltaFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.deltaPath));\n}\n\nexport async function collectScenarioFiles(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.scenarioPath));\n}\n\nexport async function collectUiContractFiles(\n uiRoot: string,\n): Promise<string[]> {\n return collectFiles(uiRoot, { extensions: [\".yaml\", \".yml\"] });\n}\n\nexport async function collectApiContractFiles(\n apiRoot: string,\n): Promise<string[]> {\n return collectFiles(apiRoot, { extensions: [\".yaml\", \".yml\", \".json\"] });\n}\n\nexport async function collectDataContractFiles(\n dataRoot: string,\n): Promise<string[]> {\n return collectFiles(dataRoot, { extensions: [\".sql\"] });\n}\n\nexport async function collectContractFiles(\n uiRoot: string,\n apiRoot: string,\n dataRoot: string,\n): Promise<ContractFiles> {\n const [ui, api, db] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDataContractFiles(dataRoot),\n ]);\n return { ui, api, db };\n}\n\nasync function filterExisting(files: string[]): Promise<string[]> {\n const existing: string[] = [];\n for (const file of files) {\n if (await exists(file)) {\n existing.push(file);\n }\n }\n return existing;\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { access, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport fg from \"fast-glob\";\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \".pnpm\",\n \"tmp\",\n \".mcp-tools\",\n]);\n\nexport type CollectFilesOptions = {\n extensions?: string[];\n ignoreDirs?: string[];\n};\n\nexport type CollectFilesByGlobOptions = {\n globs: string[];\n ignore?: string[];\n};\n\nexport async function collectFiles(\n root: string,\n options: CollectFilesOptions = {},\n): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const ignoreDirs = new Set([\n ...DEFAULT_IGNORE_DIRS,\n ...(options.ignoreDirs ?? []),\n ]);\n const extensions = options.extensions?.map((ext) => ext.toLowerCase()) ?? [];\n\n await walk(root, root, ignoreDirs, extensions, entries);\n return entries;\n}\n\nexport async function collectFilesByGlobs(\n root: string,\n options: CollectFilesByGlobOptions,\n): Promise<string[]> {\n if (options.globs.length === 0) {\n return [];\n }\n return fg(options.globs, {\n cwd: root,\n ignore: options.ignore ?? [],\n onlyFiles: true,\n absolute: true,\n unique: true,\n });\n}\n\nasync function walk(\n base: string,\n current: string,\n ignoreDirs: Set<string>,\n extensions: string[],\n out: string[],\n): Promise<void> {\n const items = await readdir(current, { withFileTypes: true });\n\n for (const item of items) {\n const fullPath = path.join(current, item.name);\n\n if (item.isDirectory()) {\n if (ignoreDirs.has(item.name)) {\n continue;\n }\n await walk(base, fullPath, ignoreDirs, extensions, out);\n continue;\n }\n\n if (item.isFile()) {\n if (extensions.length > 0) {\n const ext = path.extname(item.name).toLowerCase();\n if (!extensions.includes(ext)) {\n continue;\n }\n }\n out.push(fullPath);\n }\n }\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst SPEC_DIR_RE = /^spec-\\d{4}$/;\n\nexport type SpecEntry = {\n dir: string;\n specPath: string;\n deltaPath: string;\n scenarioPath: string;\n};\n\nexport async function collectSpecEntries(\n specsRoot: string,\n): Promise<SpecEntry[]> {\n const dirs = await listSpecDirs(specsRoot);\n const entries = dirs.map((dir) => ({\n dir,\n specPath: path.join(dir, \"spec.md\"),\n deltaPath: path.join(dir, \"delta.md\"),\n scenarioPath: path.join(dir, \"scenario.md\"),\n }));\n return entries.sort((a, b) => a.dir.localeCompare(b.dir));\n}\n\nasync function listSpecDirs(specsRoot: string): Promise<string[]> {\n try {\n const items = await readdir(specsRoot, { withFileTypes: true });\n return items\n .filter((item) => item.isDirectory())\n .map((item) => item.name)\n .filter((name) => SPEC_DIR_RE.test(name.toLowerCase()))\n .map((name) => path.join(specsRoot, name));\n } catch (error) {\n if (isMissingFileError(error)) {\n return [];\n }\n throw error;\n }\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","const CONTRACT_DECLARATION_RE =\n /^\\s*(?:#|\\/\\/|--|\\/\\*+|\\*+)?\\s*QFAI-CONTRACT-ID:\\s*((?:API|UI|DB)-\\d{4})\\s*(?:\\*\\/)?\\s*$/gm;\nconst CONTRACT_DECLARATION_LINE_RE =\n /^\\s*(?:#|\\/\\/|--|\\/\\*+|\\*+)?\\s*QFAI-CONTRACT-ID:\\s*(?:API|UI|DB)-\\d{4}\\s*(?:\\*\\/)?\\s*$/;\n\nexport function extractDeclaredContractIds(text: string): string[] {\n const ids: string[] = [];\n for (const match of text.matchAll(CONTRACT_DECLARATION_RE)) {\n const id = match[1];\n if (id) {\n ids.push(id);\n }\n }\n return ids;\n}\n\nexport function stripContractDeclarationLines(text: string): string {\n return text\n .split(/\\r?\\n/)\n .filter((line) => !CONTRACT_DECLARATION_LINE_RE.test(line))\n .join(\"\\n\");\n}\n","export type IdPrefix = \"SPEC\" | \"BR\" | \"SC\" | \"UI\" | \"API\" | \"DB\";\nexport type IdFormatPrefix = IdPrefix | \"ADR\";\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DB\"];\n\nconst STRICT_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-\\d{4}\\b/g,\n BR: /\\bBR-\\d{4}\\b/g,\n SC: /\\bSC-\\d{4}\\b/g,\n UI: /\\bUI-\\d{4}\\b/g,\n API: /\\bAPI-\\d{4}\\b/g,\n DB: /\\bDB-\\d{4}\\b/g,\n ADR: /\\bADR-\\d{4}\\b/g,\n};\n\nconst LOOSE_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-[A-Za-z0-9_-]+\\b/gi,\n BR: /\\bBR-[A-Za-z0-9_-]+\\b/gi,\n SC: /\\bSC-[A-Za-z0-9_-]+\\b/gi,\n UI: /\\bUI-[A-Za-z0-9_-]+\\b/gi,\n API: /\\bAPI-[A-Za-z0-9_-]+\\b/gi,\n DB: /\\bDB-[A-Za-z0-9_-]+\\b/gi,\n ADR: /\\bADR-[A-Za-z0-9_-]+\\b/gi,\n};\n\nexport function extractIds(text: string, prefix: IdPrefix): string[] {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const matches = text.match(pattern);\n return unique(matches ?? []);\n}\n\nexport function extractAllIds(text: string): string[] {\n const all: string[] = [];\n ID_PREFIXES.forEach((prefix) => {\n all.push(...extractIds(text, prefix));\n });\n return unique(all);\n}\n\nexport function extractInvalidIds(\n text: string,\n prefixes: IdFormatPrefix[],\n): string[] {\n const invalid: string[] = [];\n for (const prefix of prefixes) {\n const candidates = text.match(LOOSE_ID_PATTERNS[prefix]) ?? [];\n for (const candidate of candidates) {\n if (!isValidId(candidate, prefix)) {\n invalid.push(candidate);\n }\n }\n }\n return unique(invalid);\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction isValidId(value: string, prefix: IdFormatPrefix): boolean {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const strict = new RegExp(pattern.source);\n return strict.test(value);\n}\n","export type Heading = { level: number; title: string; line: number };\n\nexport type H2Section = {\n title: string;\n startLine: number;\n endLine: number;\n body: string;\n};\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\nexport function parseHeadings(md: string): Heading[] {\n const lines = md.split(/\\r?\\n/);\n const headings: Heading[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const match = line.match(HEADING_RE);\n if (!match) continue;\n const levelToken = match[1];\n const title = match[2];\n if (!levelToken || !title) continue;\n headings.push({\n level: levelToken.length,\n title: title.trim(),\n line: i + 1,\n });\n }\n return headings;\n}\n\nexport function extractH2Sections(md: string): Map<string, H2Section> {\n const lines = md.split(/\\r?\\n/);\n const headings = parseHeadings(md).filter((heading) => heading.level === 2);\n const sections = new Map<string, H2Section>();\n\n for (let i = 0; i < headings.length; i++) {\n const current = headings[i];\n if (!current) continue;\n const next = headings[i + 1];\n const startLine = current.line + 1;\n const endLine = (next?.line ?? lines.length + 1) - 1;\n const body =\n startLine <= endLine\n ? lines.slice(startLine - 1, endLine).join(\"\\n\")\n : \"\";\n\n sections.set(current.title.trim(), {\n title: current.title.trim(),\n startLine,\n endLine,\n body,\n });\n }\n\n return sections;\n}\n","import { extractH2Sections, parseHeadings } from \"./markdown.js\";\n\nexport type BrPriority = \"P0\" | \"P1\" | \"P2\" | \"P3\";\n\nexport type ParsedBr = {\n id: string;\n priority: BrPriority;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithoutPriority = {\n id: string;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithInvalidPriority = {\n id: string;\n priority: string;\n text: string;\n line: number;\n};\n\nexport type ParsedSpec = {\n file: string;\n specId?: string;\n sections: Set<string>;\n brs: ParsedBr[];\n brsWithoutPriority: ParsedBrWithoutPriority[];\n brsWithInvalidPriority: ParsedBrWithInvalidPriority[];\n contractRefs: ParsedContractRefs;\n};\n\nexport type ParsedContractRefs = {\n lines: string[];\n ids: string[];\n invalidTokens: string[];\n hasNone: boolean;\n};\n\nconst SPEC_ID_RE = /\\bSPEC-\\d{4}\\b/;\nconst BR_LINE_RE = /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[0-3])\\]\\s*(.+)$/;\nconst BR_LINE_ANY_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[^\\]]+)\\]\\s*(.+)$/;\nconst BR_LINE_NO_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\](?!\\s*\\[P)\\s*(.*\\S.*)$/;\nconst CONTRACT_REF_LINE_RE =\n /^[ \\t]*QFAI-CONTRACT-REF:[ \\t]*([^\\r\\n]*)[ \\t]*$/gm;\nconst CONTRACT_REF_ID_RE = /^(?:API|UI|DB)-\\d{4}$/;\n\nconst BR_SECTION_TITLE = \"業務ルール\";\nconst VALID_PRIORITIES = new Set<BrPriority>([\"P0\", \"P1\", \"P2\", \"P3\"]);\n\nexport function parseSpec(md: string, file: string): ParsedSpec {\n const headings = parseHeadings(md);\n const h1 = headings.find((heading) => heading.level === 1);\n const specId = h1?.title.match(SPEC_ID_RE)?.[0];\n\n const sections = extractH2Sections(md);\n const sectionNames = new Set(Array.from(sections.keys()));\n const brSection = sections.get(BR_SECTION_TITLE);\n const brLines = brSection ? brSection.body.split(/\\r?\\n/) : [];\n const startLine = brSection?.startLine ?? 1;\n\n const brs: ParsedBr[] = [];\n const brsWithoutPriority: ParsedBrWithoutPriority[] = [];\n const brsWithInvalidPriority: ParsedBrWithInvalidPriority[] = [];\n\n for (let i = 0; i < brLines.length; i++) {\n const lineText = brLines[i] ?? \"\";\n const lineNumber = startLine + i;\n\n const validMatch = lineText.match(BR_LINE_RE);\n if (validMatch) {\n const id = validMatch[1];\n const priority = validMatch[2];\n const text = validMatch[3];\n if (!id || !priority || !text) continue;\n brs.push({\n id,\n priority: priority as BrPriority,\n text: text.trim(),\n line: lineNumber,\n });\n continue;\n }\n\n const anyPriorityMatch = lineText.match(BR_LINE_ANY_PRIORITY_RE);\n if (anyPriorityMatch) {\n const id = anyPriorityMatch[1];\n const priority = anyPriorityMatch[2];\n const text = anyPriorityMatch[3];\n if (!id || !priority || !text) continue;\n if (!VALID_PRIORITIES.has(priority as BrPriority)) {\n brsWithInvalidPriority.push({\n id,\n priority,\n text: text.trim(),\n line: lineNumber,\n });\n }\n continue;\n }\n\n const noPriorityMatch = lineText.match(BR_LINE_NO_PRIORITY_RE);\n if (noPriorityMatch) {\n const id = noPriorityMatch[1];\n const text = noPriorityMatch[2];\n if (!id || !text) continue;\n brsWithoutPriority.push({\n id,\n text: text.trim(),\n line: lineNumber,\n });\n }\n }\n\n const parsed: ParsedSpec = {\n file,\n sections: sectionNames,\n brs,\n brsWithoutPriority,\n brsWithInvalidPriority,\n contractRefs: parseContractRefs(md),\n };\n if (specId) {\n parsed.specId = specId;\n }\n return parsed;\n}\n\nexport function parseContractRefs(md: string): ParsedContractRefs {\n const lines: string[] = [];\n for (const match of md.matchAll(CONTRACT_REF_LINE_RE)) {\n lines.push((match[1] ?? \"\").trim());\n }\n\n const ids: string[] = [];\n const invalidTokens: string[] = [];\n let hasNone = false;\n\n for (const line of lines) {\n if (line.length === 0) {\n invalidTokens.push(\"(empty)\");\n continue;\n }\n const tokens = line.split(\",\").map((token) => token.trim());\n for (const token of tokens) {\n if (token.length === 0) {\n invalidTokens.push(\"(empty)\");\n continue;\n }\n if (token === \"none\") {\n hasNone = true;\n continue;\n }\n if (CONTRACT_REF_ID_RE.test(token)) {\n ids.push(token);\n continue;\n }\n invalidTokens.push(token);\n }\n }\n\n return {\n lines,\n ids: unique(ids),\n invalidTokens: unique(invalidTokens),\n hasNone,\n };\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { collectFilesByGlobs } from \"./fs.js\";\nimport { parseScenarioDocument } from \"./scenarioModel.js\";\n\nexport const SC_TAG_RE = /^SC-\\d{4}$/;\nexport const SC_TEST_ANNOTATION_RE = /\\bQFAI:SC-(\\d{4})\\b/g;\nexport const DEFAULT_TEST_FILE_EXCLUDE_GLOBS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/.qfai/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/.next/**\",\n \"**/out/**\",\n];\n\nexport type ScCoverage = {\n total: number;\n covered: number;\n missing: number;\n missingIds: string[];\n refs: Record<string, string[]>;\n};\n\nexport type TestFileScan = {\n globs: string[];\n excludeGlobs: string[];\n matchedFileCount: number;\n};\n\nexport type ScTestReferenceResult = {\n refs: Map<string, Set<string>>;\n scan: TestFileScan;\n error?: string;\n};\n\nexport function extractAnnotatedScIds(text: string): string[] {\n const ids = new Set<string>();\n for (const match of text.matchAll(SC_TEST_ANNOTATION_RE)) {\n const suffix = match[1];\n if (suffix) {\n ids.add(`SC-${suffix}`);\n }\n }\n return Array.from(ids);\n}\n\nexport async function collectScIdsFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Set<string>> {\n const scIds = new Set<string>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n scIds.add(tag);\n }\n }\n }\n }\n return scIds;\n}\n\nexport async function collectScIdSourcesFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Map<string, Set<string>>> {\n const sources = new Map<string, Set<string>>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (!SC_TAG_RE.test(tag)) {\n continue;\n }\n const current = sources.get(tag) ?? new Set<string>();\n current.add(file);\n sources.set(tag, current);\n }\n }\n }\n return sources;\n}\n\nexport async function collectScTestReferences(\n root: string,\n globs: string[],\n excludeGlobs: string[],\n): Promise<ScTestReferenceResult> {\n const refs = new Map<string, Set<string>>();\n const normalizedGlobs = normalizeGlobs(globs);\n const normalizedExcludeGlobs = normalizeGlobs(excludeGlobs);\n const mergedExcludeGlobs = Array.from(\n new Set([...DEFAULT_TEST_FILE_EXCLUDE_GLOBS, ...normalizedExcludeGlobs]),\n );\n if (normalizedGlobs.length === 0) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n };\n }\n\n let files: string[] = [];\n try {\n files = await collectFilesByGlobs(root, {\n globs: normalizedGlobs,\n ignore: mergedExcludeGlobs,\n });\n } catch (error) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n error: formatError(error),\n };\n }\n\n const normalizedFiles = Array.from(\n new Set(files.map((file) => path.normalize(file))),\n );\n for (const file of normalizedFiles) {\n const text = await readFile(file, \"utf-8\");\n const scIds = extractAnnotatedScIds(text);\n if (scIds.length === 0) {\n continue;\n }\n for (const scId of scIds) {\n const current = refs.get(scId) ?? new Set<string>();\n current.add(file);\n refs.set(scId, current);\n }\n }\n\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: normalizedFiles.length,\n },\n };\n}\n\nexport function buildScCoverage(\n scIds: Iterable<string>,\n refs: Map<string, Set<string>>,\n): ScCoverage {\n const sortedScIds = toSortedArray(scIds);\n const refsRecord: Record<string, string[]> = {};\n const missingIds: string[] = [];\n let covered = 0;\n\n for (const scId of sortedScIds) {\n const files = refs.get(scId);\n const sortedFiles = files ? toSortedArray(files) : [];\n refsRecord[scId] = sortedFiles;\n if (sortedFiles.length === 0) {\n missingIds.push(scId);\n } else {\n covered += 1;\n }\n }\n\n return {\n total: sortedScIds.length,\n covered,\n missing: missingIds.length,\n missingIds,\n refs: refsRecord,\n };\n}\n\nfunction toSortedArray(values: Iterable<string>): string[] {\n return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));\n}\n\nfunction normalizeGlobs(globs: string[]): string[] {\n return globs.map((glob) => glob.trim()).filter((glob) => glob.length > 0);\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import {\n AstBuilder,\n GherkinClassicTokenMatcher,\n Parser,\n} from \"@cucumber/gherkin\";\nimport type { GherkinDocument } from \"@cucumber/messages\";\nimport { randomUUID } from \"node:crypto\";\n\nexport type ParsedGherkin = {\n gherkinDocument: GherkinDocument | null;\n errors: string[];\n};\n\nexport function parseGherkin(source: string, uri: string): ParsedGherkin {\n const errors: string[] = [];\n const uuidFn = () => randomUUID();\n const builder = new AstBuilder(uuidFn);\n const matcher = new GherkinClassicTokenMatcher();\n const parser = new Parser(builder, matcher);\n\n try {\n const gherkinDocument = parser.parse(source);\n gherkinDocument.uri = uri;\n return { gherkinDocument, errors };\n } catch (error) {\n errors.push(formatError(error));\n return { gherkinDocument: null, errors };\n }\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import type * as Messages from \"@cucumber/messages\";\n\nimport { parseGherkin } from \"./gherkin/parse.js\";\nimport { extractIds } from \"./ids.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\nconst UI_TAG_RE = /^UI-\\d{4}$/;\nconst API_TAG_RE = /^API-\\d{4}$/;\nconst DB_TAG_RE = /^DB-\\d{4}$/;\n\nexport type ScenarioKind = \"Scenario\" | \"ScenarioOutline\";\n\nexport type ScenarioNode = {\n name: string;\n kind: ScenarioKind;\n line?: number;\n tags: string[];\n steps: readonly Messages.Step[];\n};\n\nexport type ScenarioDocument = {\n uri: string;\n featureName?: string;\n featureTags: string[];\n scenarios: ScenarioNode[];\n};\n\nexport type ScenarioParseResult = {\n document: ScenarioDocument | null;\n errors: string[];\n};\n\nexport type ScenarioAtom = {\n uri: string;\n featureName: string;\n scenarioName: string;\n kind: ScenarioKind;\n specId?: string;\n scId?: string;\n brIds: string[];\n contractIds: string[];\n line?: number;\n};\n\nexport function parseScenarioDocument(\n text: string,\n uri: string,\n): ScenarioParseResult {\n const { gherkinDocument, errors } = parseGherkin(text, uri);\n if (!gherkinDocument) {\n return { document: null, errors };\n }\n\n const feature = gherkinDocument.feature;\n if (!feature) {\n return {\n document: { uri, featureTags: [], scenarios: [] },\n errors,\n };\n }\n\n const featureTags = collectTagNames(feature.tags);\n const scenarios = collectScenarioNodes(feature, featureTags);\n return {\n document: {\n uri,\n featureName: feature.name,\n featureTags,\n scenarios,\n },\n errors,\n };\n}\n\nexport function buildScenarioAtoms(document: ScenarioDocument): ScenarioAtom[] {\n return document.scenarios.map((scenario) => {\n const specIds = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const scIds = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n const brIds = unique(scenario.tags.filter((tag) => BR_TAG_RE.test(tag)));\n\n const contractIds = new Set<string>();\n scenario.tags.forEach((tag) => {\n if (UI_TAG_RE.test(tag) || API_TAG_RE.test(tag) || DB_TAG_RE.test(tag)) {\n contractIds.add(tag);\n }\n });\n\n for (const step of scenario.steps) {\n for (const text of collectStepTexts(step)) {\n extractIds(text, \"UI\").forEach((id) => contractIds.add(id));\n extractIds(text, \"API\").forEach((id) => contractIds.add(id));\n extractIds(text, \"DB\").forEach((id) => contractIds.add(id));\n }\n }\n\n const atom: ScenarioAtom = {\n uri: document.uri,\n featureName: document.featureName ?? \"\",\n scenarioName: scenario.name,\n kind: scenario.kind,\n brIds,\n contractIds: Array.from(contractIds).sort(),\n };\n\n if (scenario.line !== undefined) {\n atom.line = scenario.line;\n }\n if (specIds.length === 1) {\n const specId = specIds[0];\n if (specId) {\n atom.specId = specId;\n }\n }\n if (scIds.length === 1) {\n const scId = scIds[0];\n if (scId) {\n atom.scId = scId;\n }\n }\n\n return atom;\n });\n}\n\nfunction collectScenarioNodes(\n feature: Messages.Feature,\n featureTags: string[],\n): ScenarioNode[] {\n const scenarios: ScenarioNode[] = [];\n\n for (const child of feature.children) {\n if (child.scenario) {\n scenarios.push(buildScenarioNode(child.scenario, featureTags, []));\n }\n if (child.rule) {\n const ruleTags = collectTagNames(child.rule.tags);\n for (const ruleChild of child.rule.children) {\n if (ruleChild.scenario) {\n scenarios.push(\n buildScenarioNode(ruleChild.scenario, featureTags, ruleTags),\n );\n }\n }\n }\n }\n\n return scenarios;\n}\n\nfunction buildScenarioNode(\n scenario: Messages.Scenario,\n featureTags: string[],\n ruleTags: string[],\n): ScenarioNode {\n const tags = [...featureTags, ...ruleTags, ...collectTagNames(scenario.tags)];\n const kind: ScenarioKind =\n scenario.examples.length > 0 ? \"ScenarioOutline\" : \"Scenario\";\n return {\n name: scenario.name,\n kind,\n line: scenario.location?.line,\n tags,\n steps: scenario.steps,\n };\n}\n\nfunction collectTagNames(tags: readonly Messages.Tag[]): string[] {\n return tags.map((tag) => tag.name.replace(/^@/, \"\"));\n}\n\nfunction collectStepTexts(step: Messages.Step): string[] {\n const texts: string[] = [];\n if (step.text) {\n texts.push(step.text);\n }\n if (step.docString?.content) {\n texts.push(step.docString.content);\n }\n if (step.dataTable?.rows) {\n for (const row of step.dataTable.rows) {\n for (const cell of row.cells) {\n texts.push(cell.value);\n }\n }\n }\n return texts;\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ndeclare const __QFAI_TOOL_VERSION__: string | undefined;\n\nexport async function resolveToolVersion(): Promise<string> {\n if (\n typeof __QFAI_TOOL_VERSION__ === \"string\" &&\n __QFAI_TOOL_VERSION__.length > 0\n ) {\n return __QFAI_TOOL_VERSION__;\n }\n\n try {\n const packagePath = resolvePackageJsonPath();\n const raw = await readFile(packagePath, \"utf-8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n const version = typeof parsed.version === \"string\" ? parsed.version : \"\";\n return version.length > 0 ? version : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction resolvePackageJsonPath(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n return path.resolve(path.dirname(basePath), \"../../package.json\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { parseStructuredContract } from \"../contracts.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport {\n extractDeclaredContractIds,\n stripContractDeclarationLines,\n} from \"../contractsDecl.js\";\nimport {\n collectApiContractFiles,\n collectDataContractFiles,\n collectUiContractFiles,\n} from \"../discovery.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SQL_DANGEROUS_PATTERNS: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /\\bDROP\\s+TABLE\\b/i, label: \"DROP TABLE\" },\n { pattern: /\\bDROP\\s+DATABASE\\b/i, label: \"DROP DATABASE\" },\n { pattern: /\\bTRUNCATE\\b/i, label: \"TRUNCATE\" },\n {\n pattern: /\\bALTER\\s+TABLE\\b[\\s\\S]*\\bDROP\\b/i,\n label: \"ALTER TABLE ... DROP\",\n },\n];\n\nexport async function validateContracts(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n\n issues.push(...(await validateUiContracts(path.join(contractsRoot, \"ui\"))));\n issues.push(...(await validateApiContracts(path.join(contractsRoot, \"api\"))));\n issues.push(...(await validateDataContracts(path.join(contractsRoot, \"db\"))));\n const contractIndex = await buildContractIndex(root, config);\n issues.push(...validateDuplicateContractIds(contractIndex));\n\n return issues;\n}\n\nasync function validateUiContracts(uiRoot: string): Promise<Issue[]> {\n const files = await collectUiContractFiles(uiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-UI-000\",\n \"UI 契約ファイルが見つかりません。\",\n \"info\",\n uiRoot,\n \"contracts.ui.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"UI\"));\n try {\n parseStructuredContract(file, stripContractDeclarationLines(text));\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `UI 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.ui.parse\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateApiContracts(apiRoot: string): Promise<Issue[]> {\n const files = await collectApiContractFiles(apiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-API-000\",\n \"API 契約ファイルが見つかりません。\",\n \"info\",\n apiRoot,\n \"contracts.api.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"API\"));\n let doc: Record<string, unknown>;\n try {\n doc = parseStructuredContract(file, stripContractDeclarationLines(text));\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `API 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.api.parse\",\n ),\n );\n continue;\n }\n\n if (!hasOpenApi(doc)) {\n issues.push(\n issue(\n \"QFAI-API-001\",\n \"OpenAPI 定義が見つかりません。\",\n \"error\",\n file,\n \"contracts.api.openapi\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateDataContracts(dataRoot: string): Promise<Issue[]> {\n const files = await collectDataContractFiles(dataRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-DB-000\",\n \"DB 契約ファイルが見つかりません。\",\n \"info\",\n dataRoot,\n \"contracts.db.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"DB\"));\n issues.push(...lintSql(text, file));\n }\n\n return issues;\n}\n\nexport function lintSql(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n for (const { pattern, label } of SQL_DANGEROUS_PATTERNS) {\n if (pattern.test(text)) {\n issues.push(\n issue(\n \"QFAI-DB-001\",\n `危険な SQL 操作が含まれています: ${label}`,\n \"warning\",\n file,\n \"contracts.db.sql\",\n ),\n );\n }\n }\n return issues;\n}\n\ntype ContractKind = \"UI\" | \"API\" | \"DB\";\n\nfunction validateDeclaredContractIds(\n ids: string[],\n file: string,\n kind: ContractKind,\n): Issue[] {\n const issues: Issue[] = [];\n if (ids.length === 0) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-010\",\n `契約ファイルに QFAI-CONTRACT-ID がありません: ${file}`,\n \"error\",\n file,\n \"contracts.declaration\",\n ),\n );\n return issues;\n }\n if (ids.length > 1) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-011\",\n `契約ファイルに複数の QFAI-CONTRACT-ID が宣言されています: ${ids.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"contracts.declaration\",\n ids,\n ),\n );\n return issues;\n }\n\n const [id] = ids;\n if (id && !id.startsWith(`${kind}-`)) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-013\",\n `契約ファイルの QFAI-CONTRACT-ID が ${kind}- ではありません: ${id}`,\n \"error\",\n file,\n \"contracts.declarationPrefix\",\n [id],\n ),\n );\n }\n\n return issues;\n}\n\nfunction validateDuplicateContractIds(contractIndex: {\n idToFiles: Map<string, Set<string>>;\n}): Issue[] {\n const issues: Issue[] = [];\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sortedFiles = Array.from(files).sort((a, b) => a.localeCompare(b));\n issues.push(\n issue(\n \"QFAI-CONTRACT-012\",\n `契約 ID が複数ファイルで宣言されています: ${id} (${sortedFiles.join(\n \", \",\n )})`,\n \"error\",\n sortedFiles[0],\n \"contracts.idDuplicate\",\n [id],\n ),\n );\n }\n return issues;\n}\n\nfunction hasOpenApi(doc: Record<string, unknown>): boolean {\n return typeof doc.openapi === \"string\" && doc.openapi.length > 0;\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport { extractIds } from \"./ids.js\";\n\nexport function parseStructuredContract(\n file: string,\n text: string,\n): Record<string, unknown> {\n const ext = path.extname(file).toLowerCase();\n if (ext === \".json\") {\n return JSON.parse(text) as Record<string, unknown>;\n }\n return parseYaml(text) as Record<string, unknown>;\n}\n\nexport function extractUiContractIds(doc: Record<string, unknown>): string[] {\n const id = typeof doc.id === \"string\" ? doc.id : \"\";\n return extractIds(id, \"UI\");\n}\n\nexport function extractApiContractIds(doc: Record<string, unknown>): string[] {\n const operationIds = new Set<string>();\n collectOperationIds(doc, operationIds);\n\n const ids = new Set<string>();\n for (const operationId of operationIds) {\n extractIds(operationId, \"API\").forEach((id) => ids.add(id));\n }\n return Array.from(ids);\n}\n\nexport function collectOperationIds(value: unknown, out: Set<string>): void {\n if (!value || typeof value !== \"object\") {\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectOperationIds(item, out);\n }\n return;\n }\n\n for (const [key, entry] of Object.entries(value)) {\n if (key === \"operationId\" && typeof entry === \"string\") {\n out.add(entry);\n continue;\n }\n collectOperationIds(entry, out);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { collectSpecPackDirs } from \"../discovery.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SECTION_RE = /^##\\s+変更区分/m;\nconst COMPAT_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Change\\/Improvement\\b/m;\nconst COMPAT_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Change\\/Improvement\\b/m;\n\nexport async function validateDeltas(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const packs = await collectSpecPackDirs(specsRoot);\n if (packs.length === 0) {\n return [];\n }\n\n const issues: Issue[] = [];\n for (const pack of packs) {\n const deltaPath = path.join(pack, \"delta.md\");\n let text: string;\n try {\n text = await readFile(deltaPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-DELTA-001\",\n \"delta.md が見つかりません。\",\n \"error\",\n deltaPath,\n \"delta.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n\n const hasSection = SECTION_RE.test(text);\n const hasCompatibility = COMPAT_LINE_RE.test(text);\n const hasChange = CHANGE_LINE_RE.test(text);\n if (!hasSection || !hasCompatibility || !hasChange) {\n issues.push(\n issue(\n \"QFAI-DELTA-002\",\n \"delta.md の変更区分が不足しています。\",\n \"error\",\n deltaPath,\n \"delta.section\",\n ),\n );\n continue;\n }\n\n const compatibilityChecked = COMPAT_CHECKED_RE.test(text);\n const changeChecked = CHANGE_CHECKED_RE.test(text);\n if (compatibilityChecked === changeChecked) {\n issues.push(\n issue(\n \"QFAI-DELTA-003\",\n \"delta.md の変更区分はどちらか1つだけ選択してください(両方ON/両方OFFは無効です)。\",\n \"error\",\n deltaPath,\n \"delta.classification\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SC_TAG_RE = /^SC-\\d{4}$/;\n\nexport async function validateDefinedIds(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const defined = new Map<string, Set<string>>();\n\n await collectSpecDefinitionIds(specFiles, defined);\n await collectScenarioDefinitionIds(scenarioFiles, defined);\n const contractIndex = await buildContractIndex(root, config);\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n for (const file of files) {\n recordId(defined, id, file);\n }\n }\n\n for (const [id, files] of defined.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sorted = Array.from(files).sort();\n issues.push(\n issue(\n \"QFAI-ID-001\",\n `ID が重複しています: ${id} (${formatFileList(sorted, root)})`,\n \"error\",\n sorted[0],\n \"id.duplicate\",\n ),\n );\n }\n\n return issues;\n}\n\nasync function collectSpecDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n recordId(out, parsed.specId, file);\n }\n parsed.brs.forEach((br) => recordId(out, br.id, file));\n }\n}\n\nasync function collectScenarioDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n recordId(out, tag, file);\n }\n }\n }\n }\n}\n\nfunction recordId(\n out: Map<string, Set<string>>,\n id: string,\n file: string,\n): void {\n const current = out.get(id) ?? new Set<string>();\n current.add(file);\n out.set(id, current);\n}\n\nfunction formatFileList(files: string[], root: string): string {\n return files\n .map((file) => {\n const relative = path.relative(root, file);\n return relative.length > 0 ? relative : file;\n })\n .join(\", \");\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst GIVEN_PATTERN = /\\bGiven\\b/;\nconst WHEN_PATTERN = /\\bWhen\\b/;\nconst THEN_PATTERN = /\\bThen\\b/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\n\nexport async function validateScenarios(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/scenario.md\";\n const legacy = \"spec-001/scenario.md\";\n return [\n issue(\n \"QFAI-SC-000\",\n `Scenario ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"scenario.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.scenarioPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SC-001\",\n \"scenario.md が見つかりません。\",\n \"error\",\n entry.scenarioPath,\n \"scenario.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(...validateScenarioContent(text, entry.scenarioPath));\n }\n\n return issues;\n}\n\nexport function validateScenarioContent(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-010\",\n `Gherkin の解析に失敗しました: ${errors.join(\", \") || \"unknown\"}`,\n \"error\",\n file,\n \"scenario.parse\",\n ),\n );\n return issues;\n }\n\n const featureSpecTags = document.featureTags.filter((tag) =>\n SPEC_TAG_RE.test(tag),\n );\n if (featureSpecTags.length > 1) {\n issues.push(\n issue(\n \"QFAI-SC-009\",\n `Feature の SPEC タグが複数あります: ${featureSpecTags.join(\", \")}`,\n \"error\",\n file,\n \"scenario.featureSpec\",\n featureSpecTags,\n ),\n );\n }\n\n const missingStructure: string[] = [];\n if (!document.featureName) missingStructure.push(\"Feature\");\n if (document.scenarios.length === 0) missingStructure.push(\"Scenario\");\n if (missingStructure.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-006\",\n `Scenario ファイルに必要な構造がありません: ${missingStructure.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"scenario.structure\",\n ),\n );\n }\n\n for (const scenario of document.scenarios) {\n if (scenario.tags.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-007\",\n `Scenario タグが見つかりません: ${scenario.name}`,\n \"error\",\n file,\n \"scenario.tags\",\n ),\n );\n continue;\n }\n\n const missingTags: string[] = [];\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n if (scTags.length === 0) {\n missingTags.push(\"SC(0件)\");\n } else if (scTags.length > 1) {\n missingTags.push(`SC(${scTags.length}件/1件必須)`);\n }\n if (missingTags.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-008\",\n `Scenario タグに不足があります: ${missingTags.join(\", \")} (${\n scenario.name\n })`,\n \"error\",\n file,\n \"scenario.tagIds\",\n ),\n );\n }\n }\n\n for (const scenario of document.scenarios) {\n const missingSteps: string[] = [];\n const keywords = scenario.steps.map((step) => step.keyword.trim());\n if (!keywords.some((keyword) => GIVEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Given\");\n }\n if (!keywords.some((keyword) => WHEN_PATTERN.test(keyword))) {\n missingSteps.push(\"When\");\n }\n if (!keywords.some((keyword) => THEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Then\");\n }\n if (missingSteps.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-005\",\n `Given/When/Then が不足しています: ${missingSteps.join(\", \")} (${\n scenario.name\n })`,\n \"warning\",\n file,\n \"scenario.steps\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractIds, extractInvalidIds } from \"../ids.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nexport async function validateSpecs(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/spec.md\";\n const legacy = \"spec-001/spec.md\";\n return [\n issue(\n \"QFAI-SPEC-000\",\n `Spec ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"spec.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.specPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SPEC-005\",\n \"spec.md が見つかりません。\",\n \"error\",\n entry.specPath,\n \"spec.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(\n ...validateSpecContent(\n text,\n entry.specPath,\n config.validation.require.specSections,\n ),\n );\n }\n\n return issues;\n}\n\nexport function validateSpecContent(\n text: string,\n file: string,\n requiredSections: string[],\n): Issue[] {\n const issues: Issue[] = [];\n\n const parsed = parseSpec(text, file);\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n if (!parsed.specId) {\n issues.push(\n issue(\n \"QFAI-SPEC-001\",\n \"SPEC ID が見つかりません。\",\n \"error\",\n file,\n \"spec.id\",\n ),\n );\n }\n\n if (parsed.brs.length === 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-002\",\n \"BR ID が見つかりません。\",\n \"error\",\n file,\n \"spec.br\",\n ),\n );\n }\n\n for (const br of parsed.brsWithoutPriority) {\n issues.push(\n issue(\n \"QFAI-BR-001\",\n `BR 行に Priority がありません: ${br.id}`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n for (const br of parsed.brsWithInvalidPriority) {\n issues.push(\n issue(\n \"QFAI-BR-002\",\n `BR Priority が不正です: ${br.id} (${br.priority})`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n const scIds = extractIds(text, \"SC\");\n if (scIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-003\",\n \"Spec は SC を参照しないルールです。\",\n \"warning\",\n file,\n \"spec.noSc\",\n scIds,\n ),\n );\n }\n\n for (const section of requiredSections) {\n if (!parsed.sections.has(section)) {\n issues.push(\n issue(\n \"QFAI-SPEC-004\",\n `必須セクションが不足しています: ${section}`,\n \"error\",\n file,\n \"spec.requiredSection\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { collectFiles } from \"../fs.js\";\nimport { extractAllIds } from \"../ids.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { buildScenarioAtoms, parseScenarioDocument } from \"../scenarioModel.js\";\nimport { SC_TAG_RE, collectScTestReferences } from \"../traceability.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\n\nexport async function validateTraceability(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const upstreamIds = new Set<string>();\n const specIds = new Set<string>();\n const brIdsInSpecs = new Set<string>();\n const brIdsInScenarios = new Set<string>();\n const scIdsInScenarios = new Set<string>();\n const specContractIds = new Set<string>();\n const specToBrIds = new Map<string, Set<string>>();\n const contractIndex = await buildContractIndex(root, config);\n const contractIds = contractIndex.ids;\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n specIds.add(parsed.specId);\n }\n\n const brIds = parsed.brs.map((br) => br.id);\n brIds.forEach((id) => brIdsInSpecs.add(id));\n\n if (parsed.specId) {\n const current = specToBrIds.get(parsed.specId) ?? new Set<string>();\n brIds.forEach((id) => current.add(id));\n specToBrIds.set(parsed.specId, current);\n }\n\n const contractRefs = parsed.contractRefs;\n if (contractRefs.lines.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-020\",\n \"Spec に QFAI-CONTRACT-REF がありません。\",\n \"error\",\n file,\n \"traceability.specContractRefRequired\",\n ),\n );\n } else {\n if (contractRefs.hasNone && contractRefs.ids.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-021\",\n \"Spec の QFAI-CONTRACT-REF に none と契約 ID が混在しています。\",\n \"error\",\n file,\n \"traceability.specContractRefFormat\",\n ),\n );\n }\n if (contractRefs.invalidTokens.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-021\",\n `Spec の契約 ID が不正です: ${contractRefs.invalidTokens.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"traceability.specContractRefFormat\",\n contractRefs.invalidTokens,\n ),\n );\n }\n }\n\n contractRefs.ids.forEach((id) => {\n specContractIds.add(id);\n });\n\n const unknownContractIds = contractRefs.ids.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-021\",\n `Spec が未知の契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"traceability.specContractExists\",\n unknownContractIds,\n ),\n );\n }\n }\n\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n const atoms = buildScenarioAtoms(document);\n const scIdsInFile = new Set<string>();\n\n for (const [index, scenario] of document.scenarios.entries()) {\n const atom = atoms[index];\n if (!atom) {\n continue;\n }\n\n const specTags = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const brTags = scenario.tags.filter((tag) => BR_TAG_RE.test(tag));\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n\n if (specTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-014\",\n `Scenario が SPEC タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioSpecRequired\",\n ),\n );\n }\n if (brTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-015\",\n `Scenario が BR タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioBrRequired\",\n ),\n );\n }\n\n brTags.forEach((id) => brIdsInScenarios.add(id));\n scTags.forEach((id) => {\n scIdsInScenarios.add(id);\n scIdsInFile.add(id);\n });\n const unknownSpecIds = specTags.filter((id) => !specIds.has(id));\n if (unknownSpecIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-005\",\n `Scenario が存在しない SPEC を参照しています: ${unknownSpecIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioSpecExists\",\n unknownSpecIds,\n ),\n );\n }\n\n const unknownBrIds = brTags.filter((id) => !brIdsInSpecs.has(id));\n if (unknownBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-006\",\n `Scenario が存在しない BR を参照しています: ${unknownBrIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrExists\",\n unknownBrIds,\n ),\n );\n }\n\n const unknownContractIds = atom.contractIds.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-008\",\n `Scenario が存在しない契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )} (${scenario.name})`,\n config.validation.traceability.unknownContractIdSeverity,\n file,\n \"traceability.scenarioContractExists\",\n unknownContractIds,\n ),\n );\n }\n\n if (specTags.length > 0 && brTags.length > 0) {\n const allowedBrIds = new Set<string>();\n for (const specId of specTags) {\n const brIdsForSpec = specToBrIds.get(specId);\n if (!brIdsForSpec) {\n continue;\n }\n brIdsForSpec.forEach((id) => allowedBrIds.add(id));\n }\n const invalidBrIds = brTags.filter((id) => !allowedBrIds.has(id));\n if (invalidBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-007\",\n `Scenario の BR が参照 SPEC に属していません: ${invalidBrIds.join(\n \", \",\n )} (SPEC: ${specTags.join(\", \")}) (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrUnderSpec\",\n invalidBrIds,\n ),\n );\n }\n }\n }\n\n if (scIdsInFile.size !== 1) {\n const invalidScIds = Array.from(scIdsInFile).sort((a, b) =>\n a.localeCompare(b),\n );\n const detail =\n invalidScIds.length === 0\n ? \"SC が見つかりません\"\n : `複数の SC が存在します: ${invalidScIds.join(\", \")}`;\n issues.push(\n issue(\n \"QFAI-TRACE-012\",\n `Spec entry が Spec:SC=1:1 を満たしていません: ${detail}`,\n \"error\",\n file,\n \"traceability.specScOneToOne\",\n invalidScIds,\n ),\n );\n }\n }\n\n if (upstreamIds.size === 0) {\n return [\n issue(\n \"QFAI-TRACE-000\",\n \"上流 ID が見つかりません。\",\n \"info\",\n specsRoot,\n \"traceability.upstream\",\n ),\n ];\n }\n\n if (config.validation.traceability.brMustHaveSc && brIdsInSpecs.size > 0) {\n const orphanBrIds = Array.from(brIdsInSpecs).filter(\n (id) => !brIdsInScenarios.has(id),\n );\n if (orphanBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_TRACE_BR_ORPHAN\",\n `BR が SC に紐づいていません: ${orphanBrIds.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.brMustHaveSc\",\n orphanBrIds,\n ),\n );\n }\n }\n\n const scRefsResult = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scTestRefs = scRefsResult.refs;\n const testFileScan = scRefsResult.scan;\n const hasScenarios = scIdsInScenarios.size > 0;\n const hasGlobConfig = testFileScan.globs.length > 0;\n const hasMatchedTests = testFileScan.matchedFileCount > 0;\n\n if (\n hasScenarios &&\n (!hasGlobConfig || !hasMatchedTests || scRefsResult.error)\n ) {\n const detail = scRefsResult.error ? `(詳細: ${scRefsResult.error})` : \"\";\n issues.push(\n issue(\n \"QFAI-TRACE-013\",\n `テスト探索 glob が未設定/不正/一致ファイル0のため SC→Test を判定できません。${detail}`,\n \"error\",\n testsRoot,\n \"traceability.testFileGlobs\",\n ),\n );\n } else {\n if (\n config.validation.traceability.scMustHaveTest &&\n scIdsInScenarios.size\n ) {\n const scWithoutTests = Array.from(scIdsInScenarios).filter((id) => {\n const refs = scTestRefs.get(id);\n return !refs || refs.size === 0;\n });\n if (scWithoutTests.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-010\",\n `SC がテストで参照されていません: ${scWithoutTests.join(\n \", \",\n )}。testFileGlobs に一致するテストファイルへ QFAI:SC-xxxx を記載してください。`,\n config.validation.traceability.scNoTestSeverity,\n testsRoot,\n \"traceability.scMustHaveTest\",\n scWithoutTests,\n ),\n );\n }\n }\n\n const unknownScIds = Array.from(scTestRefs.keys()).filter(\n (id) => !scIdsInScenarios.has(id),\n );\n if (unknownScIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-011\",\n `テストが未知の SC をアノテーション参照しています: ${unknownScIds.join(\n \", \",\n )}`,\n \"error\",\n testsRoot,\n \"traceability.scUnknownInTests\",\n unknownScIds,\n ),\n );\n }\n }\n\n if (!config.validation.traceability.allowOrphanContracts) {\n if (contractIds.size > 0) {\n const orphanContracts = Array.from(contractIds).filter(\n (id) => !specContractIds.has(id),\n );\n if (orphanContracts.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-022\",\n `契約が Spec から参照されていません: ${orphanContracts.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.contractCoverage\",\n orphanContracts,\n ),\n );\n }\n }\n }\n\n issues.push(\n ...(await validateCodeReferences(upstreamIds, srcRoot, testsRoot)),\n );\n return issues;\n}\n\nasync function validateCodeReferences(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-001\",\n \"参照対象のコード/テストが見つかりません。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n return issues;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n let found = false;\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n issues.push(\n issue(\n \"QFAI-TRACE-002\",\n \"上流 ID がコード/テストに参照されていません(参考情報)。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n }\n\n return issues;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport { collectScenarioFiles } from \"./discovery.js\";\nimport {\n buildScCoverage,\n collectScIdsFromScenarioFiles,\n collectScTestReferences,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { resolveToolVersion } from \"./version.js\";\nimport { validateContracts } from \"./validators/contracts.js\";\nimport { validateDeltas } from \"./validators/delta.js\";\nimport { validateDefinedIds } from \"./validators/ids.js\";\nimport { validateScenarios } from \"./validators/scenario.js\";\nimport { validateSpecs } from \"./validators/spec.js\";\nimport { validateTraceability } from \"./validators/traceability.js\";\n\nexport async function validateProject(\n root: string,\n configResult?: ConfigLoadResult,\n): Promise<ValidationResult> {\n const resolved = configResult ?? (await loadConfig(root));\n const { config, issues: configIssues } = resolved;\n const issues = [\n ...configIssues,\n ...(await validateSpecs(root, config)),\n ...(await validateDeltas(root, config)),\n ...(await validateScenarios(root, config)),\n ...(await validateContracts(root, config)),\n ...(await validateDefinedIds(root, config)),\n ...(await validateTraceability(root, config)),\n ];\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const scIds = await collectScIdsFromScenarioFiles(scenarioFiles);\n const { refs: scTestRefs, scan: testFiles } = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scCoverage = buildScCoverage(scIds, scTestRefs);\n\n const toolVersion = await resolveToolVersion();\n return {\n toolVersion,\n issues,\n counts: countIssues(issues),\n traceability: {\n sc: scCoverage,\n testFiles,\n },\n };\n}\n\nfunction countIssues(issues: Issue[]): ValidationCounts {\n return issues.reduce<ValidationCounts>(\n (acc, issue) => {\n acc[issue.severity] += 1;\n return acc;\n },\n { info: 0, warning: 0, error: 0 },\n );\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { FailOn, OutputFormat } from \"../../core/config.js\";\nimport { loadConfig } from \"../../core/config.js\";\nimport type { Issue, ValidationResult } from \"../../core/types.js\";\nimport { validateProject } from \"../../core/validate.js\";\nimport { shouldFail } from \"../lib/failOn.js\";\n\nexport type ValidateOptions = {\n root: string;\n strict: boolean;\n failOn?: FailOn;\n format?: OutputFormat;\n};\n\nexport async function runValidate(options: ValidateOptions): Promise<number> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const result = await validateProject(root, configResult);\n\n const format = options.format ?? \"text\";\n if (format === \"text\") {\n emitText(result);\n }\n if (format === \"github\") {\n result.issues.forEach(emitGitHub);\n }\n await emitJson(result, root, configResult.config.output.validateJsonPath);\n\n const failOn = resolveFailOn(options, configResult.config.validation.failOn);\n return shouldFail(result, failOn) ? 1 : 0;\n}\n\nfunction resolveFailOn(options: ValidateOptions, fallback: FailOn): FailOn {\n if (options.failOn) {\n return options.failOn;\n }\n if (options.strict) {\n return \"warning\";\n }\n return fallback;\n}\n\nfunction emitText(result: ValidationResult): void {\n for (const item of result.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n process.stdout.write(\n `[${item.severity}] ${item.code} ${item.message}${location}${refs}\\n`,\n );\n }\n process.stdout.write(\n `counts: info=${result.counts.info} warning=${result.counts.warning} error=${result.counts.error}\\n`,\n );\n}\n\nfunction emitGitHub(issue: Issue): void {\n const level =\n issue.severity === \"error\"\n ? \"error\"\n : issue.severity === \"warning\"\n ? \"warning\"\n : \"notice\";\n const file = issue.file ? `file=${issue.file}` : \"\";\n const line = issue.loc?.line ? `,line=${issue.loc.line}` : \"\";\n const column = issue.loc?.column ? `,col=${issue.loc.column}` : \"\";\n const location = file ? ` ${file}${line}${column}` : \"\";\n process.stdout.write(\n `::${level}${location}::${issue.code}: ${issue.message}\\n`,\n );\n}\n\nasync function emitJson(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n): Promise<void> {\n const abs = path.isAbsolute(jsonPath)\n ? jsonPath\n : path.resolve(root, jsonPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\n","import type { FailOn } from \"../../core/config.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\n\nexport type { FailOn };\n\nexport function shouldFail(result: ValidationResult, failOn: FailOn): boolean {\n if (failOn === \"never\") {\n return false;\n }\n if (failOn === \"error\") {\n return result.counts.error > 0;\n }\n return result.counts.error + result.counts.warning > 0;\n}\n","export type ParsedArgs = {\n command: string | null;\n options: {\n root: string;\n dir: string;\n force: boolean;\n yes: boolean;\n dryRun: boolean;\n reportFormat: \"md\" | \"json\";\n reportOut?: string;\n validateFormat: \"text\" | \"github\";\n strict: boolean;\n failOn?: \"never\" | \"warning\" | \"error\";\n help: boolean;\n };\n};\n\nexport function parseArgs(argv: string[], cwd: string): ParsedArgs {\n const options: ParsedArgs[\"options\"] = {\n root: cwd,\n dir: cwd,\n force: false,\n yes: false,\n dryRun: false,\n reportFormat: \"md\",\n validateFormat: \"text\",\n strict: false,\n help: false,\n };\n\n const args = [...argv];\n let command = args.shift() ?? null;\n\n if (command === \"--help\" || command === \"-h\") {\n options.help = true;\n command = null;\n }\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n switch (arg) {\n case \"--root\":\n options.root = args[i + 1] ?? options.root;\n i += 1;\n break;\n case \"--dir\":\n options.dir = args[i + 1] ?? options.dir;\n i += 1;\n break;\n case \"--force\":\n options.force = true;\n break;\n case \"--yes\":\n options.yes = true;\n break;\n case \"--dry-run\":\n options.dryRun = true;\n break;\n case \"--format\": {\n const next = args[i + 1];\n applyFormatOption(command, next, options);\n i += 1;\n break;\n }\n case \"--strict\":\n options.strict = true;\n break;\n case \"--fail-on\": {\n const next = args[i + 1];\n if (next === \"never\" || next === \"warning\" || next === \"error\") {\n options.failOn = next;\n }\n i += 1;\n break;\n }\n case \"--out\":\n {\n const next = args[i + 1];\n if (next) {\n options.reportOut = next;\n }\n }\n i += 1;\n break;\n case \"--help\":\n case \"-h\":\n options.help = true;\n break;\n default:\n break;\n }\n }\n\n return { command, options };\n}\n\nfunction applyFormatOption(\n command: string | null,\n value: string | undefined,\n options: ParsedArgs[\"options\"],\n): void {\n if (!value) {\n return;\n }\n if (command === \"report\") {\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n return;\n }\n if (command === \"validate\") {\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n return;\n }\n\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n}\n","import { runInit } from \"./commands/init.js\";\nimport { runReport } from \"./commands/report.js\";\nimport { runValidate } from \"./commands/validate.js\";\nimport { parseArgs } from \"./lib/args.js\";\nimport { error, info } from \"./lib/logger.js\";\n\nexport async function run(argv: string[], cwd: string): Promise<void> {\n const { command, options } = parseArgs(argv, cwd);\n\n if (!command || options.help) {\n info(usage());\n return;\n }\n\n switch (command) {\n case \"init\":\n await runInit({\n dir: options.dir,\n force: options.force,\n dryRun: options.dryRun,\n yes: options.yes,\n });\n return;\n case \"validate\":\n process.exitCode = await runValidate({\n root: options.root,\n strict: options.strict,\n format: options.validateFormat,\n ...(options.failOn !== undefined ? { failOn: options.failOn } : {}),\n });\n return;\n case \"report\":\n await runReport({\n root: options.root,\n format: options.reportFormat,\n ...(options.reportOut !== undefined\n ? { outPath: options.reportOut }\n : {}),\n });\n return;\n default:\n error(`Unknown command: ${command}`);\n info(usage());\n return;\n }\n}\n\nfunction usage(): string {\n return `qfai <command> [options]\n\nCommands:\n init テンプレを生成\n validate 仕様/契約/参照の検査\n report 検証結果と集計を出力\n\nOptions:\n --root <path> 対象ディレクトリ\n --dir <path> init の出力先\n --force 既存ファイルを上書き\n --yes init: 予約フラグ(現状は非対話のため挙動差なし。将来の対話導入時に自動Yes)\n --dry-run 変更を行わず表示のみ\n --format <text|github> validate の出力形式\n --format <md|json> report の出力形式\n --strict validate: warning 以上で exit 1\n --fail-on <error|warning|never> validate: 失敗条件\n --out <path> report: 出力先\n -h, --help ヘルプ表示\n`;\n}\n","#!/usr/bin/env node\nimport { run } from \"./main.js\";\n\nrun(process.argv.slice(2), process.cwd()).catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":";;;AAAA,OAAOA,WAAU;;;ACAjB,SAAS,QAAQ,UAAU,OAAO,eAAe;AACjD,OAAO,UAAU;AAYjB,eAAsB,iBACpB,YACA,UACA,SACqB;AACrB,QAAM,QAAQ,MAAM,qBAAqB,UAAU;AACnD,SAAO,UAAU,OAAO,YAAY,UAAU,OAAO;AACvD;AAkBA,eAAe,UACb,OACA,YACA,UACA,SACqB;AACrB,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAoB,CAAC;AAC3B,QAAM,YAAsB,CAAC;AAE7B,MAAI,CAAC,QAAQ,OAAO;AAClB,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,KAAK,SAAS,YAAY,IAAI;AAC/C,YAAM,OAAO,KAAK,KAAK,UAAU,QAAQ;AACzC,UAAI,CAAE,MAAM,YAAY,MAAM,QAAQ,KAAK,GAAI;AAC7C,kBAAU,KAAK,IAAI;AAAA,MACrB;AAAA,IACF;AAEA,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,IAAI,MAAM,sBAAsB,SAAS,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,KAAK,SAAS,YAAY,IAAI;AAC/C,UAAM,OAAO,KAAK,KAAK,UAAU,QAAQ;AAEzC,QAAI,CAAE,MAAM,YAAY,MAAM,QAAQ,KAAK,GAAI;AAC7C,cAAQ,KAAK,IAAI;AACjB;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,QAAQ;AACnB,YAAM,MAAM,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,YAAM,SAAS,MAAM,IAAI;AAAA,IAC3B;AACA,WAAO,KAAK,IAAI;AAAA,EAClB;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEA,SAAS,sBAAsB,WAA6B;AAC1D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,UAAU,IAAI,CAAC,aAAa,KAAK,QAAQ,EAAE;AAAA,IAC9C;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,eAAe,qBAAqB,MAAiC;AACnE,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAE,MAAM,OAAO,IAAI,GAAI;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AACzD,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAW,KAAK,KAAK,MAAM,KAAK,IAAI;AAC1C,QAAI,KAAK,YAAY,GAAG;AACtB,YAAM,SAAS,MAAM,qBAAqB,QAAQ;AAClD,cAAQ,KAAK,GAAG,MAAM;AACtB;AAAA,IACF;AACA,QAAI,KAAK,OAAO,GAAG;AACjB,cAAQ,KAAK,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,YAAY,QAAgB,OAAkC;AAC3E,MAAI,OAAO;AACT,WAAO;AAAA,EACT;AACA,SAAO,CAAE,MAAM,OAAO,MAAM;AAC9B;AAEA,eAAe,OAAO,QAAkC;AACtD,MAAI;AACF,UAAM,OAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AChIA,SAAS,kBAAkB;AAC3B,OAAOC,WAAU;AACjB,SAAS,qBAAqB;AAEvB,SAAS,mBAA2B;AACzC,QAAM,OAAO,YAAY;AACzB,QAAM,WAAW,KAAK,WAAW,OAAO,IAAI,cAAc,IAAI,IAAI;AAClE,QAAM,UAAUA,MAAK,QAAQ,QAAQ;AAErC,QAAM,aAAa;AAAA,IACjBA,MAAK,QAAQ,SAAS,sBAAsB;AAAA,IAC5CA,MAAK,QAAQ,SAAS,mBAAmB;AAAA,EAC3C;AAEA,aAAW,aAAa,YAAY;AAClC,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA;AAAA,MACA,GAAG,WAAW,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;AAAA,IACnD,EAAE,KAAK,IAAI;AAAA,EACb;AACF;;;AC3BO,SAAS,KAAK,SAAuB;AAC1C,UAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACrC;AAMO,SAAS,MAAM,SAAuB;AAC3C,UAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACrC;;;AHGA,eAAsB,QAAQ,SAAqC;AACjE,QAAM,aAAa,iBAAiB;AACpC,QAAM,aAAaC,MAAK,KAAK,YAAY,MAAM;AAC/C,QAAM,aAAaA,MAAK,KAAK,YAAY,OAAO;AAEhD,QAAM,WAAWA,MAAK,QAAQ,QAAQ,GAAG;AACzC,QAAM,WAAWA,MAAK,KAAK,UAAU,OAAO;AAE5C,QAAM,aAAa,MAAM,iBAAiB,YAAY,UAAU;AAAA,IAC9D,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACD,QAAM,aAAa,MAAM,iBAAiB,YAAY,UAAU;AAAA,IAC9D,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED;AAAA,IACE,CAAC,GAAG,WAAW,QAAQ,GAAG,WAAW,MAAM;AAAA,IAC3C,CAAC,GAAG,WAAW,SAAS,GAAG,WAAW,OAAO;AAAA,IAC7C,QAAQ;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,OACP,QACA,SACA,QACA,OACM;AACN,OAAK,QAAQ,KAAK,KAAK,SAAS,YAAY,MAAM,EAAE;AACpD,MAAI,OAAO,SAAS,GAAG;AACrB,SAAK,cAAc,OAAO,MAAM,EAAE;AAAA,EACpC;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,SAAK,cAAc,QAAQ,MAAM,EAAE;AAAA,EACrC;AACF;;;AInDA,SAAS,SAAAC,QAAO,YAAAC,YAAU,iBAAiB;AAC3C,OAAOC,YAAU;;;ACDjB,SAAS,gBAAgB;AACzB,OAAOC,WAAU;AAEjB,SAAS,SAAS,iBAAiB;AAoD5B,IAAM,gBAA4B;AAAA,EACvC,OAAO;AAAA,IACL,cAAc;AAAA,IACd,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,eAAe,CAAC;AAAA,MAChB,sBAAsB,CAAC;AAAA,MACvB,kBAAkB;AAAA,MAClB,sBAAsB;AAAA,MACtB,2BAA2B;AAAA,IAC7B;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,kBAAkB;AAAA,EACpB;AACF;AAEO,SAAS,cAAc,MAAsB;AAClD,SAAOA,MAAK,KAAK,MAAM,kBAAkB;AAC3C;AAEA,eAAsB,WAAW,MAAyC;AACxE,QAAM,aAAa,cAAc,IAAI;AACrC,QAAM,SAAkB,CAAC;AAEzB,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,YAAY,OAAO;AAC9C,aAAS,UAAU,GAAG;AAAA,EACxB,SAASC,QAAO;AACd,QAAI,cAAcA,MAAK,GAAG;AACxB,aAAO,EAAE,QAAQ,eAAe,QAAQ,WAAW;AAAA,IACrD;AACA,WAAO,KAAK,YAAY,YAAY,YAAYA,MAAK,CAAC,CAAC;AACvD,WAAO,EAAE,QAAQ,eAAe,QAAQ,WAAW;AAAA,EACrD;AAEA,QAAM,aAAa,gBAAgB,QAAQ,YAAY,MAAM;AAC7D,SAAO,EAAE,QAAQ,YAAY,QAAQ,WAAW;AAClD;AAEO,SAAS,YACd,MACA,QACA,KACQ;AACR,SAAOD,MAAK,QAAQ,MAAM,OAAO,MAAM,GAAG,CAAC;AAC7C;AAEA,SAAS,gBACP,KACA,YACA,QACY;AACZ,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO,KAAK,YAAY,YAAY,4FAAiB,CAAC;AACtD,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,OAAO,eAAe,IAAI,OAAO,YAAY,MAAM;AAAA,IACnD,YAAY,oBAAoB,IAAI,YAAY,YAAY,MAAM;AAAA,IAClE,QAAQ,gBAAgB,IAAI,QAAQ,YAAY,MAAM;AAAA,EACxD;AACF;AAEA,SAAS,eACP,KACA,YACA,QACW;AACX,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,MACL,YAAY,YAAY,oHAA0B;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,MACZ,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,oBACP,KACA,YACA,QACsB;AACtB,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI,IAAI,YAAY,QAAW;AAC7B,iBAAa;AAAA,EACf,WAAW,SAAS,IAAI,OAAO,GAAG;AAChC,iBAAa,IAAI;AAAA,EACnB,OAAO;AACL,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,iBAAa;AAAA,EACf;AAEA,MAAI;AACJ,MAAI,IAAI,iBAAiB,QAAW;AAClC,sBAAkB;AAAA,EACpB,WAAW,SAAS,IAAI,YAAY,GAAG;AACrC,sBAAkB,IAAI;AAAA,EACxB,OAAO;AACL,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,sBAAkB;AAAA,EACpB;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,cAAc;AAAA,QACZ,YAAY;AAAA,QACZ,KAAK,QAAQ;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,cAAc;AAAA,QACZ,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,gBAAgB;AAAA,QACd,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe;AAAA,QACb,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,QACpB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,kBAAkB;AAAA,QAChB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,QACpB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,2BAA2B;AAAA,QACzB,iBAAiB;AAAA,QACjB,KAAK,aAAa;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gBACP,KACA,YACA,QACkB;AAClB,QAAM,OAAO,cAAc;AAC3B,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AACA,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,WAAO;AAAA,MACL,YAAY,YAAY,qHAA2B;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,kBAAkB;AAAA,MAChB,IAAI;AAAA,MACJ,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WACP,OACA,UACA,OACA,YACA,QACQ;AACR,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,GAAG;AACxD,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,YAAY,YAAY,GAAG,KAAK,6FAAkB;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBACP,OACA,UACA,OACA,YACA,QACU;AACV,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AAC3E,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,YAAY,YAAY,GAAG,KAAK,yGAAoB;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YACP,OACA,UACA,OACA,YACA,QACS;AACT,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,YAAY,YAAY,GAAG,KAAK,6FAAkB;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WACP,OACA,UACA,OACA,YACA,QACQ;AACR,MAAI,UAAU,WAAW,UAAU,aAAa,UAAU,SAAS;AACjE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,GAAG,KAAK;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBACP,OACA,UACA,OACA,YACA,QACsB;AACtB,MAAI,UAAU,aAAa,UAAU,SAAS;AAC5C,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,GAAG,KAAK;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAAc,SAAwB;AACzD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,cAAcC,QAAyB;AAC9C,MAAIA,UAAS,OAAOA,WAAU,YAAY,UAAUA,QAAO;AACzD,WAAQA,OAA4B,SAAS;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,YAAYA,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;ACheA,SAAS,YAAAC,kBAAgB;AACzB,OAAOC,YAAU;;;ACDjB,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,WAAU;;;ACDjB,SAAS,UAAAC,eAAc;;;ACAvB,SAAS,UAAAC,SAAQ,WAAAC,gBAAe;AAChC,OAAOC,WAAU;AAEjB,OAAO,QAAQ;AAEf,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAYD,eAAsB,aACpB,MACA,UAA+B,CAAC,GACb;AACnB,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAE,MAAMC,QAAO,IAAI,GAAI;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,oBAAI,IAAI;AAAA,IACzB,GAAG;AAAA,IACH,GAAI,QAAQ,cAAc,CAAC;AAAA,EAC7B,CAAC;AACD,QAAM,aAAa,QAAQ,YAAY,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,KAAK,CAAC;AAE3E,QAAM,KAAK,MAAM,MAAM,YAAY,YAAY,OAAO;AACtD,SAAO;AACT;AAEA,eAAsB,oBACpB,MACA,SACmB;AACnB,MAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,WAAO,CAAC;AAAA,EACV;AACA,SAAO,GAAG,QAAQ,OAAO;AAAA,IACvB,KAAK;AAAA,IACL,QAAQ,QAAQ,UAAU,CAAC;AAAA,IAC3B,WAAW;AAAA,IACX,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,eAAe,KACb,MACA,SACA,YACA,YACA,KACe;AACf,QAAM,QAAQ,MAAMF,SAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AAE5D,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAWC,MAAK,KAAK,SAAS,KAAK,IAAI;AAE7C,QAAI,KAAK,YAAY,GAAG;AACtB,UAAI,WAAW,IAAI,KAAK,IAAI,GAAG;AAC7B;AAAA,MACF;AACA,YAAM,KAAK,MAAM,UAAU,YAAY,YAAY,GAAG;AACtD;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,GAAG;AACjB,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,MAAMA,MAAK,QAAQ,KAAK,IAAI,EAAE,YAAY;AAChD,YAAI,CAAC,WAAW,SAAS,GAAG,GAAG;AAC7B;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAK,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;AAEA,eAAeC,QAAO,QAAkC;AACtD,MAAI;AACF,UAAMH,QAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClGA,SAAS,WAAAI,gBAAe;AACxB,OAAOC,WAAU;AAEjB,IAAM,cAAc;AASpB,eAAsB,mBACpB,WACsB;AACtB,QAAM,OAAO,MAAM,aAAa,SAAS;AACzC,QAAM,UAAU,KAAK,IAAI,CAAC,SAAS;AAAA,IACjC;AAAA,IACA,UAAUA,MAAK,KAAK,KAAK,SAAS;AAAA,IAClC,WAAWA,MAAK,KAAK,KAAK,UAAU;AAAA,IACpC,cAAcA,MAAK,KAAK,KAAK,aAAa;AAAA,EAC5C,EAAE;AACF,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,cAAc,EAAE,GAAG,CAAC;AAC1D;AAEA,eAAe,aAAa,WAAsC;AAChE,MAAI;AACF,UAAM,QAAQ,MAAMD,SAAQ,WAAW,EAAE,eAAe,KAAK,CAAC;AAC9D,WAAO,MACJ,OAAO,CAAC,SAAS,KAAK,YAAY,CAAC,EACnC,IAAI,CAAC,SAAS,KAAK,IAAI,EACvB,OAAO,CAAC,SAAS,YAAY,KAAK,KAAK,YAAY,CAAC,CAAC,EACrD,IAAI,CAAC,SAASC,MAAK,KAAK,WAAW,IAAI,CAAC;AAAA,EAC7C,SAASC,QAAO;AACd,QAAI,mBAAmBA,MAAK,GAAG;AAC7B,aAAO,CAAC;AAAA,IACV;AACA,UAAMA;AAAA,EACR;AACF;AAEA,SAAS,mBAAmBA,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;;;AFnCA,eAAsB,oBACpB,WACmB;AACnB,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAClD,SAAO,QAAQ,IAAI,CAAC,UAAU,MAAM,GAAG;AACzC;AAEA,eAAsB,iBAAiB,WAAsC;AAC3E,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAClD,SAAO,eAAe,QAAQ,IAAI,CAAC,UAAU,MAAM,QAAQ,CAAC;AAC9D;AAOA,eAAsB,qBACpB,WACmB;AACnB,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAClD,SAAO,eAAe,QAAQ,IAAI,CAAC,UAAU,MAAM,YAAY,CAAC;AAClE;AAEA,eAAsB,uBACpB,QACmB;AACnB,SAAO,aAAa,QAAQ,EAAE,YAAY,CAAC,SAAS,MAAM,EAAE,CAAC;AAC/D;AAEA,eAAsB,wBACpB,SACmB;AACnB,SAAO,aAAa,SAAS,EAAE,YAAY,CAAC,SAAS,QAAQ,OAAO,EAAE,CAAC;AACzE;AAEA,eAAsB,yBACpB,UACmB;AACnB,SAAO,aAAa,UAAU,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC;AACxD;AAEA,eAAsB,qBACpB,QACA,SACA,UACwB;AACxB,QAAM,CAAC,IAAI,KAAK,EAAE,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtC,uBAAuB,MAAM;AAAA,IAC7B,wBAAwB,OAAO;AAAA,IAC/B,yBAAyB,QAAQ;AAAA,EACnC,CAAC;AACD,SAAO,EAAE,IAAI,KAAK,GAAG;AACvB;AAEA,eAAe,eAAe,OAAoC;AAChE,QAAM,WAAqB,CAAC;AAC5B,aAAW,QAAQ,OAAO;AACxB,QAAI,MAAMC,QAAO,IAAI,GAAG;AACtB,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAeA,QAAO,QAAkC;AACtD,MAAI;AACF,UAAMC,QAAO,MAAM;AACnB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AGnFA,IAAM,0BACJ;AACF,IAAM,+BACJ;AAEK,SAAS,2BAA2B,MAAwB;AACjE,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,KAAK,SAAS,uBAAuB,GAAG;AAC1D,UAAM,KAAK,MAAM,CAAC;AAClB,QAAI,IAAI;AACN,UAAI,KAAK,EAAE;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,8BAA8B,MAAsB;AAClE,SAAO,KACJ,MAAM,OAAO,EACb,OAAO,CAAC,SAAS,CAAC,6BAA6B,KAAK,IAAI,CAAC,EACzD,KAAK,IAAI;AACd;;;AJHA,eAAsB,mBACpB,MACA,QACwB;AACxB,QAAM,gBAAgB,YAAY,MAAM,QAAQ,cAAc;AAC9D,QAAM,SAASC,MAAK,KAAK,eAAe,IAAI;AAC5C,QAAM,UAAUA,MAAK,KAAK,eAAe,KAAK;AAC9C,QAAM,SAASA,MAAK,KAAK,eAAe,IAAI;AAE5C,QAAM,CAAC,SAAS,UAAU,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IACrD,uBAAuB,MAAM;AAAA,IAC7B,wBAAwB,OAAO;AAAA,IAC/B,yBAAyB,MAAM;AAAA,EACjC,CAAC;AAED,QAAM,QAAuB;AAAA,IAC3B,KAAK,oBAAI,IAAY;AAAA,IACrB,WAAW,oBAAI,IAAyB;AAAA,IACxC,OAAO,EAAE,IAAI,SAAS,KAAK,UAAU,IAAI,QAAQ;AAAA,EACnD;AAEA,QAAM,mBAAmB,SAAS,KAAK;AACvC,QAAM,mBAAmB,UAAU,KAAK;AACxC,QAAM,mBAAmB,SAAS,KAAK;AAEvC,SAAO;AACT;AAEA,eAAe,mBACb,OACA,OACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,+BAA2B,IAAI,EAAE,QAAQ,CAAC,OAAO,OAAO,OAAO,IAAI,IAAI,CAAC;AAAA,EAC1E;AACF;AAEA,SAAS,OAAO,OAAsB,IAAY,MAAoB;AACpE,QAAM,IAAI,IAAI,EAAE;AAChB,QAAM,UAAU,MAAM,UAAU,IAAI,EAAE,KAAK,oBAAI,IAAY;AAC3D,UAAQ,IAAI,IAAI;AAChB,QAAM,UAAU,IAAI,IAAI,OAAO;AACjC;;;AK1DA,IAAM,cAA0B,CAAC,QAAQ,MAAM,MAAM,MAAM,OAAO,IAAI;AAEtE,IAAM,qBAAqD;AAAA,EACzD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AACP;AAEA,IAAM,oBAAoD;AAAA,EACxD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AACP;AAEO,SAAS,WAAW,MAAc,QAA4B;AACnE,QAAM,UAAU,mBAAmB,MAAM;AACzC,QAAM,UAAU,KAAK,MAAM,OAAO;AAClC,SAAO,OAAO,WAAW,CAAC,CAAC;AAC7B;AAEO,SAAS,cAAc,MAAwB;AACpD,QAAM,MAAgB,CAAC;AACvB,cAAY,QAAQ,CAAC,WAAW;AAC9B,QAAI,KAAK,GAAG,WAAW,MAAM,MAAM,CAAC;AAAA,EACtC,CAAC;AACD,SAAO,OAAO,GAAG;AACnB;AAEO,SAAS,kBACd,MACA,UACU;AACV,QAAM,UAAoB,CAAC;AAC3B,aAAW,UAAU,UAAU;AAC7B,UAAM,aAAa,KAAK,MAAM,kBAAkB,MAAM,CAAC,KAAK,CAAC;AAC7D,eAAW,aAAa,YAAY;AAClC,UAAI,CAAC,UAAU,WAAW,MAAM,GAAG;AACjC,gBAAQ,KAAK,SAAS;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO,OAAO;AACvB;AAEA,SAAS,OAAO,QAA4B;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AACnC;AAEA,SAAS,UAAU,OAAe,QAAiC;AACjE,QAAM,UAAU,mBAAmB,MAAM;AACzC,QAAM,SAAS,IAAI,OAAO,QAAQ,MAAM;AACxC,SAAO,OAAO,KAAK,KAAK;AAC1B;;;ACtDA,IAAM,aAAa;AAEZ,SAAS,cAAc,IAAuB;AACnD,QAAM,QAAQ,GAAG,MAAM,OAAO;AAC9B,QAAM,WAAsB,CAAC;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC,KAAK;AACzB,UAAM,QAAQ,KAAK,MAAM,UAAU;AACnC,QAAI,CAAC,MAAO;AACZ,UAAM,aAAa,MAAM,CAAC;AAC1B,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,CAAC,cAAc,CAAC,MAAO;AAC3B,aAAS,KAAK;AAAA,MACZ,OAAO,WAAW;AAAA,MAClB,OAAO,MAAM,KAAK;AAAA,MAClB,MAAM,IAAI;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,IAAoC;AACpE,QAAM,QAAQ,GAAG,MAAM,OAAO;AAC9B,QAAM,WAAW,cAAc,EAAE,EAAE,OAAO,CAAC,YAAY,QAAQ,UAAU,CAAC;AAC1E,QAAM,WAAW,oBAAI,IAAuB;AAE5C,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,UAAU,SAAS,CAAC;AAC1B,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,SAAS,IAAI,CAAC;AAC3B,UAAM,YAAY,QAAQ,OAAO;AACjC,UAAM,WAAW,MAAM,QAAQ,MAAM,SAAS,KAAK;AACnD,UAAM,OACJ,aAAa,UACT,MAAM,MAAM,YAAY,GAAG,OAAO,EAAE,KAAK,IAAI,IAC7C;AAEN,aAAS,IAAI,QAAQ,MAAM,KAAK,GAAG;AAAA,MACjC,OAAO,QAAQ,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACdA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,0BACJ;AACF,IAAM,yBACJ;AACF,IAAM,uBACJ;AACF,IAAM,qBAAqB;AAE3B,IAAM,mBAAmB;AACzB,IAAM,mBAAmB,oBAAI,IAAgB,CAAC,MAAM,MAAM,MAAM,IAAI,CAAC;AAE9D,SAAS,UAAU,IAAY,MAA0B;AAC9D,QAAM,WAAW,cAAc,EAAE;AACjC,QAAM,KAAK,SAAS,KAAK,CAAC,YAAY,QAAQ,UAAU,CAAC;AACzD,QAAM,SAAS,IAAI,MAAM,MAAM,UAAU,IAAI,CAAC;AAE9C,QAAM,WAAW,kBAAkB,EAAE;AACrC,QAAM,eAAe,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,CAAC,CAAC;AACxD,QAAM,YAAY,SAAS,IAAI,gBAAgB;AAC/C,QAAM,UAAU,YAAY,UAAU,KAAK,MAAM,OAAO,IAAI,CAAC;AAC7D,QAAM,YAAY,WAAW,aAAa;AAE1C,QAAM,MAAkB,CAAC;AACzB,QAAM,qBAAgD,CAAC;AACvD,QAAM,yBAAwD,CAAC;AAE/D,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,WAAW,QAAQ,CAAC,KAAK;AAC/B,UAAM,aAAa,YAAY;AAE/B,UAAM,aAAa,SAAS,MAAM,UAAU;AAC5C,QAAI,YAAY;AACd,YAAM,KAAK,WAAW,CAAC;AACvB,YAAM,WAAW,WAAW,CAAC;AAC7B,YAAM,OAAO,WAAW,CAAC;AACzB,UAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAM;AAC/B,UAAI,KAAK;AAAA,QACP;AAAA,QACA;AAAA,QACA,MAAM,KAAK,KAAK;AAAA,QAChB,MAAM;AAAA,MACR,CAAC;AACD;AAAA,IACF;AAEA,UAAM,mBAAmB,SAAS,MAAM,uBAAuB;AAC/D,QAAI,kBAAkB;AACpB,YAAM,KAAK,iBAAiB,CAAC;AAC7B,YAAM,WAAW,iBAAiB,CAAC;AACnC,YAAM,OAAO,iBAAiB,CAAC;AAC/B,UAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAM;AAC/B,UAAI,CAAC,iBAAiB,IAAI,QAAsB,GAAG;AACjD,+BAAuB,KAAK;AAAA,UAC1B;AAAA,UACA;AAAA,UACA,MAAM,KAAK,KAAK;AAAA,UAChB,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,UAAM,kBAAkB,SAAS,MAAM,sBAAsB;AAC7D,QAAI,iBAAiB;AACnB,YAAM,KAAK,gBAAgB,CAAC;AAC5B,YAAM,OAAO,gBAAgB,CAAC;AAC9B,UAAI,CAAC,MAAM,CAAC,KAAM;AAClB,yBAAmB,KAAK;AAAA,QACtB;AAAA,QACA,MAAM,KAAK,KAAK;AAAA,QAChB,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,SAAqB;AAAA,IACzB;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,kBAAkB,EAAE;AAAA,EACpC;AACA,MAAI,QAAQ;AACV,WAAO,SAAS;AAAA,EAClB;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,IAAgC;AAChE,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,GAAG,SAAS,oBAAoB,GAAG;AACrD,UAAM,MAAM,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;AAAA,EACpC;AAEA,QAAM,MAAgB,CAAC;AACvB,QAAM,gBAA0B,CAAC;AACjC,MAAI,UAAU;AAEd,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,GAAG;AACrB,oBAAc,KAAK,SAAS;AAC5B;AAAA,IACF;AACA,UAAM,SAAS,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC;AAC1D,eAAW,SAAS,QAAQ;AAC1B,UAAI,MAAM,WAAW,GAAG;AACtB,sBAAc,KAAK,SAAS;AAC5B;AAAA,MACF;AACA,UAAI,UAAU,QAAQ;AACpB,kBAAU;AACV;AAAA,MACF;AACA,UAAI,mBAAmB,KAAK,KAAK,GAAG;AAClC,YAAI,KAAK,KAAK;AACd;AAAA,MACF;AACA,oBAAc,KAAK,KAAK;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,KAAKC,QAAO,GAAG;AAAA,IACf,eAAeA,QAAO,aAAa;AAAA,IACnC;AAAA,EACF;AACF;AAEA,SAASA,QAAO,QAA4B;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AACnC;;;AC/KA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,WAAU;;;ACDjB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;AAOpB,SAAS,aAAa,QAAgB,KAA4B;AACvE,QAAM,SAAmB,CAAC;AAC1B,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,UAAU,IAAI,WAAW,MAAM;AACrC,QAAM,UAAU,IAAI,2BAA2B;AAC/C,QAAM,SAAS,IAAI,OAAO,SAAS,OAAO;AAE1C,MAAI;AACF,UAAM,kBAAkB,OAAO,MAAM,MAAM;AAC3C,oBAAgB,MAAM;AACtB,WAAO,EAAE,iBAAiB,OAAO;AAAA,EACnC,SAASC,QAAO;AACd,WAAO,KAAKC,aAAYD,MAAK,CAAC;AAC9B,WAAO,EAAE,iBAAiB,MAAM,OAAO;AAAA,EACzC;AACF;AAEA,SAASC,aAAYD,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;;;AC9BA,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,aAAa;AACnB,IAAM,YAAY;AAoCX,SAAS,sBACd,MACA,KACqB;AACrB,QAAM,EAAE,iBAAiB,OAAO,IAAI,aAAa,MAAM,GAAG;AAC1D,MAAI,CAAC,iBAAiB;AACpB,WAAO,EAAE,UAAU,MAAM,OAAO;AAAA,EAClC;AAEA,QAAM,UAAU,gBAAgB;AAChC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,UAAU,EAAE,KAAK,aAAa,CAAC,GAAG,WAAW,CAAC,EAAE;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cAAc,gBAAgB,QAAQ,IAAI;AAChD,QAAM,YAAY,qBAAqB,SAAS,WAAW;AAC3D,SAAO;AAAA,IACL,UAAU;AAAA,MACR;AAAA,MACA,aAAa,QAAQ;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,UAA4C;AAC7E,SAAO,SAAS,UAAU,IAAI,CAAC,aAAa;AAC1C,UAAM,UAAU,SAAS,KAAK,OAAO,CAAC,QAAQ,YAAY,KAAK,GAAG,CAAC;AACnE,UAAM,QAAQ,SAAS,KAAK,OAAO,CAAC,QAAQ,UAAU,KAAK,GAAG,CAAC;AAC/D,UAAM,QAAQE,QAAO,SAAS,KAAK,OAAO,CAAC,QAAQ,UAAU,KAAK,GAAG,CAAC,CAAC;AAEvE,UAAM,cAAc,oBAAI,IAAY;AACpC,aAAS,KAAK,QAAQ,CAAC,QAAQ;AAC7B,UAAI,UAAU,KAAK,GAAG,KAAK,WAAW,KAAK,GAAG,KAAK,UAAU,KAAK,GAAG,GAAG;AACtE,oBAAY,IAAI,GAAG;AAAA,MACrB;AAAA,IACF,CAAC;AAED,eAAW,QAAQ,SAAS,OAAO;AACjC,iBAAW,QAAQ,iBAAiB,IAAI,GAAG;AACzC,mBAAW,MAAM,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAC1D,mBAAW,MAAM,KAAK,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAC3D,mBAAW,MAAM,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAAA,MAC5D;AAAA,IACF;AAEA,UAAM,OAAqB;AAAA,MACzB,KAAK,SAAS;AAAA,MACd,aAAa,SAAS,eAAe;AAAA,MACrC,cAAc,SAAS;AAAA,MACvB,MAAM,SAAS;AAAA,MACf;AAAA,MACA,aAAa,MAAM,KAAK,WAAW,EAAE,KAAK;AAAA,IAC5C;AAEA,QAAI,SAAS,SAAS,QAAW;AAC/B,WAAK,OAAO,SAAS;AAAA,IACvB;AACA,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,SAAS,QAAQ,CAAC;AACxB,UAAI,QAAQ;AACV,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AACA,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,MAAM;AACR,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,qBACP,SACA,aACgB;AAChB,QAAM,YAA4B,CAAC;AAEnC,aAAW,SAAS,QAAQ,UAAU;AACpC,QAAI,MAAM,UAAU;AAClB,gBAAU,KAAK,kBAAkB,MAAM,UAAU,aAAa,CAAC,CAAC,CAAC;AAAA,IACnE;AACA,QAAI,MAAM,MAAM;AACd,YAAM,WAAW,gBAAgB,MAAM,KAAK,IAAI;AAChD,iBAAW,aAAa,MAAM,KAAK,UAAU;AAC3C,YAAI,UAAU,UAAU;AACtB,oBAAU;AAAA,YACR,kBAAkB,UAAU,UAAU,aAAa,QAAQ;AAAA,UAC7D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,UACA,aACA,UACc;AACd,QAAM,OAAO,CAAC,GAAG,aAAa,GAAG,UAAU,GAAG,gBAAgB,SAAS,IAAI,CAAC;AAC5E,QAAM,OACJ,SAAS,SAAS,SAAS,IAAI,oBAAoB;AACrD,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf;AAAA,IACA,MAAM,SAAS,UAAU;AAAA,IACzB;AAAA,IACA,OAAO,SAAS;AAAA,EAClB;AACF;AAEA,SAAS,gBAAgB,MAAyC;AAChE,SAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,KAAK,QAAQ,MAAM,EAAE,CAAC;AACrD;AAEA,SAAS,iBAAiB,MAA+B;AACvD,QAAM,QAAkB,CAAC;AACzB,MAAI,KAAK,MAAM;AACb,UAAM,KAAK,KAAK,IAAI;AAAA,EACtB;AACA,MAAI,KAAK,WAAW,SAAS;AAC3B,UAAM,KAAK,KAAK,UAAU,OAAO;AAAA,EACnC;AACA,MAAI,KAAK,WAAW,MAAM;AACxB,eAAW,OAAO,KAAK,UAAU,MAAM;AACrC,iBAAW,QAAQ,IAAI,OAAO;AAC5B,cAAM,KAAK,KAAK,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAASA,QAAO,QAA4B;AAC1C,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC;AACnC;;;AF1LO,IAAMC,aAAY;AAClB,IAAM,wBAAwB;AAC9B,IAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsBO,SAAS,sBAAsB,MAAwB;AAC5D,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,SAAS,KAAK,SAAS,qBAAqB,GAAG;AACxD,UAAM,SAAS,MAAM,CAAC;AACtB,QAAI,QAAQ;AACV,UAAI,IAAI,MAAM,MAAM,EAAE;AAAA,IACxB;AAAA,EACF;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;AAEA,eAAsB,8BACpB,eACsB;AACtB,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AAEA,eAAW,YAAY,SAAS,WAAW;AACzC,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAID,WAAU,KAAK,GAAG,GAAG;AACvB,gBAAM,IAAI,GAAG;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,oCACpB,eACmC;AACnC,QAAM,UAAU,oBAAI,IAAyB;AAC7C,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AAEA,eAAW,YAAY,SAAS,WAAW;AACzC,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAI,CAACD,WAAU,KAAK,GAAG,GAAG;AACxB;AAAA,QACF;AACA,cAAM,UAAU,QAAQ,IAAI,GAAG,KAAK,oBAAI,IAAY;AACpD,gBAAQ,IAAI,IAAI;AAChB,gBAAQ,IAAI,KAAK,OAAO;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,wBACpB,MACA,OACA,cACgC;AAChC,QAAM,OAAO,oBAAI,IAAyB;AAC1C,QAAM,kBAAkB,eAAe,KAAK;AAC5C,QAAM,yBAAyB,eAAe,YAAY;AAC1D,QAAM,qBAAqB,MAAM;AAAA,IAC/B,oBAAI,IAAI,CAAC,GAAG,iCAAiC,GAAG,sBAAsB,CAAC;AAAA,EACzE;AACA,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,cAAc;AAAA,QACd,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAkB,CAAC;AACvB,MAAI;AACF,YAAQ,MAAM,oBAAoB,MAAM;AAAA,MACtC,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,CAAC;AAAA,EACH,SAASE,QAAO;AACd,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,cAAc;AAAA,QACd,kBAAkB;AAAA,MACpB;AAAA,MACA,OAAOC,aAAYD,MAAK;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAAA,IAC5B,IAAI,IAAI,MAAM,IAAI,CAAC,SAASE,MAAK,UAAU,IAAI,CAAC,CAAC;AAAA,EACnD;AACA,aAAW,QAAQ,iBAAiB;AAClC,UAAM,OAAO,MAAMH,UAAS,MAAM,OAAO;AACzC,UAAM,QAAQ,sBAAsB,IAAI;AACxC,QAAI,MAAM,WAAW,GAAG;AACtB;AAAA,IACF;AACA,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,IAAI,IAAI,KAAK,oBAAI,IAAY;AAClD,cAAQ,IAAI,IAAI;AAChB,WAAK,IAAI,MAAM,OAAO;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,cAAc;AAAA,MACd,kBAAkB,gBAAgB;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,gBACd,OACA,MACY;AACZ,QAAM,cAAc,cAAc,KAAK;AACvC,QAAM,aAAuC,CAAC;AAC9C,QAAM,aAAuB,CAAC;AAC9B,MAAI,UAAU;AAEd,aAAW,QAAQ,aAAa;AAC9B,UAAM,QAAQ,KAAK,IAAI,IAAI;AAC3B,UAAM,cAAc,QAAQ,cAAc,KAAK,IAAI,CAAC;AACpD,eAAW,IAAI,IAAI;AACnB,QAAI,YAAY,WAAW,GAAG;AAC5B,iBAAW,KAAK,IAAI;AAAA,IACtB,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,YAAY;AAAA,IACnB;AAAA,IACA,SAAS,WAAW;AAAA,IACpB;AAAA,IACA,MAAM;AAAA,EACR;AACF;AAEA,SAAS,cAAc,QAAoC;AACzD,SAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AACtE;AAEA,SAAS,eAAe,OAA2B;AACjD,SAAO,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AAC1E;AAEA,SAASE,aAAYD,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;;;AG7MA,SAAS,YAAAG,iBAAgB;AACzB,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAI9B,eAAsB,qBAAsC;AAC1D,MAEE,QAAsB,SAAS,GAC/B;AACA,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,cAAc,uBAAuB;AAC3C,UAAM,MAAM,MAAMF,UAAS,aAAa,OAAO;AAC/C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,WAAO,QAAQ,SAAS,IAAI,UAAU;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,yBAAiC;AACxC,QAAM,OAAO,YAAY;AACzB,QAAM,WAAW,KAAK,WAAW,OAAO,IAAIE,eAAc,IAAI,IAAI;AAClE,SAAOD,MAAK,QAAQA,MAAK,QAAQ,QAAQ,GAAG,oBAAoB;AAClE;;;AC7BA,SAAS,YAAAE,iBAAgB;AACzB,OAAOC,YAAU;;;ACDjB,OAAOC,YAAU;AAEjB,SAAS,SAASC,kBAAiB;AAI5B,SAAS,wBACd,MACA,MACyB;AACzB,QAAM,MAAMC,OAAK,QAAQ,IAAI,EAAE,YAAY;AAC3C,MAAI,QAAQ,SAAS;AACnB,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AACA,SAAOC,WAAU,IAAI;AACvB;;;ADIA,IAAM,yBAAoE;AAAA,EACxE,EAAE,SAAS,qBAAqB,OAAO,aAAa;AAAA,EACpD,EAAE,SAAS,wBAAwB,OAAO,gBAAgB;AAAA,EAC1D,EAAE,SAAS,iBAAiB,OAAO,WAAW;AAAA,EAC9C;AAAA,IACE,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,MACA,QACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,gBAAgB,YAAY,MAAM,QAAQ,cAAc;AAE9D,SAAO,KAAK,GAAI,MAAM,oBAAoBC,OAAK,KAAK,eAAe,IAAI,CAAC,CAAE;AAC1E,SAAO,KAAK,GAAI,MAAM,qBAAqBA,OAAK,KAAK,eAAe,KAAK,CAAC,CAAE;AAC5E,SAAO,KAAK,GAAI,MAAM,sBAAsBA,OAAK,KAAK,eAAe,IAAI,CAAC,CAAE;AAC5E,QAAM,gBAAgB,MAAM,mBAAmB,MAAM,MAAM;AAC3D,SAAO,KAAK,GAAG,6BAA6B,aAAa,CAAC;AAE1D,SAAO;AACT;AAEA,eAAe,oBAAoB,QAAkC;AACnE,QAAM,QAAQ,MAAM,uBAAuB,MAAM;AACjD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,aAAa,kBAAkB,MAAM;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,2BAA2B,IAAI;AACnD,WAAO,KAAK,GAAG,4BAA4B,aAAa,MAAM,IAAI,CAAC;AACnE,QAAI;AACF,8BAAwB,MAAM,8BAA8B,IAAI,CAAC;AAAA,IACnE,SAASC,QAAO;AACd,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,wGAAwB,IAAI,KAAKC,aAAYD,MAAK,CAAC;AAAA,UACnD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,qBAAqB,SAAmC;AACrE,QAAM,QAAQ,MAAM,wBAAwB,OAAO;AACnD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMD,UAAS,MAAM,OAAO;AACzC,UAAM,aAAa,kBAAkB,MAAM;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,2BAA2B,IAAI;AACnD,WAAO,KAAK,GAAG,4BAA4B,aAAa,MAAM,KAAK,CAAC;AACpE,QAAI;AACJ,QAAI;AACF,YAAM,wBAAwB,MAAM,8BAA8B,IAAI,CAAC;AAAA,IACzE,SAASC,QAAO;AACd,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,yGAAyB,IAAI,KAAKC,aAAYD,MAAK,CAAC;AAAA,UACpD;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,CAAC,WAAW,GAAG,GAAG;AACpB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,sBAAsB,UAAoC;AACvE,QAAM,QAAQ,MAAM,yBAAyB,QAAQ;AACrD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMD,UAAS,MAAM,OAAO;AACzC,UAAM,aAAa,kBAAkB,MAAM;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,UACxC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,cAAc,2BAA2B,IAAI;AACnD,WAAO,KAAK,GAAG,4BAA4B,aAAa,MAAM,IAAI,CAAC;AACnE,WAAO,KAAK,GAAG,QAAQ,MAAM,IAAI,CAAC;AAAA,EACpC;AAEA,SAAO;AACT;AAEO,SAAS,QAAQ,MAAc,MAAuB;AAC3D,QAAM,SAAkB,CAAC;AACzB,aAAW,EAAE,SAAS,MAAM,KAAK,wBAAwB;AACvD,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,wFAAuB,KAAK;AAAA,UAC5B;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,4BACP,KACA,MACA,MACS;AACT,QAAM,SAAkB,CAAC;AACzB,MAAI,IAAI,WAAW,GAAG;AACpB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,qGAAoC,IAAI;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,MAAI,IAAI,SAAS,GAAG;AAClB,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,yIAA0C,IAAI;AAAA,UAC5C;AAAA,QACF,CAAC;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,EAAE,IAAI;AACb,MAAI,MAAM,CAAC,GAAG,WAAW,GAAG,IAAI,GAAG,GAAG;AACpC,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,sEAA8B,IAAI,iDAAc,EAAE;AAAA,QAClD;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,EAAE;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,6BAA6B,eAE1B;AACV,QAAM,SAAkB,CAAC;AACzB,aAAW,CAAC,IAAI,KAAK,KAAK,cAAc,UAAU,QAAQ,GAAG;AAC3D,QAAI,MAAM,QAAQ,GAAG;AACnB;AAAA,IACF;AACA,UAAM,cAAc,MAAM,KAAK,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AACvE,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,qHAA2B,EAAE,KAAK,YAAY;AAAA,UAC5C;AAAA,QACF,CAAC;AAAA,QACD;AAAA,QACA,YAAY,CAAC;AAAA,QACb;AAAA,QACA,CAAC,EAAE;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,KAAuC;AACzD,SAAO,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,SAAS;AACjE;AAEA,SAASE,aAAYD,QAAwB;AAC3C,MAAIA,kBAAiB,OAAO;AAC1B,WAAOA,OAAM;AAAA,EACf;AACA,SAAO,OAAOA,MAAK;AACrB;AAEA,SAAS,MACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAME,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;AE/VA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,YAAU;AAOjB,IAAM,aAAa;AACnB,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAE1B,eAAsB,eACpB,MACA,QACkB;AAClB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,QAAQ,MAAM,oBAAoB,SAAS;AACjD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAYC,OAAK,KAAK,MAAM,UAAU;AAC5C,QAAI;AACJ,QAAI;AACF,aAAO,MAAMC,UAAS,WAAW,OAAO;AAAA,IAC1C,SAASC,QAAO;AACd,UAAIC,oBAAmBD,MAAK,GAAG;AAC7B,eAAO;AAAA,UACLE;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAMF;AAAA,IACR;AAEA,UAAM,aAAa,WAAW,KAAK,IAAI;AACvC,UAAM,mBAAmB,eAAe,KAAK,IAAI;AACjD,UAAM,YAAY,eAAe,KAAK,IAAI;AAC1C,QAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,WAAW;AAClD,aAAO;AAAA,QACLE;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,uBAAuB,kBAAkB,KAAK,IAAI;AACxD,UAAM,gBAAgB,kBAAkB,KAAK,IAAI;AACjD,QAAI,yBAAyB,eAAe;AAC1C,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASD,oBAAmBD,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;AAEA,SAASE,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;AC9GA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,YAAU;AAUjB,IAAMC,aAAY;AAElB,eAAsB,mBACpB,MACA,QACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AAEtD,QAAM,YAAY,MAAM,iBAAiB,SAAS;AAClD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAE1D,QAAM,UAAU,oBAAI,IAAyB;AAE7C,QAAM,yBAAyB,WAAW,OAAO;AACjD,QAAM,6BAA6B,eAAe,OAAO;AACzD,QAAM,gBAAgB,MAAM,mBAAmB,MAAM,MAAM;AAC3D,aAAW,CAAC,IAAI,KAAK,KAAK,cAAc,UAAU,QAAQ,GAAG;AAC3D,eAAW,QAAQ,OAAO;AACxB,eAAS,SAAS,IAAI,IAAI;AAAA,IAC5B;AAAA,EACF;AAEA,aAAW,CAAC,IAAI,KAAK,KAAK,QAAQ,QAAQ,GAAG;AAC3C,QAAI,MAAM,QAAQ,GAAG;AACnB;AAAA,IACF;AACA,UAAM,SAAS,MAAM,KAAK,KAAK,EAAE,KAAK;AACtC,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,wDAAgB,EAAE,KAAK,eAAe,QAAQ,IAAI,CAAC;AAAA,QACnD;AAAA,QACA,OAAO,CAAC;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,yBACb,OACA,KACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMC,UAAS,MAAM,OAAO;AACzC,UAAM,SAAS,UAAU,MAAM,IAAI;AACnC,QAAI,OAAO,QAAQ;AACjB,eAAS,KAAK,OAAO,QAAQ,IAAI;AAAA,IACnC;AACA,WAAO,IAAI,QAAQ,CAAC,OAAO,SAAS,KAAK,GAAG,IAAI,IAAI,CAAC;AAAA,EACvD;AACF;AAEA,eAAe,6BACb,OACA,KACe;AACf,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMA,UAAS,MAAM,OAAO;AACzC,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AACA,eAAW,YAAY,SAAS,WAAW;AACzC,iBAAW,OAAO,SAAS,MAAM;AAC/B,YAAIF,WAAU,KAAK,GAAG,GAAG;AACvB,mBAAS,KAAK,KAAK,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,SACP,KACA,IACA,MACM;AACN,QAAM,UAAU,IAAI,IAAI,EAAE,KAAK,oBAAI,IAAY;AAC/C,UAAQ,IAAI,IAAI;AAChB,MAAI,IAAI,IAAI,OAAO;AACrB;AAEA,SAAS,eAAe,OAAiB,MAAsB;AAC7D,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,UAAM,WAAWG,OAAK,SAAS,MAAM,IAAI;AACzC,WAAO,SAAS,SAAS,IAAI,WAAW;AAAA,EAC1C,CAAC,EACA,KAAK,IAAI;AACd;AAEA,SAASF,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;ACjIA,SAAS,YAAAG,iBAAgB;AASzB,IAAM,gBAAgB;AACtB,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAMC,aAAY;AAClB,IAAMC,eAAc;AAEpB,eAAsB,kBACpB,MACA,QACkB;AAClB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAElD,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,WAAW;AACjB,UAAM,SAAS;AACf,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,oHAA+B,OAAO,MAAM,QAAQ,4CAAc,QAAQ,KAAK,MAAM;AAAA,QACrF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,QAAI;AACJ,QAAI;AACF,aAAO,MAAMC,UAAS,MAAM,cAAc,OAAO;AAAA,IACnD,SAASC,QAAO;AACd,UAAIC,oBAAmBD,MAAK,GAAG;AAC7B,eAAO;AAAA,UACLF;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAME;AAAA,IACR;AACA,WAAO,KAAK,GAAG,wBAAwB,MAAM,MAAM,YAAY,CAAC;AAAA,EAClE;AAEA,SAAO;AACT;AAEO,SAAS,wBAAwB,MAAc,MAAuB;AAC3E,QAAM,SAAkB,CAAC;AAEzB,QAAM,aAAa,kBAAkB,MAAM;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO;AAAA,MACLF;AAAA,QACE;AAAA,QACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,MAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,yEAAuB,OAAO,KAAK,IAAI,KAAK,SAAS;AAAA,QACrD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,SAAS,YAAY;AAAA,IAAO,CAAC,QACnDD,aAAY,KAAK,GAAG;AAAA,EACtB;AACA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,+EAA6B,gBAAgB,KAAK,IAAI,CAAC;AAAA,QACvD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAA6B,CAAC;AACpC,MAAI,CAAC,SAAS,YAAa,kBAAiB,KAAK,SAAS;AAC1D,MAAI,SAAS,UAAU,WAAW,EAAG,kBAAiB,KAAK,UAAU;AACrE,MAAI,iBAAiB,SAAS,GAAG;AAC/B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,8GAA8B,iBAAiB;AAAA,UAC7C;AAAA,QACF,CAAC;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,YAAY,SAAS,WAAW;AACzC,QAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,0EAAwB,SAAS,IAAI;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,cAAwB,CAAC;AAC/B,UAAM,SAAS,SAAS,KAAK,OAAO,CAAC,QAAQF,WAAU,KAAK,GAAG,CAAC;AAChE,QAAI,OAAO,WAAW,GAAG;AACvB,kBAAY,KAAK,aAAQ;AAAA,IAC3B,WAAW,OAAO,SAAS,GAAG;AAC5B,kBAAY,KAAK,MAAM,OAAO,MAAM,6BAAS;AAAA,IAC/C;AACA,QAAI,YAAY,SAAS,GAAG;AAC1B,aAAO;AAAA,QACLE;AAAA,UACE;AAAA,UACA,0EAAwB,YAAY,KAAK,IAAI,CAAC,KAC5C,SAAS,IACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,YAAY,SAAS,WAAW;AACzC,UAAM,eAAyB,CAAC;AAChC,UAAM,WAAW,SAAS,MAAM,IAAI,CAAC,SAAS,KAAK,QAAQ,KAAK,CAAC;AACjE,QAAI,CAAC,SAAS,KAAK,CAAC,YAAY,cAAc,KAAK,OAAO,CAAC,GAAG;AAC5D,mBAAa,KAAK,OAAO;AAAA,IAC3B;AACA,QAAI,CAAC,SAAS,KAAK,CAAC,YAAY,aAAa,KAAK,OAAO,CAAC,GAAG;AAC3D,mBAAa,KAAK,MAAM;AAAA,IAC1B;AACA,QAAI,CAAC,SAAS,KAAK,CAAC,YAAY,aAAa,KAAK,OAAO,CAAC,GAAG;AAC3D,mBAAa,KAAK,MAAM;AAAA,IAC1B;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,qEAA6B,aAAa,KAAK,IAAI,CAAC,KAClD,SAAS,IACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASA,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;AAEA,SAASG,oBAAmBD,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;;;ACtOA,SAAS,YAAAE,iBAAgB;AAQzB,eAAsB,cACpB,MACA,QACkB;AAClB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,UAAU,MAAM,mBAAmB,SAAS;AAElD,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,WAAW;AACjB,UAAM,SAAS;AACf,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA,gHAA2B,OAAO,MAAM,QAAQ,4CAAc,QAAQ,KAAK,MAAM;AAAA,QACjF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,QAAI;AACJ,QAAI;AACF,aAAO,MAAMC,UAAS,MAAM,UAAU,OAAO;AAAA,IAC/C,SAASC,QAAO;AACd,UAAIC,oBAAmBD,MAAK,GAAG;AAC7B,eAAO;AAAA,UACLF;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAME;AAAA,IACR;AACA,WAAO;AAAA,MACL,GAAG;AAAA,QACD;AAAA,QACA,MAAM;AAAA,QACN,OAAO,WAAW,QAAQ;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,oBACd,MACA,MACA,kBACS;AACT,QAAM,SAAkB,CAAC;AAEzB,QAAM,SAAS,UAAU,MAAM,IAAI;AAEnC,QAAM,aAAa,kBAAkB,MAAM;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,WAAW,SAAS,GAAG;AACzB,WAAO;AAAA,MACLF;AAAA,QACE;AAAA,QACA,0EAAmB,WAAW,KAAK,IAAI,CAAC;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,IAAI,WAAW,GAAG;AAC3B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,OAAO,oBAAoB;AAC1C,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,kEAA0B,GAAG,EAAE;AAAA,QAC/B;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,GAAG,EAAE;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,OAAO,wBAAwB;AAC9C,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,+CAAsB,GAAG,EAAE,KAAK,GAAG,QAAQ;AAAA,QAC3C;AAAA,QACA;AAAA,QACA;AAAA,QACA,CAAC,GAAG,EAAE;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,WAAW,kBAAkB;AACtC,QAAI,CAAC,OAAO,SAAS,IAAI,OAAO,GAAG;AACjC,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,+FAAoB,OAAO;AAAA,UAC3B;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASA,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;AAEA,SAASG,oBAAmBD,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAQA,OAA4B,SAAS;AAC/C;;;AC3MA,SAAS,YAAAE,kBAAgB;AAazB,IAAMC,eAAc;AACpB,IAAMC,aAAY;AAElB,eAAsB,qBACpB,MACA,QACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,UAAU,YAAY,MAAM,QAAQ,QAAQ;AAClD,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AAEtD,QAAM,YAAY,MAAM,iBAAiB,SAAS;AAClD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAE1D,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAM,cAAc,oBAAI,IAAyB;AACjD,QAAM,gBAAgB,MAAM,mBAAmB,MAAM,MAAM;AAC3D,QAAM,cAAc,cAAc;AAElC,aAAW,QAAQ,WAAW;AAC5B,UAAM,OAAO,MAAMC,WAAS,MAAM,OAAO;AACzC,kBAAc,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAEvD,UAAM,SAAS,UAAU,MAAM,IAAI;AACnC,QAAI,OAAO,QAAQ;AACjB,cAAQ,IAAI,OAAO,MAAM;AAAA,IAC3B;AAEA,UAAM,QAAQ,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE;AAC1C,UAAM,QAAQ,CAAC,OAAO,aAAa,IAAI,EAAE,CAAC;AAE1C,QAAI,OAAO,QAAQ;AACjB,YAAM,UAAU,YAAY,IAAI,OAAO,MAAM,KAAK,oBAAI,IAAY;AAClE,YAAM,QAAQ,CAAC,OAAO,QAAQ,IAAI,EAAE,CAAC;AACrC,kBAAY,IAAI,OAAO,QAAQ,OAAO;AAAA,IACxC;AAEA,UAAM,eAAe,OAAO;AAC5B,QAAI,aAAa,MAAM,WAAW,GAAG;AACnC,aAAO;AAAA,QACLC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAI,aAAa,WAAW,aAAa,IAAI,SAAS,GAAG;AACvD,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,aAAa,cAAc,SAAS,GAAG;AACzC,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,8DAAsB,aAAa,cAAc;AAAA,cAC/C;AAAA,YACF,CAAC;AAAA,YACD;AAAA,YACA;AAAA,YACA;AAAA,YACA,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,iBAAa,IAAI,QAAQ,CAAC,OAAO;AAC/B,sBAAgB,IAAI,EAAE;AAAA,IACxB,CAAC;AAED,UAAM,qBAAqB,aAAa,IAAI;AAAA,MAC1C,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;AAAA,IAC7B;AACA,QAAI,mBAAmB,SAAS,GAAG;AACjC,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,kGAA4B,mBAAmB;AAAA,YAC7C;AAAA,UACF,CAAC;AAAA,UACD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,QAAQ,eAAe;AAChC,UAAM,OAAO,MAAMD,WAAS,MAAM,OAAO;AACzC,kBAAc,IAAI,EAAE,QAAQ,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC;AAEvD,UAAM,EAAE,UAAU,OAAO,IAAI,sBAAsB,MAAM,IAAI;AAC7D,QAAI,CAAC,YAAY,OAAO,SAAS,GAAG;AAClC;AAAA,IACF;AAEA,UAAM,QAAQ,mBAAmB,QAAQ;AACzC,UAAM,cAAc,oBAAI,IAAY;AAEpC,eAAW,CAAC,OAAO,QAAQ,KAAK,SAAS,UAAU,QAAQ,GAAG;AAC5D,YAAM,OAAO,MAAM,KAAK;AACxB,UAAI,CAAC,MAAM;AACT;AAAA,MACF;AAEA,YAAM,WAAW,SAAS,KAAK,OAAO,CAAC,QAAQF,aAAY,KAAK,GAAG,CAAC;AACpE,YAAM,SAAS,SAAS,KAAK,OAAO,CAAC,QAAQC,WAAU,KAAK,GAAG,CAAC;AAChE,YAAM,SAAS,SAAS,KAAK,OAAO,CAAC,QAAQG,WAAU,KAAK,GAAG,CAAC;AAEhE,UAAI,SAAS,WAAW,GAAG;AACzB,eAAO;AAAA,UACLD;AAAA,YACE;AAAA,YACA,sFAA+B,SAAS,IAAI;AAAA,YAC5C;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,OAAO,WAAW,GAAG;AACvB,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,oFAA6B,SAAS,IAAI;AAAA,YAC1C;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,aAAO,QAAQ,CAAC,OAAO,iBAAiB,IAAI,EAAE,CAAC;AAC/C,aAAO,QAAQ,CAAC,OAAO;AACrB,yBAAiB,IAAI,EAAE;AACvB,oBAAY,IAAI,EAAE;AAAA,MACpB,CAAC;AACD,YAAM,iBAAiB,SAAS,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;AAC/D,UAAI,eAAe,SAAS,GAAG;AAC7B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,wGAAkC,eAAe;AAAA,cAC/C;AAAA,YACF,CAAC,KAAK,SAAS,IAAI;AAAA,YACnB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,eAAe,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;AAChE,UAAI,aAAa,SAAS,GAAG;AAC3B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,sGAAgC,aAAa;AAAA,cAC3C;AAAA,YACF,CAAC,KAAK,SAAS,IAAI;AAAA,YACnB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,qBAAqB,KAAK,YAAY;AAAA,QAC1C,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE;AAAA,MAC7B;AACA,UAAI,mBAAmB,SAAS,GAAG;AACjC,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,kHAAkC,mBAAmB;AAAA,cACnD;AAAA,YACF,CAAC,KAAK,SAAS,IAAI;AAAA,YACnB,OAAO,WAAW,aAAa;AAAA,YAC/B;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS,SAAS,KAAK,OAAO,SAAS,GAAG;AAC5C,cAAM,eAAe,oBAAI,IAAY;AACrC,mBAAW,UAAU,UAAU;AAC7B,gBAAM,eAAe,YAAY,IAAI,MAAM;AAC3C,cAAI,CAAC,cAAc;AACjB;AAAA,UACF;AACA,uBAAa,QAAQ,CAAC,OAAO,aAAa,IAAI,EAAE,CAAC;AAAA,QACnD;AACA,cAAM,eAAe,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;AAChE,YAAI,aAAa,SAAS,GAAG;AAC3B,iBAAO;AAAA,YACLA;AAAA,cACE;AAAA,cACA,gGAAoC,aAAa;AAAA,gBAC/C;AAAA,cACF,CAAC,WAAW,SAAS,KAAK,IAAI,CAAC,MAAM,SAAS,IAAI;AAAA,cAClD;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,eAAe,MAAM,KAAK,WAAW,EAAE;AAAA,QAAK,CAAC,GAAG,MACpD,EAAE,cAAc,CAAC;AAAA,MACnB;AACA,YAAM,SACJ,aAAa,WAAW,IACpB,wDACA,+DAAkB,aAAa,KAAK,IAAI,CAAC;AAC/C,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,yFAAuC,MAAM;AAAA,UAC7C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,aAAa,gBAAgB,aAAa,OAAO,GAAG;AACxE,UAAM,cAAc,MAAM,KAAK,YAAY,EAAE;AAAA,MAC3C,CAAC,OAAO,CAAC,iBAAiB,IAAI,EAAE;AAAA,IAClC;AACA,QAAI,YAAY,SAAS,GAAG;AAC1B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,wEAAsB,YAAY,KAAK,IAAI,CAAC;AAAA,UAC5C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA,OAAO,WAAW,aAAa;AAAA,IAC/B,OAAO,WAAW,aAAa;AAAA,EACjC;AACA,QAAM,aAAa,aAAa;AAChC,QAAM,eAAe,aAAa;AAClC,QAAM,eAAe,iBAAiB,OAAO;AAC7C,QAAM,gBAAgB,aAAa,MAAM,SAAS;AAClD,QAAM,kBAAkB,aAAa,mBAAmB;AAExD,MACE,iBACC,CAAC,iBAAiB,CAAC,mBAAmB,aAAa,QACpD;AACA,UAAM,SAAS,aAAa,QAAQ,uBAAQ,aAAa,KAAK,WAAM;AACpE,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA,wMAAkD,MAAM;AAAA,QACxD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,QACE,OAAO,WAAW,aAAa,kBAC/B,iBAAiB,MACjB;AACA,YAAM,iBAAiB,MAAM,KAAK,gBAAgB,EAAE,OAAO,CAAC,OAAO;AACjE,cAAM,OAAO,WAAW,IAAI,EAAE;AAC9B,eAAO,CAAC,QAAQ,KAAK,SAAS;AAAA,MAChC,CAAC;AACD,UAAI,eAAe,SAAS,GAAG;AAC7B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,4FAAsB,eAAe;AAAA,cACnC;AAAA,YACF,CAAC;AAAA,YACD,OAAO,WAAW,aAAa;AAAA,YAC/B;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,KAAK,WAAW,KAAK,CAAC,EAAE;AAAA,MACjD,CAAC,OAAO,CAAC,iBAAiB,IAAI,EAAE;AAAA,IAClC;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,aAAO;AAAA,QACLA;AAAA,UACE;AAAA,UACA,6IAA+B,aAAa;AAAA,YAC1C;AAAA,UACF,CAAC;AAAA,UACD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,WAAW,aAAa,sBAAsB;AACxD,QAAI,YAAY,OAAO,GAAG;AACxB,YAAM,kBAAkB,MAAM,KAAK,WAAW,EAAE;AAAA,QAC9C,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE;AAAA,MACjC;AACA,UAAI,gBAAgB,SAAS,GAAG;AAC9B,eAAO;AAAA,UACLA;AAAA,YACE;AAAA,YACA,+FAAyB,gBAAgB,KAAK,IAAI,CAAC;AAAA,YACnD;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAI,MAAM,uBAAuB,aAAa,SAAS,SAAS;AAAA,EAClE;AACA,SAAO;AACT;AAEA,eAAe,uBACb,aACA,SACA,WACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,YAAY,MAAM,aAAa,SAAS;AAAA,IAC5C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,YAAY,MAAM,aAAa,WAAW;AAAA,IAC9C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,cAAc,CAAC,GAAG,WAAW,GAAG,SAAS;AAE/C,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,MACLA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,eAAe,MAAM,KAAK,WAAW,CAAC;AACtD,MAAI,QAAQ;AAEZ,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,MAAMD,WAAS,MAAM,OAAO;AACzC,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,cAAQ;AACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACLC;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,KAAuB;AAC7C,QAAM,UAAU,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,uBAAuB,MAAM,CAAC;AACzE,SAAO,IAAI,OAAO,OAAO,QAAQ,KAAK,GAAG,CAAC,MAAM;AAClD;AAEA,SAASA,OACP,MACA,SACA,UACA,MACA,MACA,MACO;AACP,QAAMA,SAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,MAAM;AACR,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,MAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,IAAAA,OAAM,OAAO;AAAA,EACf;AACA,SAAOA;AACT;;;ACxcA,eAAsB,gBACpB,MACA,cAC2B;AAC3B,QAAM,WAAW,gBAAiB,MAAM,WAAW,IAAI;AACvD,QAAM,EAAE,QAAQ,QAAQ,aAAa,IAAI;AACzC,QAAM,SAAS;AAAA,IACb,GAAG;AAAA,IACH,GAAI,MAAM,cAAc,MAAM,MAAM;AAAA,IACpC,GAAI,MAAM,eAAe,MAAM,MAAM;AAAA,IACrC,GAAI,MAAM,kBAAkB,MAAM,MAAM;AAAA,IACxC,GAAI,MAAM,kBAAkB,MAAM,MAAM;AAAA,IACxC,GAAI,MAAM,mBAAmB,MAAM,MAAM;AAAA,IACzC,GAAI,MAAM,qBAAqB,MAAM,MAAM;AAAA,EAC7C;AAEA,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAC1D,QAAM,QAAQ,MAAM,8BAA8B,aAAa;AAC/D,QAAM,EAAE,MAAM,YAAY,MAAM,UAAU,IAAI,MAAM;AAAA,IAClD;AAAA,IACA,OAAO,WAAW,aAAa;AAAA,IAC/B,OAAO,WAAW,aAAa;AAAA,EACjC;AACA,QAAM,aAAa,gBAAgB,OAAO,UAAU;AAEpD,QAAM,cAAc,MAAM,mBAAmB;AAC7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,YAAY,MAAM;AAAA,IAC1B,cAAc;AAAA,MACZ,IAAI;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,QAAmC;AACtD,SAAO,OAAO;AAAA,IACZ,CAAC,KAAKE,WAAU;AACd,UAAIA,OAAM,QAAQ,KAAK;AACvB,aAAO;AAAA,IACT;AAAA,IACA,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,EAAE;AAAA,EAClC;AACF;;;ApBgBA,IAAMC,eAA0B,CAAC,QAAQ,MAAM,MAAM,MAAM,OAAO,IAAI;AAEtE,eAAsB,iBACpB,MACA,YACA,cACqB;AACrB,QAAM,WAAW,gBAAiB,MAAM,WAAW,IAAI;AACvD,QAAM,SAAS,SAAS;AACxB,QAAM,aAAa,SAAS;AAE5B,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AACtD,QAAM,gBAAgB,YAAY,MAAM,QAAQ,cAAc;AAC9D,QAAM,UAAUC,OAAK,KAAK,eAAe,KAAK;AAC9C,QAAM,SAASA,OAAK,KAAK,eAAe,IAAI;AAC5C,QAAM,SAASA,OAAK,KAAK,eAAe,IAAI;AAC5C,QAAM,UAAU,YAAY,MAAM,QAAQ,QAAQ;AAClD,QAAM,YAAY,YAAY,MAAM,QAAQ,UAAU;AAEtD,QAAM,YAAY,MAAM,iBAAiB,SAAS;AAClD,QAAM,gBAAgB,MAAM,qBAAqB,SAAS;AAC1D,QAAM;AAAA,IACJ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,EACN,IAAI,MAAM,qBAAqB,QAAQ,SAAS,MAAM;AACtD,QAAM,gBAAgB,MAAM,mBAAmB,MAAM,MAAM;AAC3D,QAAM,mBAAmB,MAAM,wBAAwB,SAAS;AAChE,QAAM,iBAAiB,MAAM,KAAK,cAAc,GAAG;AACnD,QAAM,sBAAsB,oBAAI,IAAY;AAC5C,aAAW,OAAO,iBAAiB,kBAAkB,OAAO,GAAG;AAC7D,QAAI,QAAQ,CAAC,OAAO,oBAAoB,IAAI,EAAE,CAAC;AAAA,EACjD;AACA,QAAM,0BAA0B,eAAe;AAAA,IAAO,CAAC,OACrD,oBAAoB,IAAI,EAAE;AAAA,EAC5B,EAAE;AACF,QAAM,sBAAsB,eAAe;AAAA,IACzC,CAAC,OAAO,CAAC,oBAAoB,IAAI,EAAE;AAAA,EACrC,EAAE;AACF,QAAM,0BAA0B,kBAAkB,iBAAiB,SAAS;AAC5E,QAAM,0BAA0B;AAAA,IAC9B,iBAAiB;AAAA,EACnB;AAEA,QAAM,cAAc,MAAM,WAAW;AAAA,IACnC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AAED,QAAM,cAAc,MAAM,mBAAmB;AAAA,IAC3C,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AACD,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ,MAAM,8BAA8B,aAAa;AAC/D,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA,OAAO,WAAW,aAAa;AAAA,IAC/B,OAAO,WAAW,aAAa;AAAA,EACjC;AACA,QAAM,aACJ,YAAY,cAAc,MAAM,gBAAgB,OAAO,aAAa,IAAI;AAC1E,QAAM,YAAY,YAAY,cAAc,aAAa,aAAa;AACtE,QAAM,YAAY,MAAM,oCAAoC,aAAa;AACzE,QAAM,iBAAiB,kBAAkB,SAAS;AAElD,QAAM,qBACJ,cAAe,MAAM,gBAAgB,MAAM,QAAQ;AACrD,QAAM,UAAU,MAAM,mBAAmB;AAEzC,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,OAAO,UAAU;AAAA,MACjB,WAAW,cAAc;AAAA,MACzB,WAAW;AAAA,QACT,KAAK,SAAS;AAAA,QACd,IAAI,QAAQ;AAAA,QACZ,IAAI,QAAQ;AAAA,MACd;AAAA,MACA,QAAQ,mBAAmB;AAAA,IAC7B;AAAA,IACA,KAAK;AAAA,MACH,MAAM,YAAY;AAAA,MAClB,IAAI,YAAY;AAAA,MAChB,IAAI,YAAY;AAAA,MAChB,IAAI,YAAY;AAAA,MAChB,KAAK,YAAY;AAAA,MACjB,IAAI,YAAY;AAAA,IAClB;AAAA,IACA,cAAc;AAAA,MACZ,kBAAkB,YAAY;AAAA,MAC9B,yBAAyB;AAAA,MACzB,IAAI;AAAA,MACJ,WAAW;AAAA,MACX;AAAA,MACA,WAAW;AAAA,QACT,OAAO,eAAe;AAAA,QACtB,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,WAAW;AAAA,MACb;AAAA,MACA,OAAO;AAAA,QACL,oBAAoB,iBAAiB,gBAAgB;AAAA,QACrD,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,IACA,QAAQ,mBAAmB;AAAA,EAC7B;AACF;AAEO,SAAS,qBAAqB,MAA0B;AAC7D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,+BAAW,KAAK,WAAW,EAAE;AACxC,QAAM,KAAK,yBAAU,KAAK,IAAI,EAAE;AAChC,QAAM,KAAK,mBAAS,KAAK,UAAU,EAAE;AACrC,QAAM,KAAK,aAAQ,KAAK,OAAO,EAAE;AACjC,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,iBAAO;AAClB,QAAM,KAAK,YAAY,KAAK,QAAQ,KAAK,EAAE;AAC3C,QAAM,KAAK,gBAAgB,KAAK,QAAQ,SAAS,EAAE;AACnD,QAAM;AAAA,IACJ,oBAAoB,KAAK,QAAQ,UAAU,GAAG,SAAS,KAAK,QAAQ,UAAU,EAAE,SAAS,KAAK,QAAQ,UAAU,EAAE;AAAA,EACpH;AACA,QAAM;AAAA,IACJ,kBAAkB,KAAK,QAAQ,OAAO,IAAI,cAAc,KAAK,QAAQ,OAAO,OAAO,YAAY,KAAK,QAAQ,OAAO,KAAK;AAAA,EAC1H;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,mBAAS;AACpB,QAAM,KAAK,aAAa,QAAQ,KAAK,IAAI,IAAI,CAAC;AAC9C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,aAAa,OAAO,KAAK,IAAI,GAAG,CAAC;AAC5C,QAAM,KAAK,aAAa,MAAM,KAAK,IAAI,EAAE,CAAC;AAC1C,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,qDAAa;AACxB,QAAM,KAAK,uCAAc,KAAK,aAAa,gBAAgB,EAAE;AAC7D,QAAM;AAAA,IACJ,wDAAgB,KAAK,aAAa,0BAA0B,iBAAO,cAAI;AAAA,EACzE;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,+CAAY;AACvB,QAAM,KAAK,YAAY,KAAK,aAAa,UAAU,KAAK,EAAE;AAC1D,QAAM,KAAK,iBAAiB,KAAK,aAAa,UAAU,UAAU,EAAE;AACpE,QAAM,KAAK,aAAa,KAAK,aAAa,UAAU,MAAM,EAAE;AAC5D,QAAM;AAAA,IACJ,6BAA6B,KAAK,aAAa,MAAM,kBAAkB;AAAA,EACzE;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,2BAAY;AACvB,QAAM,kBAAkB,KAAK,aAAa,UAAU;AACpD,QAAM,cAAc,OAAO,KAAK,eAAe,EAAE;AAAA,IAAK,CAAC,GAAG,MACxD,EAAE,cAAc,CAAC;AAAA,EACnB;AACA,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,cAAc,aAAa;AACpC,YAAM,QAAQ,gBAAgB,UAAU,KAAK,CAAC;AAC9C,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM,KAAK,KAAK,UAAU,UAAU;AAAA,MACtC,OAAO;AACL,cAAM,KAAK,KAAK,UAAU,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,2BAAY;AACvB,QAAM,kBAAkB,KAAK,aAAa,MAAM;AAChD,QAAM,UAAU,OAAO,KAAK,eAAe,EAAE;AAAA,IAAK,CAAC,GAAG,MACpD,EAAE,cAAc,CAAC;AAAA,EACnB;AACA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,UAAU,SAAS;AAC5B,YAAMC,eAAc,gBAAgB,MAAM,KAAK,CAAC;AAChD,UAAIA,aAAY,WAAW,GAAG;AAC5B,cAAM,KAAK,KAAK,MAAM,UAAU;AAAA,MAClC,OAAO;AACL,cAAM,KAAK,KAAK,MAAM,KAAKA,aAAY,KAAK,IAAI,CAAC,EAAE;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,qCAAY;AACvB,QAAM,KAAK,YAAY,KAAK,aAAa,GAAG,KAAK,EAAE;AACnD,QAAM,KAAK,cAAc,KAAK,aAAa,GAAG,OAAO,EAAE;AACvD,QAAM,KAAK,cAAc,KAAK,aAAa,GAAG,OAAO,EAAE;AACvD,QAAM;AAAA,IACJ,oBAAoB,WAAW,KAAK,aAAa,UAAU,KAAK,CAAC;AAAA,EACnE;AACA,QAAM;AAAA,IACJ,2BAA2B;AAAA,MACzB,KAAK,aAAa,UAAU;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,QAAM;AAAA,IACJ,oBAAoB,KAAK,aAAa,UAAU,gBAAgB;AAAA,EAClE;AACA,MAAI,KAAK,aAAa,GAAG,WAAW,WAAW,GAAG;AAChD,UAAM,KAAK,sBAAsB;AAAA,EACnC,OAAO;AACL,UAAM,UAAU,KAAK,aAAa;AAClC,UAAM,qBAAqB,KAAK,aAAa,GAAG,WAAW,IAAI,CAAC,OAAO;AACrE,YAAM,QAAQ,QAAQ,EAAE,KAAK,CAAC;AAC9B,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO;AAAA,MACT;AACA,aAAO,GAAG,EAAE,KAAK,MAAM,KAAK,IAAI,CAAC;AAAA,IACnC,CAAC;AACD,UAAM,KAAK,iBAAiB,mBAAmB,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7D;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,2CAAa;AACxB,QAAM,SAAS,KAAK,aAAa,GAAG;AACpC,QAAM,QAAQ,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AACnE,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,OAAO;AACxB,YAAM,OAAO,OAAO,IAAI,KAAK,CAAC;AAC9B,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,KAAK,KAAK,IAAI,UAAU;AAAA,MAChC,OAAO;AACL,cAAM,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,6BAAmB;AAC9B,QAAM,eAAe,KAAK,OAAO;AAAA,IAC/B,CAAC,SAAS,KAAK,SAAS;AAAA,EAC1B;AACA,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,cAAc;AAC/B,YAAM,WAAW,KAAK,QAAQ;AAC9B,YAAM,OACJ,KAAK,QAAQ,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK;AAClE,YAAM,KAAK,KAAK,QAAQ,KAAK,IAAI,EAAE;AAAA,IACrC;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,aAAa;AACxB,QAAM,WAAW,cAAc,KAAK,MAAM;AAC1C,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,UAAU;AAC3B,YAAM;AAAA,QACJ,KAAK,KAAK,IAAI,WAAW,KAAK,KAAK,WAAW,KAAK,KAAK,cAAc,KAAK,OAAO,WAAW,KAAK,IAAI;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,6EAAiB;AAC5B,QAAM,cAAc,KAAK,OAAO;AAAA,IAC9B,CAAC,SACC,KAAK,MAAM,WAAW,eAAe,KACrC,KAAK,KAAK,WAAW,YAAY,KACjC,KAAK,KAAK,WAAW,aAAa;AAAA,EACtC;AACA,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,aAAa;AAC9B,YAAM,WAAW,KAAK,OAAO,KAAK,KAAK,IAAI,MAAM;AACjD,YAAM;AAAA,QACJ,KAAK,KAAK,SAAS,YAAY,CAAC,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,QAAQ;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM,KAAK,6BAAS;AACpB,MAAI,KAAK,OAAO,WAAW,GAAG;AAC5B,UAAM,KAAK,UAAU;AAAA,EACvB,OAAO;AACL,eAAW,QAAQ,KAAK,QAAQ;AAC9B,YAAM,WAAW,KAAK,OAAO,KAAK,KAAK,IAAI,MAAM;AACjD,YAAM,OACJ,KAAK,QAAQ,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK;AACvE,YAAM;AAAA,QACJ,KAAK,KAAK,SAAS,YAAY,CAAC,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,QAAQ,GAAG,IAAI;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,iBAAiB,MAA0B;AACzD,SAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AACrC;AAQA,eAAe,wBACb,WACiC;AACjC,QAAM,oBAAoB,oBAAI,IAAyB;AACvD,QAAM,YAAY,oBAAI,IAAyB;AAC/C,QAAM,kBAAkB,oBAAI,IAAY;AAExC,aAAW,QAAQ,WAAW;AAC5B,UAAM,OAAO,MAAMC,WAAS,MAAM,OAAO;AACzC,UAAM,SAAS,UAAU,MAAM,IAAI;AACnC,UAAM,UAAU,OAAO,UAAU;AACjC,UAAM,OAAO,OAAO;AAEpB,QAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,sBAAgB,IAAI,OAAO;AAAA,IAC7B;AAEA,UAAM,mBACJ,kBAAkB,IAAI,OAAO,KAAK,oBAAI,IAAY;AACpD,eAAW,MAAM,KAAK,KAAK;AACzB,uBAAiB,IAAI,EAAE;AACvB,YAAM,QAAQ,UAAU,IAAI,EAAE,KAAK,oBAAI,IAAY;AACnD,YAAM,IAAI,OAAO;AACjB,gBAAU,IAAI,IAAI,KAAK;AAAA,IACzB;AACA,sBAAkB,IAAI,SAAS,gBAAgB;AAAA,EACjD;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,WACb,OACqC;AACrC,QAAM,SAAwC;AAAA,IAC5C,MAAM,oBAAI,IAAI;AAAA,IACd,IAAI,oBAAI,IAAI;AAAA,IACZ,IAAI,oBAAI,IAAI;AAAA,IACZ,IAAI,oBAAI,IAAI;AAAA,IACZ,KAAK,oBAAI,IAAI;AAAA,IACb,IAAI,oBAAI,IAAI;AAAA,EACd;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMA,WAAS,MAAM,OAAO;AACzC,eAAW,UAAUH,cAAa;AAChC,YAAM,MAAM,WAAW,MAAM,MAAM;AACnC,UAAI,QAAQ,CAAC,OAAO,OAAO,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAMI,eAAc,OAAO,IAAI;AAAA,IAC/B,IAAIA,eAAc,OAAO,EAAE;AAAA,IAC3B,IAAIA,eAAc,OAAO,EAAE;AAAA,IAC3B,IAAIA,eAAc,OAAO,EAAE;AAAA,IAC3B,KAAKA,eAAc,OAAO,GAAG;AAAA,IAC7B,IAAIA,eAAc,OAAO,EAAE;AAAA,EAC7B;AACF;AAEA,eAAe,mBAAmB,OAAuC;AACvE,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAMD,WAAS,MAAM,OAAO;AACzC,kBAAc,IAAI,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;AAAA,EACjD;AACA,SAAO;AACT;AAEA,eAAe,qBACb,aACA,SACA,WACkB;AAClB,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,MAAM,aAAa,SAAS;AAAA,IAC5C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,YAAY,MAAM,aAAa,WAAW;AAAA,IAC9C,YAAY,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EAC3C,CAAC;AACD,QAAM,cAAc,CAAC,GAAG,WAAW,GAAG,SAAS;AAE/C,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,UAAUE,gBAAe,MAAM,KAAK,WAAW,CAAC;AAEtD,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,MAAMF,WAAS,MAAM,OAAO;AACzC,QAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASE,gBAAe,KAAuB;AAC7C,QAAM,UAAU,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,uBAAuB,MAAM,CAAC;AACzE,SAAO,IAAI,OAAO,OAAO,QAAQ,KAAK,GAAG,CAAC,MAAM;AAClD;AAEA,SAAS,aAAa,OAAe,QAA0B;AAC7D,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO,KAAK,KAAK,KAAK,OAAO,KAAK,IAAI,CAAC;AACzC;AAEA,SAAS,WAAW,QAA0B;AAC5C,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AACA,SAAO,OAAO,KAAK,IAAI;AACzB;AAEA,SAASD,eAAc,QAA+B;AACpD,SAAO,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAC7D;AAEA,SAAS,kBACP,QAC0B;AAC1B,QAAME,UAAmC,CAAC;AAC1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC3C,IAAAA,QAAO,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAAA,EACnE;AACA,SAAOA;AACT;AAUA,SAAS,cAAc,QAA4B;AACjD,QAAM,MAAM,oBAAI,IAAqB;AACrC,aAAWC,UAAS,QAAQ;AAC1B,QAAI,CAACA,OAAM,MAAM;AACf;AAAA,IACF;AACA,UAAM,UACJ,IAAI,IAAIA,OAAM,IAAI,KACjB;AAAA,MACC,MAAMA,OAAM;AAAA,MACZ,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACF,YAAQ,SAAS;AACjB,YAAQA,OAAM,QAAQ,KAAK;AAC3B,QAAI,IAAIA,OAAM,MAAM,OAAO;AAAA,EAC7B;AAEA,SAAO,MAAM,KAAK,IAAI,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,GAAG,MACvC,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EACvE;AACF;;;AF/iBA,eAAsB,UAAU,SAAuC;AACrE,QAAM,OAAOC,OAAK,QAAQ,QAAQ,IAAI;AACtC,QAAM,eAAe,MAAM,WAAW,IAAI;AAC1C,QAAM,QAAQ,aAAa,OAAO,OAAO;AACzC,QAAM,YAAYA,OAAK,WAAW,KAAK,IAAI,QAAQA,OAAK,QAAQ,MAAM,KAAK;AAC3E,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,qBAAqB,SAAS;AAAA,EACnD,SAAS,KAAK;AACZ,QAAIC,oBAAmB,GAAG,GAAG;AAC3B;AAAA,QACE;AAAA,UACE,sGAAgC,SAAS;AAAA,UACzC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,MACb;AACA,cAAQ,WAAW;AACnB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,QAAM,OAAO,MAAM,iBAAiB,MAAM,YAAY,YAAY;AAClE,QAAM,SACJ,QAAQ,WAAW,SACf,iBAAiB,IAAI,IACrB,qBAAqB,IAAI;AAE/B,QAAM,UAAU,YAAY,MAAM,aAAa,QAAQ,QAAQ;AAC/D,QAAM,aACJ,QAAQ,WAAW,SACfD,OAAK,KAAK,SAAS,aAAa,IAChCA,OAAK,KAAK,SAAS,WAAW;AACpC,QAAM,MAAM,QAAQ,WAAW;AAC/B,QAAM,UAAUA,OAAK,WAAW,GAAG,IAAI,MAAMA,OAAK,QAAQ,MAAM,GAAG;AAEnE,QAAME,OAAMF,OAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,QAAM,UAAU,SAAS,GAAG,MAAM;AAAA,GAAM,OAAO;AAE/C;AAAA,IACE,gBAAgB,WAAW,OAAO,IAAI,YAAY,WAAW,OAAO,OAAO,UAAU,WAAW,OAAO,KAAK;AAAA,EAC9G;AACA,OAAK,iBAAiB,OAAO,EAAE;AACjC;AAEA,eAAe,qBACb,WAC2B;AAC3B,QAAM,MAAM,MAAMG,WAAS,WAAW,OAAO;AAC7C,QAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,MAAI,CAAC,mBAAmB,MAAM,GAAG;AAC/B,UAAM,IAAI,MAAM,mEAA2B,SAAS,EAAE;AAAA,EACxD;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,OAA2C;AACrE,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAMC,UAAS;AACf,MAAI,OAAOA,QAAO,gBAAgB,UAAU;AAC1C,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM,QAAQA,QAAO,MAAM,GAAG;AACjC,WAAO;AAAA,EACT;AACA,QAAM,SAASA,QAAO;AACtB,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SACE,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,YAAY,YAC1B,OAAO,OAAO,UAAU;AAE5B;AAEA,SAASH,oBAAmBI,QAAyB;AACnD,MAAI,CAACA,UAAS,OAAOA,WAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAMD,UAASC;AACf,SAAOD,QAAO,SAAS;AACzB;;;AuB3GA,SAAS,SAAAE,QAAO,aAAAC,kBAAiB;AACjC,OAAOC,YAAU;;;ACIV,SAAS,WAAW,QAA0B,QAAyB;AAC5E,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,SAAS;AACtB,WAAO,OAAO,OAAO,QAAQ;AAAA,EAC/B;AACA,SAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,UAAU;AACvD;;;ADGA,eAAsB,YAAY,SAA2C;AAC3E,QAAM,OAAOC,OAAK,QAAQ,QAAQ,IAAI;AACtC,QAAM,eAAe,MAAM,WAAW,IAAI;AAC1C,QAAM,SAAS,MAAM,gBAAgB,MAAM,YAAY;AAEvD,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,WAAW,QAAQ;AACrB,aAAS,MAAM;AAAA,EACjB;AACA,MAAI,WAAW,UAAU;AACvB,WAAO,OAAO,QAAQ,UAAU;AAAA,EAClC;AACA,QAAM,SAAS,QAAQ,MAAM,aAAa,OAAO,OAAO,gBAAgB;AAExE,QAAM,SAAS,cAAc,SAAS,aAAa,OAAO,WAAW,MAAM;AAC3E,SAAO,WAAW,QAAQ,MAAM,IAAI,IAAI;AAC1C;AAEA,SAAS,cAAc,SAA0B,UAA0B;AACzE,MAAI,QAAQ,QAAQ;AAClB,WAAO,QAAQ;AAAA,EACjB;AACA,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,SAAS,QAAgC;AAChD,aAAW,QAAQ,OAAO,QAAQ;AAChC,UAAM,WAAW,KAAK,OAAO,KAAK,KAAK,IAAI,MAAM;AACjD,UAAM,OACJ,KAAK,QAAQ,KAAK,KAAK,SAAS,IAAI,SAAS,KAAK,KAAK,KAAK,GAAG,CAAC,KAAK;AACvE,YAAQ,OAAO;AAAA,MACb,IAAI,KAAK,QAAQ,KAAK,KAAK,IAAI,IAAI,KAAK,OAAO,GAAG,QAAQ,GAAG,IAAI;AAAA;AAAA,IACnE;AAAA,EACF;AACA,UAAQ,OAAO;AAAA,IACb,gBAAgB,OAAO,OAAO,IAAI,YAAY,OAAO,OAAO,OAAO,UAAU,OAAO,OAAO,KAAK;AAAA;AAAA,EAClG;AACF;AAEA,SAAS,WAAWC,QAAoB;AACtC,QAAM,QACJA,OAAM,aAAa,UACf,UACAA,OAAM,aAAa,YACjB,YACA;AACR,QAAM,OAAOA,OAAM,OAAO,QAAQA,OAAM,IAAI,KAAK;AACjD,QAAM,OAAOA,OAAM,KAAK,OAAO,SAASA,OAAM,IAAI,IAAI,KAAK;AAC3D,QAAM,SAASA,OAAM,KAAK,SAAS,QAAQA,OAAM,IAAI,MAAM,KAAK;AAChE,QAAM,WAAW,OAAO,IAAI,IAAI,GAAG,IAAI,GAAG,MAAM,KAAK;AACrD,UAAQ,OAAO;AAAA,IACb,KAAK,KAAK,GAAG,QAAQ,KAAKA,OAAM,IAAI,KAAKA,OAAM,OAAO;AAAA;AAAA,EACxD;AACF;AAEA,eAAe,SACb,QACA,MACA,UACe;AACf,QAAM,MAAMD,OAAK,WAAW,QAAQ,IAChC,WACAA,OAAK,QAAQ,MAAM,QAAQ;AAC/B,QAAME,OAAMF,OAAK,QAAQ,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAMG,WAAU,KAAK,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,GAAM,OAAO;AACtE;;;AEnEO,SAAS,UAAU,MAAgB,KAAyB;AACjE,QAAM,UAAiC;AAAA,IACrC,MAAM;AAAA,IACN,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAEA,QAAM,OAAO,CAAC,GAAG,IAAI;AACrB,MAAI,UAAU,KAAK,MAAM,KAAK;AAE9B,MAAI,YAAY,YAAY,YAAY,MAAM;AAC5C,YAAQ,OAAO;AACf,cAAU;AAAA,EACZ;AAEA,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,MAAM,KAAK,CAAC;AAClB,YAAQ,KAAK;AAAA,MACX,KAAK;AACH,gBAAQ,OAAO,KAAK,IAAI,CAAC,KAAK,QAAQ;AACtC,aAAK;AACL;AAAA,MACF,KAAK;AACH,gBAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,QAAQ;AACrC,aAAK;AACL;AAAA,MACF,KAAK;AACH,gBAAQ,QAAQ;AAChB;AAAA,MACF,KAAK;AACH,gBAAQ,MAAM;AACd;AAAA,MACF,KAAK;AACH,gBAAQ,SAAS;AACjB;AAAA,MACF,KAAK,YAAY;AACf,cAAM,OAAO,KAAK,IAAI,CAAC;AACvB,0BAAkB,SAAS,MAAM,OAAO;AACxC,aAAK;AACL;AAAA,MACF;AAAA,MACA,KAAK;AACH,gBAAQ,SAAS;AACjB;AAAA,MACF,KAAK,aAAa;AAChB,cAAM,OAAO,KAAK,IAAI,CAAC;AACvB,YAAI,SAAS,WAAW,SAAS,aAAa,SAAS,SAAS;AAC9D,kBAAQ,SAAS;AAAA,QACnB;AACA,aAAK;AACL;AAAA,MACF;AAAA,MACA,KAAK;AACH;AACE,gBAAM,OAAO,KAAK,IAAI,CAAC;AACvB,cAAI,MAAM;AACR,oBAAQ,YAAY;AAAA,UACtB;AAAA,QACF;AACA,aAAK;AACL;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,gBAAQ,OAAO;AACf;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAEA,SAAS,kBACP,SACA,OACA,SACM;AACN,MAAI,CAAC,OAAO;AACV;AAAA,EACF;AACA,MAAI,YAAY,UAAU;AACxB,QAAI,UAAU,QAAQ,UAAU,QAAQ;AACtC,cAAQ,eAAe;AAAA,IACzB;AACA;AAAA,EACF;AACA,MAAI,YAAY,YAAY;AAC1B,QAAI,UAAU,UAAU,UAAU,UAAU;AAC1C,cAAQ,iBAAiB;AAAA,IAC3B;AACA;AAAA,EACF;AAEA,MAAI,UAAU,QAAQ,UAAU,QAAQ;AACtC,YAAQ,eAAe;AAAA,EACzB;AACA,MAAI,UAAU,UAAU,UAAU,UAAU;AAC1C,YAAQ,iBAAiB;AAAA,EAC3B;AACF;;;ACrHA,eAAsB,IAAI,MAAgB,KAA4B;AACpE,QAAM,EAAE,SAAS,QAAQ,IAAI,UAAU,MAAM,GAAG;AAEhD,MAAI,CAAC,WAAW,QAAQ,MAAM;AAC5B,SAAK,MAAM,CAAC;AACZ;AAAA,EACF;AAEA,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,YAAM,QAAQ;AAAA,QACZ,KAAK,QAAQ;AAAA,QACb,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,QAChB,KAAK,QAAQ;AAAA,MACf,CAAC;AACD;AAAA,IACF,KAAK;AACH,cAAQ,WAAW,MAAM,YAAY;AAAA,QACnC,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACnE,CAAC;AACD;AAAA,IACF,KAAK;AACH,YAAM,UAAU;AAAA,QACd,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,GAAI,QAAQ,cAAc,SACtB,EAAE,SAAS,QAAQ,UAAU,IAC7B,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACE,YAAM,oBAAoB,OAAO,EAAE;AACnC,WAAK,MAAM,CAAC;AACZ;AAAA,EACJ;AACF;AAEA,SAAS,QAAgB;AACvB,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBT;;;ACjEA,IAAI,QAAQ,KAAK,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ;AACvD,UAAQ,OAAO,MAAM,GAAG,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC5E,UAAQ,WAAW;AACrB,CAAC;","names":["path","path","path","mkdir","readFile","path","path","error","readFile","path","readFile","path","access","access","readdir","path","exists","readdir","path","error","exists","access","path","readFile","unique","readFile","path","error","formatError","unique","SC_TAG_RE","readFile","error","formatError","path","readFile","path","fileURLToPath","readFile","path","path","parseYaml","path","parseYaml","path","readFile","error","formatError","issue","readFile","path","path","readFile","error","isMissingFileError","issue","readFile","path","SC_TAG_RE","issue","readFile","path","readFile","SC_TAG_RE","SPEC_TAG_RE","issue","readFile","error","isMissingFileError","readFile","issue","readFile","error","isMissingFileError","readFile","SPEC_TAG_RE","BR_TAG_RE","readFile","issue","SC_TAG_RE","issue","ID_PREFIXES","path","contractIds","readFile","toSortedArray","buildIdPattern","record","issue","path","isMissingFileError","mkdir","readFile","record","error","mkdir","writeFile","path","path","issue","mkdir","writeFile"]}
|