@contractkit/openapi-to-ck 0.7.8 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$ci.log +6 -6
- package/.turbo/turbo-test$colon$ci.log +12 -12
- package/CHANGELOG.md +42 -0
- package/coverage/clover.xml +148 -146
- package/coverage/coverage-final.json +1 -1
- package/coverage/index.html +14 -14
- package/coverage/src/ast-to-ck.ts.html +19 -13
- package/coverage/src/circular-refs.ts.html +1 -1
- package/coverage/src/convert.ts.html +1 -1
- package/coverage/src/index.html +14 -14
- package/coverage/src/normalize.ts.html +1 -1
- package/coverage/src/paths-to-ast.ts.html +3 -3
- package/coverage/src/schema-to-ast.ts.html +1 -1
- package/coverage/src/tag-splitter.ts.html +1 -1
- package/coverage/src/warnings.ts.html +1 -1
- package/coverage/tests/helpers.ts.html +1 -1
- package/coverage/tests/index.html +1 -1
- package/dist/ast-to-ck.d.ts.map +1 -1
- package/dist/{chunk-T2G2WRZ2.js → chunk-YOTHJ2V4.js} +8 -6
- package/dist/chunk-YOTHJ2V4.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +2 -2
- package/src/ast-to-ck.ts +7 -5
- package/src/paths-to-ast.ts +2 -2
- package/tests/ast-to-ck.test.ts +3 -3
- package/dist/chunk-T2G2WRZ2.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/normalize.ts","../src/circular-refs.ts","../src/schema-to-ast.ts","../src/paths-to-ast.ts","../src/tag-splitter.ts","../src/ast-to-ck.ts","../src/convert.ts","../src/warnings.ts"],"sourcesContent":["import type { NormalizedDocument } from './types.js';\nimport type { WarningCollector } from './warnings.js';\n\n/**\n * Detects the OpenAPI version from a parsed document and normalizes it to a\n * 3.1-like shape. Swagger 2.0 and OpenAPI 3.0 documents are transformed\n * so that downstream code only needs to handle one schema dialect.\n *\n * Uses @scalar/openapi-parser's `upgrade()` for the heavy lifting when\n * available, with manual fallbacks for edge cases.\n */\nexport function normalize(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const version = detectVersion(doc);\n\n if (version === '2.0') {\n return normalizeSwagger2(doc, warnings);\n }\n if (version === '3.0') {\n return normalizeOas30(doc as unknown as NormalizedDocument, warnings);\n }\n // 3.1+ — already in target shape\n return doc as unknown as NormalizedDocument;\n}\n\nfunction detectVersion(doc: Record<string, unknown>): '2.0' | '3.0' | '3.1' {\n if (typeof doc.swagger === 'string' && doc.swagger.startsWith('2')) return '2.0';\n if (typeof doc.openapi === 'string') {\n if (doc.openapi.startsWith('3.0')) return '3.0';\n }\n return '3.1';\n}\n\n// ─── Swagger 2.0 → 3.1 ───────────────────────────────────────────────────\n\nfunction normalizeSwagger2(doc: Record<string, unknown>, warnings: WarningCollector): NormalizedDocument {\n const info = (doc.info as Record<string, unknown>) ?? { title: 'Untitled', version: '0.0.0' };\n const basePath = (doc.basePath as string) ?? '';\n const schemes = (doc.schemes as string[]) ?? ['https'];\n const host = (doc.host as string) ?? 'localhost';\n const globalConsumes = (doc.consumes as string[]) ?? ['application/json'];\n const globalProduces = (doc.produces as string[]) ?? ['application/json'];\n\n const result: NormalizedDocument = {\n openapi: '3.1.0',\n info: {\n title: (info.title as string) ?? 'Untitled',\n version: (info.version as string) ?? '0.0.0',\n description: info.description as string | undefined,\n },\n servers: [{ url: `${schemes[0]}://${host}${basePath}` }],\n paths: {},\n components: {\n schemas: {},\n securitySchemes: {},\n },\n tags: (doc.tags as NormalizedDocument['tags']) ?? [],\n };\n\n // Convert definitions → components/schemas\n const definitions = (doc.definitions as Record<string, unknown>) ?? {};\n for (const [name, schema] of Object.entries(definitions)) {\n result.components!.schemas![name] = normalizeNullable30(schema as Record<string, unknown>);\n }\n\n // Convert securityDefinitions → components/securitySchemes\n const secDefs = (doc.securityDefinitions as Record<string, unknown>) ?? {};\n for (const [name, scheme] of Object.entries(secDefs)) {\n result.components!.securitySchemes![name] = convertSecurityScheme2(scheme as Record<string, unknown>);\n }\n\n // Convert paths\n const paths = (doc.paths as Record<string, Record<string, unknown>>) ?? {};\n for (const [path, pathItem] of Object.entries(paths)) {\n result.paths![path] = normalizePathItem2(pathItem, globalConsumes, globalProduces, warnings);\n }\n\n // Global security\n if (doc.security) {\n result.security = doc.security as Record<string, string[]>[];\n }\n\n return result;\n}\n\nfunction normalizePathItem2(\n pathItem: Record<string, unknown>,\n globalConsumes: string[],\n globalProduces: string[],\n warnings: WarningCollector,\n): Record<string, unknown> {\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];\n const normalized: Record<string, unknown> = {};\n\n // Path-level parameters\n const pathParams = (pathItem.parameters as unknown[]) ?? [];\n\n for (const method of methods) {\n const op = pathItem[method] as Record<string, unknown> | undefined;\n if (!op) continue;\n\n const opConsumes = (op.consumes as string[]) ?? globalConsumes;\n const opProduces = (op.produces as string[]) ?? globalProduces;\n const params = [...pathParams, ...((op.parameters as unknown[]) ?? [])];\n\n // Separate body params from others\n const nonBodyParams: unknown[] = [];\n let requestBody: Record<string, unknown> | undefined;\n\n for (const param of params as Record<string, unknown>[]) {\n if (param.in === 'body') {\n const contentType = opConsumes[0] ?? 'application/json';\n requestBody = {\n description: param.description,\n required: param.required ?? true,\n content: {\n [contentType]: {\n schema: normalizeNullable30((param.schema as Record<string, unknown>) ?? {}),\n },\n },\n };\n } else if (param.in === 'formData') {\n warnings.info(`#/paths/${encodePathSegment(method)}`, 'formData parameters converted to multipart/form-data requestBody');\n // Collect formData params into a schema\n if (!requestBody) {\n requestBody = {\n content: {\n 'multipart/form-data': {\n schema: { type: 'object', properties: {}, required: [] as string[] },\n },\n },\n };\n }\n const formSchema = (requestBody.content as Record<string, Record<string, unknown>>)['multipart/form-data']!.schema as Record<\n string,\n unknown\n >;\n const props = formSchema.properties as Record<string, unknown>;\n props[param.name as string] = normalizeNullable30(param as Record<string, unknown>);\n if (param.required) {\n (formSchema.required as string[]).push(param.name as string);\n }\n } else {\n // Convert param schema\n const normalizedParam = { ...param };\n if (param.type) {\n normalizedParam.schema = normalizeNullable30({\n type: param.type,\n format: param.format,\n enum: param.enum,\n items: param.items,\n default: param.default,\n minimum: param.minimum,\n maximum: param.maximum,\n minLength: param.minLength,\n maxLength: param.maxLength,\n pattern: param.pattern,\n } as Record<string, unknown>);\n delete normalizedParam.type;\n delete normalizedParam.format;\n delete normalizedParam.enum;\n delete normalizedParam.items;\n }\n nonBodyParams.push(normalizedParam);\n }\n }\n\n // Convert responses\n const responses: Record<string, unknown> = {};\n const opResponses = (op.responses as Record<string, Record<string, unknown>>) ?? {};\n for (const [code, resp] of Object.entries(opResponses)) {\n const contentType = opProduces[0] ?? 'application/json';\n const headers = convertResponseHeaders2(resp.headers as Record<string, Record<string, unknown>> | undefined);\n const responseEntry: Record<string, unknown> = {\n description: resp.description ?? '',\n };\n if (resp.schema) {\n responseEntry.content = {\n [contentType]: {\n schema: normalizeNullable30(resp.schema as Record<string, unknown>),\n },\n };\n }\n if (headers) {\n responseEntry.headers = headers;\n }\n responses[code] = responseEntry;\n }\n\n normalized[method] = {\n operationId: op.operationId,\n summary: op.summary,\n description: op.description,\n tags: op.tags,\n parameters: nonBodyParams.length > 0 ? nonBodyParams : undefined,\n requestBody,\n responses,\n security: op.security,\n deprecated: op.deprecated,\n };\n }\n\n return normalized;\n}\n\n/**\n * Convert Swagger 2.0 response headers to a 3.x-shaped Header Object map.\n * 2.0 stores `type`/`format`/`items` inline on the header; 3.x wraps the same fields under `schema`.\n */\nfunction convertResponseHeaders2(\n headers: Record<string, Record<string, unknown>> | undefined,\n): Record<string, Record<string, unknown>> | undefined {\n if (!headers) return undefined;\n const out: Record<string, Record<string, unknown>> = {};\n for (const [name, header] of Object.entries(headers)) {\n if (!header || typeof header !== 'object') continue;\n const { description, type, format, items, ...rest } = header;\n const schema: Record<string, unknown> = { ...rest };\n if (type !== undefined) schema.type = type;\n if (format !== undefined) schema.format = format;\n if (items !== undefined) schema.items = items;\n const normalized: Record<string, unknown> = {};\n if (description !== undefined) normalized.description = description;\n if (Object.keys(schema).length > 0) normalized.schema = normalizeNullable30(schema);\n out[name] = normalized;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction convertSecurityScheme2(scheme: Record<string, unknown>): unknown {\n const type = scheme.type as string;\n if (type === 'basic') {\n return { type: 'http', scheme: 'basic' };\n }\n if (type === 'apiKey') {\n return { type: 'apiKey', name: scheme.name, in: scheme.in };\n }\n if (type === 'oauth2') {\n const flow = scheme.flow as string;\n const flows: Record<string, unknown> = {};\n if (flow === 'implicit') {\n flows.implicit = { authorizationUrl: scheme.authorizationUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'password') {\n flows.password = { tokenUrl: scheme.tokenUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'application') {\n flows.clientCredentials = { tokenUrl: scheme.tokenUrl, scopes: scheme.scopes ?? {} };\n } else if (flow === 'accessCode') {\n flows.authorizationCode = {\n authorizationUrl: scheme.authorizationUrl,\n tokenUrl: scheme.tokenUrl,\n scopes: scheme.scopes ?? {},\n };\n }\n return { type: 'oauth2', flows };\n }\n return scheme;\n}\n\n// ─── OpenAPI 3.0 → 3.1 ───────────────────────────────────────────────────\n\nfunction normalizeOas30(doc: NormalizedDocument, _warnings: WarningCollector): NormalizedDocument {\n // Walk all schemas and convert `nullable: true` to type arrays\n if (doc.components?.schemas) {\n for (const [name, schema] of Object.entries(doc.components.schemas)) {\n doc.components.schemas[name] = normalizeNullable30(schema as Record<string, unknown>);\n }\n }\n\n // Walk paths and normalize inline schemas\n if (doc.paths) {\n for (const pathItem of Object.values(doc.paths)) {\n normalizePathItemSchemas(pathItem as Record<string, unknown>);\n }\n }\n\n doc.openapi = '3.1.0';\n return doc;\n}\n\nfunction normalizePathItemSchemas(pathItem: Record<string, unknown>): void {\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];\n for (const method of methods) {\n const op = pathItem[method] as Record<string, unknown> | undefined;\n if (!op) continue;\n\n // Normalize parameter schemas\n const params = (op.parameters as Record<string, unknown>[]) ?? [];\n for (const param of params) {\n if (param.schema) {\n param.schema = normalizeNullable30(param.schema as Record<string, unknown>);\n }\n }\n\n // Normalize requestBody schemas\n const reqBody = op.requestBody as Record<string, unknown> | undefined;\n if (reqBody?.content) {\n for (const mediaType of Object.values(reqBody.content as Record<string, Record<string, unknown>>)) {\n if (mediaType.schema) {\n mediaType.schema = normalizeNullable30(mediaType.schema as Record<string, unknown>);\n }\n }\n }\n\n // Normalize response schemas\n const responses = (op.responses as Record<string, Record<string, unknown>>) ?? {};\n for (const resp of Object.values(responses)) {\n if (resp.content) {\n for (const mediaType of Object.values(resp.content as Record<string, Record<string, unknown>>)) {\n if (mediaType.schema) {\n mediaType.schema = normalizeNullable30(mediaType.schema as Record<string, unknown>);\n }\n }\n }\n }\n }\n}\n\n/**\n * Recursively converts OAS 3.0 `nullable: true` to OAS 3.1 `type: [T, \"null\"]`.\n * Also normalizes nested schemas (properties, items, allOf, etc.).\n */\nfunction normalizeNullable30(schema: Record<string, unknown>): Record<string, unknown> {\n if (!schema || typeof schema !== 'object') return schema;\n\n const result = { ...schema };\n\n // Convert nullable: true → type array with null\n if (result.nullable === true && typeof result.type === 'string') {\n result.type = [result.type, 'null'];\n delete result.nullable;\n }\n\n // Convert $ref alongside other properties (OAS 3.0 $ref with siblings was invalid,\n // but OAS 3.1 allows it — no conversion needed, just keep walking)\n\n // Recurse into nested schemas\n if (result.properties && typeof result.properties === 'object') {\n const props = result.properties as Record<string, Record<string, unknown>>;\n for (const [key, val] of Object.entries(props)) {\n props[key] = normalizeNullable30(val);\n }\n }\n if (result.items && typeof result.items === 'object' && !Array.isArray(result.items)) {\n result.items = normalizeNullable30(result.items as Record<string, unknown>);\n }\n if (result.additionalProperties && typeof result.additionalProperties === 'object') {\n result.additionalProperties = normalizeNullable30(result.additionalProperties as Record<string, unknown>);\n }\n for (const combiner of ['allOf', 'oneOf', 'anyOf'] as const) {\n if (Array.isArray(result[combiner])) {\n result[combiner] = (result[combiner] as Record<string, unknown>[]).map(normalizeNullable30);\n }\n }\n\n return result;\n}\n\nfunction encodePathSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n","/**\n * Detects circular $ref chains in OpenAPI schema definitions.\n * Returns the set of schema names that participate in cycles.\n * These should be wrapped in `lazy()` in the output .ck.\n */\nexport function detectCircularRefs(schemas: Record<string, unknown>): Set<string> {\n const circular = new Set<string>();\n const visiting = new Set<string>(); // current DFS path\n const visited = new Set<string>(); // fully explored\n\n function visit(name: string): void {\n if (visited.has(name)) return;\n if (visiting.has(name)) {\n circular.add(name);\n return;\n }\n\n visiting.add(name);\n const schema = schemas[name];\n if (schema && typeof schema === 'object') {\n for (const ref of collectRefs(schema as Record<string, unknown>)) {\n const refName = extractRefName(ref);\n if (refName && schemas[refName]) {\n visit(refName);\n }\n }\n }\n visiting.delete(name);\n visited.add(name);\n }\n\n for (const name of Object.keys(schemas)) {\n visit(name);\n }\n\n return circular;\n}\n\n/**\n * Recursively collects all $ref strings from a schema object.\n */\nfunction collectRefs(obj: Record<string, unknown>): string[] {\n const refs: string[] = [];\n\n function walk(val: unknown): void {\n if (!val || typeof val !== 'object') return;\n if (Array.isArray(val)) {\n for (const item of val) walk(item);\n return;\n }\n const record = val as Record<string, unknown>;\n if (typeof record.$ref === 'string') {\n refs.push(record.$ref);\n }\n for (const v of Object.values(record)) {\n walk(v);\n }\n }\n\n walk(obj);\n return refs;\n}\n\n/**\n * Extracts the schema name from a $ref like \"#/components/schemas/Foo\"\n * or \"#/definitions/Foo\" (Swagger 2.0 after normalization still uses components).\n */\nexport function extractRefName(ref: string): string | undefined {\n const match = ref.match(/^#\\/(?:components\\/schemas|definitions)\\/(.+)$/);\n return match?.[1];\n}\n","import type { ContractTypeNode, ScalarTypeNode, ModelNode, FieldNode, SourceLocation } from '@contractkit/core';\nimport type { NormalizedSchema } from './types.js';\nimport { extractRefName } from './circular-refs.js';\nimport type { WarningCollector } from './warnings.js';\n\n// ─── Conversion Context ───────────────────────────────────────────────────\n\nexport interface SchemaContext {\n /** Schema names involved in circular references — use lazy() for these. */\n circularRefs: Set<string>;\n /** Warning collector for unsupported features. */\n warnings: WarningCollector;\n /** Current JSON pointer path (for warnings). */\n path: string;\n /** Whether to include descriptions. */\n includeComments: boolean;\n /** All named schemas (for inline extraction). */\n namedSchemas: Record<string, NormalizedSchema>;\n /** Extracted inline models (accumulated during conversion). */\n extractedModels: ModelNode[];\n /** Counter for generating unique names for inline models. */\n inlineCounter: number;\n}\n\nconst LOC: SourceLocation = { file: '', line: 0 };\n\n// ─── Format → Scalar Name Mapping ────────────────────────────────────────\n\nconst FORMAT_TO_SCALAR: Record<string, ScalarTypeNode['name']> = {\n email: 'email',\n uri: 'url',\n url: 'url',\n uuid: 'uuid',\n date: 'date',\n 'date-time': 'datetime',\n time: 'time',\n binary: 'binary',\n int64: 'bigint',\n};\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\n/**\n * Convert all named schemas in components/schemas to ModelNodes.\n */\nexport function schemasToModels(schemas: Record<string, NormalizedSchema>, ctx: SchemaContext): ModelNode[] {\n const models: ModelNode[] = [];\n\n for (const [name, schema] of Object.entries(schemas)) {\n const modelCtx = { ...ctx, path: `#/components/schemas/${name}` };\n const model = schemaToModel(name, schema, modelCtx);\n if (model) models.push(model);\n }\n\n // Append any inline models extracted during conversion\n models.push(...ctx.extractedModels);\n\n return models;\n}\n\n/**\n * Convert a named schema to a ModelNode.\n */\nfunction schemaToModel(name: string, schema: NormalizedSchema, ctx: SchemaContext): ModelNode | null {\n warnUnsupported(schema, ctx);\n\n const description = ctx.includeComments ? schema.description : undefined;\n\n // allOf with exactly 2 members, one being a $ref → inheritance\n if (schema.allOf && schema.allOf.length === 2) {\n const [first, second] = schema.allOf;\n const refMember = first?.$ref ? first : second?.$ref ? second : null;\n const objectMember = first?.$ref ? second : first;\n\n if (refMember?.$ref && objectMember?.properties) {\n const baseName = extractRefName(refMember.$ref);\n if (baseName) {\n const fields = schemaPropertiesToFields(objectMember, ctx);\n return {\n kind: 'model',\n name,\n bases: [baseName],\n fields,\n description,\n loc: LOC,\n };\n }\n }\n }\n\n // Object with properties → struct\n if (schema.properties || (schema.type === 'object' && !schema.additionalProperties)) {\n const fields = schemaPropertiesToFields(schema, ctx);\n return {\n kind: 'model',\n name,\n fields,\n description,\n loc: LOC,\n };\n }\n\n // Otherwise → type alias\n const typeNode = schemaToTypeNode(schema, ctx);\n return {\n kind: 'model',\n name,\n fields: [],\n type: typeNode,\n description,\n loc: LOC,\n };\n}\n\n/**\n * Convert an OpenAPI schema to a ContractTypeNode.\n */\nexport function schemaToTypeNode(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // $ref\n if (schema.$ref) {\n const refName = extractRefName(schema.$ref);\n if (refName) {\n if (ctx.circularRefs.has(refName)) {\n return { kind: 'lazy', inner: { kind: 'ref', name: refName } };\n }\n return { kind: 'ref', name: refName };\n }\n ctx.warnings.warn(ctx.path, `Unresolvable $ref: ${schema.$ref}`);\n return { kind: 'scalar', name: 'unknown' };\n }\n\n // const\n if (schema.const !== undefined) {\n return { kind: 'literal', value: schema.const as string | number | boolean };\n }\n\n // enum\n if (schema.enum) {\n return { kind: 'enum', values: schema.enum.map(String) };\n }\n\n // oneOf / anyOf → union (or discriminatedUnion when discriminator.propertyName is set)\n if (schema.oneOf && schema.oneOf.length > 0) {\n if (schema.discriminator?.propertyName) {\n return toDiscriminatedUnion(schema.oneOf, schema.discriminator.propertyName, ctx);\n }\n return toUnion(schema.oneOf, ctx);\n }\n if (schema.anyOf && schema.anyOf.length > 0) {\n if (schema.discriminator?.propertyName) {\n return toDiscriminatedUnion(schema.anyOf, schema.discriminator.propertyName, ctx);\n }\n return toUnion(schema.anyOf, ctx);\n }\n\n // allOf → intersection\n if (schema.allOf && schema.allOf.length > 0) {\n if (schema.allOf.length === 1) {\n return schemaToTypeNode(schema.allOf[0]!, ctx);\n }\n return {\n kind: 'intersection',\n members: schema.allOf.map(s => schemaToTypeNode(s, ctx)),\n };\n }\n\n // Handle nullable type arrays: [string, null] → nullable\n const types = normalizeTypeField(schema);\n\n if (types === null) {\n // No type information at all\n if (schema.properties) {\n return schemaToInlineObject(schema, ctx);\n }\n return { kind: 'scalar', name: 'unknown' };\n }\n\n const { baseType, nullable } = types;\n\n let typeNode: ContractTypeNode;\n\n switch (baseType) {\n case 'string':\n typeNode = stringSchemaToType(schema);\n break;\n case 'integer':\n typeNode = integerSchemaToType(schema);\n break;\n case 'number':\n typeNode = numberSchemaToType(schema);\n break;\n case 'boolean':\n typeNode = { kind: 'scalar', name: 'boolean' };\n break;\n case 'null':\n typeNode = { kind: 'scalar', name: 'null' };\n break;\n case 'array':\n typeNode = arraySchemaToType(schema, ctx);\n break;\n case 'object':\n typeNode = objectSchemaToType(schema, ctx);\n break;\n default:\n ctx.warnings.warn(ctx.path, `Unknown type: ${baseType}`);\n typeNode = { kind: 'scalar', name: 'unknown' };\n }\n\n if (nullable) {\n return { kind: 'union', members: [typeNode, { kind: 'scalar', name: 'null' }] };\n }\n\n return typeNode;\n}\n\n// ─── Type-Specific Converters ─────────────────────────────────────────────\n\nfunction stringSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n // Check format first\n if (schema.format) {\n const scalarName = FORMAT_TO_SCALAR[schema.format];\n if (scalarName) {\n return { kind: 'scalar', name: scalarName };\n }\n }\n\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minLength !== undefined && schema.maxLength !== undefined && schema.minLength === schema.maxLength) {\n mods.len = schema.minLength;\n } else {\n if (schema.minLength !== undefined) mods.min = schema.minLength;\n if (schema.maxLength !== undefined) mods.max = schema.maxLength;\n }\n if (schema.pattern) mods.regex = `/${schema.pattern}/`;\n if (schema.format && !FORMAT_TO_SCALAR[schema.format]) mods.format = schema.format;\n\n return { kind: 'scalar', name: 'string', ...mods };\n}\n\nfunction integerSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n const name: ScalarTypeNode['name'] = schema.format === 'int64' ? 'bigint' : 'int';\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = schema.minimum;\n if (schema.maximum !== undefined) mods.max = schema.maximum;\n return { kind: 'scalar', name, ...mods };\n}\n\nfunction numberSchemaToType(schema: NormalizedSchema): ContractTypeNode {\n const mods: Partial<ScalarTypeNode> = {};\n if (schema.minimum !== undefined) mods.min = schema.minimum;\n if (schema.maximum !== undefined) mods.max = schema.maximum;\n return { kind: 'scalar', name: 'number', ...mods };\n}\n\nfunction arraySchemaToType(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // Tuple: prefixItems (OAS 3.1)\n if (schema.prefixItems && schema.prefixItems.length > 0) {\n return {\n kind: 'tuple',\n items: schema.prefixItems.map(s => schemaToTypeNode(s, ctx)),\n };\n }\n\n const item = schema.items ? schemaToTypeNode(schema.items, ctx) : { kind: 'scalar' as const, name: 'unknown' as const };\n const mods: { min?: number; max?: number } = {};\n if (schema.minItems !== undefined) mods.min = schema.minItems;\n if (schema.maxItems !== undefined) mods.max = schema.maxItems;\n\n return { kind: 'array', item, ...mods };\n}\n\nfunction objectSchemaToType(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n // Record type: additionalProperties with no named properties\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && !schema.properties) {\n return {\n kind: 'record',\n key: { kind: 'scalar', name: 'string' },\n value: schemaToTypeNode(schema.additionalProperties, ctx),\n };\n }\n\n // Object with properties → inline object or extracted model\n if (schema.properties) {\n return schemaToInlineObject(schema, ctx);\n }\n\n // Empty object\n return { kind: 'scalar', name: 'object' };\n}\n\nfunction schemaToInlineObject(schema: NormalizedSchema, ctx: SchemaContext): ContractTypeNode {\n const fields = schemaPropertiesToFields(schema, ctx);\n return { kind: 'inlineObject', fields };\n}\n\n// ─── Field Conversion ─────────────────────────────────────────────────────\n\nfunction schemaPropertiesToFields(schema: NormalizedSchema, ctx: SchemaContext): FieldNode[] {\n const properties = schema.properties ?? {};\n const required = new Set(schema.required ?? []);\n const fields: FieldNode[] = [];\n\n for (const [name, propSchema] of Object.entries(properties)) {\n const propCtx = { ...ctx, path: `${ctx.path}/properties/${name}` };\n const fieldType = schemaToTypeNode(propSchema, propCtx);\n\n // Determine nullable from the type (if it's a union with null)\n let nullable = false;\n let effectiveType = fieldType;\n if (fieldType.kind === 'union') {\n const nonNull = fieldType.members.filter(m => !(m.kind === 'scalar' && m.name === 'null'));\n if (nonNull.length < fieldType.members.length) {\n nullable = true;\n effectiveType = nonNull.length === 1 ? nonNull[0]! : { kind: 'union', members: nonNull };\n }\n }\n\n const visibility = propSchema.readOnly ? ('readonly' as const) : propSchema.writeOnly ? ('writeonly' as const) : ('normal' as const);\n\n fields.push({\n name,\n optional: !required.has(name),\n nullable,\n visibility,\n type: effectiveType,\n default: propSchema.default as string | number | boolean | undefined,\n deprecated: propSchema.deprecated,\n description: ctx.includeComments ? propSchema.description : undefined,\n loc: LOC,\n });\n }\n\n return fields;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction normalizeTypeField(schema: NormalizedSchema): { baseType: string; nullable: boolean } | null {\n if (!schema.type) return null;\n\n if (typeof schema.type === 'string') {\n return { baseType: schema.type, nullable: false };\n }\n\n if (Array.isArray(schema.type)) {\n const types = schema.type as string[];\n const nonNull = types.filter(t => t !== 'null');\n const nullable = types.includes('null');\n if (nonNull.length === 1) {\n return { baseType: nonNull[0]!, nullable };\n }\n // Multiple non-null types — unusual but handle gracefully\n if (nonNull.length === 0) {\n return { baseType: 'null', nullable: false };\n }\n // Multiple types → treat as unknown\n return { baseType: nonNull[0]!, nullable };\n }\n\n return null;\n}\n\nfunction toUnion(schemas: NormalizedSchema[], ctx: SchemaContext): ContractTypeNode {\n const members = schemas.map(s => schemaToTypeNode(s, ctx));\n if (members.length === 1) return members[0]!;\n return { kind: 'union', members };\n}\n\nfunction toDiscriminatedUnion(schemas: NormalizedSchema[], discriminator: string, ctx: SchemaContext): ContractTypeNode {\n const members = schemas.map(s => schemaToTypeNode(s, ctx));\n if (members.length === 1) return members[0]!;\n return { kind: 'discriminatedUnion', discriminator, members };\n}\n\nfunction warnUnsupported(schema: NormalizedSchema, ctx: SchemaContext): void {\n if (schema.xml) ctx.warnings.warn(ctx.path, 'xml metadata is not supported, skipping');\n if (schema.externalDocs) ctx.warnings.info(ctx.path, 'externalDocs is not supported, skipping');\n if (schema.not) ctx.warnings.warn(ctx.path, 'not keyword is not supported, skipping');\n}\n\n/**\n * Extract a named model from an inline object schema (used for request/response bodies).\n */\nexport function extractInlineModel(\n schema: NormalizedSchema,\n suggestedName: string,\n ctx: SchemaContext,\n): { typeNode: ContractTypeNode; model?: ModelNode } {\n // If it's a $ref, just use the ref\n if (schema.$ref) {\n return { typeNode: schemaToTypeNode(schema, ctx) };\n }\n\n // If it's an object with properties, extract as a named model\n if (schema.properties || (schema.type === 'object' && schema.additionalProperties === undefined)) {\n const fields = schemaPropertiesToFields(schema, ctx);\n const model: ModelNode = {\n kind: 'model',\n name: suggestedName,\n fields,\n description: ctx.includeComments ? schema.description : undefined,\n loc: LOC,\n };\n return {\n typeNode: { kind: 'ref', name: suggestedName },\n model,\n };\n }\n\n // Otherwise return the type node directly\n return { typeNode: schemaToTypeNode(schema, ctx) };\n}\n\n/**\n * Sanitize an OpenAPI schema name to a valid .ck identifier (PascalCase).\n */\nexport function sanitizeName(name: string, warnings: WarningCollector): string {\n // Replace dots, hyphens, spaces, and other invalid chars with word boundaries\n const cleaned = name\n .replace(/[^a-zA-Z0-9_$]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n\n if (cleaned !== name) {\n warnings.info(`#/components/schemas/${name}`, `Schema name sanitized: \"${name}\" → \"${cleaned}\"`);\n }\n\n return cleaned || 'UnnamedSchema';\n}\n","import type {\n OpRouteNode,\n OpOperationNode,\n OpParamNode,\n OpRequestNode,\n OpResponseNode,\n OpResponseHeaderNode,\n HttpMethod,\n ModelNode,\n SourceLocation,\n SecurityNode,\n} from '@contractkit/core';\nimport type {\n NormalizedDocument,\n NormalizedPathItem,\n NormalizedOperation,\n NormalizedParameter,\n NormalizedRequestBody,\n NormalizedResponse,\n} from './types.js';\nimport { schemaToTypeNode, extractInlineModel } from './schema-to-ast.js';\nimport type { SchemaContext } from './schema-to-ast.js';\nimport type { WarningCollector } from './warnings.js';\n\nconst LOC: SourceLocation = { file: '', line: 0 };\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete'];\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\nexport interface PathsContext {\n circularRefs: Set<string>;\n warnings: WarningCollector;\n includeComments: boolean;\n namedSchemas: Record<string, unknown>;\n /** Accumulates inline models extracted from request/response bodies. */\n extractedModels: ModelNode[];\n /** Global security from the spec (for detecting explicit overrides). */\n globalSecurity?: Record<string, string[]>[];\n}\n\n/**\n * Convert OpenAPI paths to OpRouteNode[].\n * Returns routes along with a tag mapping for each route.\n */\nexport function pathsToRoutes(doc: NormalizedDocument, ctx: PathsContext): { routes: OpRouteNode[]; routeTags: Map<OpRouteNode, string> } {\n const routes: OpRouteNode[] = [];\n const routeTags = new Map<OpRouteNode, string>();\n const paths = doc.paths ?? {};\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem) continue;\n const result = pathItemToRoute(path, pathItem, ctx);\n if (result) {\n routes.push(result.route);\n routeTags.set(result.route, result.tag);\n }\n }\n\n return { routes, routeTags };\n}\n\n// ─── Path Item → Route ───────────────────────────────────────────────────\n\nfunction pathItemToRoute(path: string, pathItem: NormalizedPathItem, ctx: PathsContext): { route: OpRouteNode; tag: string } | null {\n const operations: OpOperationNode[] = [];\n let primaryTag = 'default';\n\n // Collect path-level parameters\n const pathParams = (pathItem.parameters ?? []).filter(p => p.in === 'path');\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const opNode = operationToNode(method, op, path, ctx);\n operations.push(opNode);\n\n // Use first tag of first operation as the route's tag\n if (op.tags && op.tags.length > 0 && primaryTag === 'default') {\n primaryTag = op.tags[0]!;\n }\n }\n\n if (operations.length === 0) return null;\n\n // Build params from path-level + inferred from path template\n const params = buildPathParams(path, pathParams, pathItem, ctx);\n\n const route: OpRouteNode = {\n path,\n operations,\n loc: LOC,\n };\n\n if (params.length > 0) {\n route.params = { kind: 'params', nodes: params };\n }\n\n if (pathItem.description && ctx.includeComments) {\n route.description = pathItem.description;\n }\n\n return { route, tag: primaryTag };\n}\n\n// ─── Operation → Node ─────────────────────────────────────────────────────\n\nfunction operationToNode(method: HttpMethod, op: NormalizedOperation, path: string, ctx: PathsContext): OpOperationNode {\n const pathPrefix = `#/paths/${encodePathSegment(path)}/${method}`;\n const schemaCtx = makeSchemaCtx(ctx, pathPrefix);\n\n const node: OpOperationNode = {\n method,\n responses: [],\n loc: LOC,\n };\n\n // operationId → sdk\n if (op.operationId) {\n node.sdk = op.operationId;\n }\n\n // Description\n if (op.description && ctx.includeComments) {\n node.description = op.description;\n }\n\n // Deprecated\n if (op.deprecated) {\n node.modifiers = ['deprecated'];\n }\n\n // Query and header parameters\n const queryParams: OpParamNode[] = [];\n const headerParams: OpParamNode[] = [];\n\n for (const param of op.parameters ?? []) {\n if (param.in === 'query') {\n queryParams.push(parameterToNode(param, schemaCtx));\n } else if (param.in === 'header') {\n headerParams.push(parameterToNode(param, schemaCtx));\n }\n }\n\n if (queryParams.length > 0) {\n node.query = { kind: 'params', nodes: queryParams };\n }\n if (headerParams.length > 0) {\n node.headers = { kind: 'params', nodes: headerParams };\n }\n\n // Request body\n if (op.requestBody) {\n node.request = requestBodyToNode(op.requestBody, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n }\n\n // Responses\n const responses = op.responses ?? {};\n for (const [code, resp] of Object.entries(responses)) {\n const statusCode = parseInt(code, 10);\n if (isNaN(statusCode)) continue;\n const respNode = responseToNode(statusCode, resp, op.operationId ?? `${method}${toPascalCase(path)}`, schemaCtx, ctx);\n node.responses.push(respNode);\n }\n\n // Security\n if (op.security !== undefined) {\n node.security = convertSecurity(op.security);\n }\n\n return node;\n}\n\n// ─── Parameters ───────────────────────────────────────────────────────────\n\nfunction buildPathParams(path: string, pathLevelParams: NormalizedParameter[], pathItem: NormalizedPathItem, ctx: PathsContext): OpParamNode[] {\n const schemaCtx = makeSchemaCtx(ctx, `#/paths/${encodePathSegment(path)}`);\n\n // Collect all path params from path-level and operation-level\n const paramMap = new Map<string, NormalizedParameter>();\n\n for (const p of pathLevelParams) {\n paramMap.set(p.name, p);\n }\n\n // Also check operation-level path params\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op?.parameters) continue;\n for (const p of op.parameters) {\n if (p.in === 'path' && !paramMap.has(p.name)) {\n paramMap.set(p.name, p);\n }\n }\n }\n\n // Extract param names from path template\n const templateNames = [...path.matchAll(/\\{([^}]+)\\}/g)].map(m => m[1]!);\n\n return templateNames.map(name => {\n const param = paramMap.get(name);\n if (param) {\n return parameterToNode(param, schemaCtx);\n }\n // Infer as uuid if no schema is given\n return {\n name,\n optional: false,\n nullable: false,\n type: { kind: 'scalar' as const, name: 'string' as const },\n loc: LOC,\n };\n });\n}\n\nfunction parameterToNode(param: NormalizedParameter, ctx: SchemaContext): OpParamNode {\n const type = param.schema ? schemaToTypeNode(param.schema, ctx) : { kind: 'scalar' as const, name: 'string' as const };\n\n return {\n name: param.name,\n optional: param.in !== 'path' && !param.required,\n nullable: false,\n type,\n description: ctx.includeComments ? param.description : undefined,\n loc: LOC,\n };\n}\n\n// ─── Request Body ─────────────────────────────────────────────────────────\n\nfunction requestBodyToNode(\n reqBody: NormalizedRequestBody,\n operationName: string,\n schemaCtx: SchemaContext,\n ctx: PathsContext,\n): OpRequestNode | undefined {\n const content = reqBody.content;\n if (!content) return undefined;\n\n const supported = new Set<string>(['application/json', 'application/x-www-form-urlencoded', 'multipart/form-data']);\n const bodies: OpRequestNode['bodies'] = [];\n\n for (const [contentType, mediaType] of Object.entries(content)) {\n if (!supported.has(contentType) || !mediaType?.schema) continue;\n const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Request`, schemaCtx);\n if (model) {\n ctx.extractedModels.push(model);\n }\n bodies.push({\n contentType: contentType as OpRequestNode['bodies'][number]['contentType'],\n bodyType: typeNode,\n });\n }\n\n if (bodies.length === 0) return undefined;\n return { bodies };\n}\n\n// ─── Responses ────────────────────────────────────────────────────────────\n\nfunction responseToNode(\n statusCode: number,\n resp: NormalizedResponse,\n operationName: string,\n schemaCtx: SchemaContext,\n ctx: PathsContext,\n): OpResponseNode {\n const headers = convertResponseHeaders(resp.headers, schemaCtx);\n\n if (!resp.content) {\n return headers ? { statusCode, headers } : { statusCode };\n }\n\n // Pick the first content type\n const [contentType, mediaType] = Object.entries(resp.content)[0] ?? [];\n if (!contentType || !mediaType?.schema) {\n return headers ? { statusCode, headers } : { statusCode };\n }\n\n const { typeNode, model } = extractInlineModel(mediaType.schema, `${toPascalCase(operationName)}Response${statusCode}`, schemaCtx);\n\n if (model) {\n ctx.extractedModels.push(model);\n }\n\n return {\n statusCode,\n contentType: contentType as 'application/json',\n bodyType: typeNode,\n ...(headers ? { headers } : {}),\n };\n}\n\nfunction convertResponseHeaders(headers: NormalizedResponse['headers'], schemaCtx: SchemaContext): OpResponseHeaderNode[] | undefined {\n if (!headers) return undefined;\n const out: OpResponseHeaderNode[] = [];\n for (const [name, header] of Object.entries(headers)) {\n if (!header) continue;\n const type = header.schema ? schemaToTypeNode(header.schema, schemaCtx) : { kind: 'scalar' as const, name: 'string' as const };\n out.push({\n name,\n optional: !header.required,\n type,\n description: schemaCtx.includeComments ? header.description : undefined,\n });\n }\n return out.length > 0 ? out : undefined;\n}\n\n// ─── Security ─────────────────────────────────────────────────────────────\n\nfunction convertSecurity(security: Record<string, string[]>[]): SecurityNode {\n // Empty array = explicitly no security\n if (security.length === 0) {\n return 'none';\n }\n\n // The DSL's security model is simpler — OpenAPI scopes/roles don't map onto named policies,\n // so any non-empty security requirement is collapsed to \"authenticated, default policy\".\n return { loc: LOC };\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction makeSchemaCtx(ctx: PathsContext, path: string): SchemaContext {\n return {\n circularRefs: ctx.circularRefs,\n warnings: ctx.warnings,\n path,\n includeComments: ctx.includeComments,\n namedSchemas: ctx.namedSchemas as Record<string, never>,\n extractedModels: ctx.extractedModels,\n inlineCounter: 0,\n };\n}\n\nfunction toPascalCase(input: string): string {\n return input\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nfunction encodePathSegment(s: string): string {\n return s.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n","import type { CkRootNode, ModelNode, OpRouteNode, ContractTypeNode } from '@contractkit/core';\n\n/**\n * Split models and routes into per-tag CkRootNode instances.\n *\n * Algorithm:\n * 1. Routes are assigned to the file of their first tag (untagged → 'default')\n * 2. Models referenced by exactly one tag go into that tag's file\n * 3. Models referenced by 2+ tags go into 'shared'\n * 4. Orphan models (not referenced by any route) go into 'shared'\n */\nexport function splitByTag(models: ModelNode[], routes: OpRouteNode[], routeTags: Map<OpRouteNode, string>): Map<string, CkRootNode> {\n // Step 1: Group routes by tag\n const routesByTag = new Map<string, OpRouteNode[]>();\n for (const route of routes) {\n const tag = routeTags.get(route) ?? 'default';\n const group = routesByTag.get(tag) ?? [];\n group.push(route);\n routesByTag.set(tag, group);\n }\n\n // Step 2: For each tag, collect which model names are referenced\n const modelsByTag = new Map<string, Set<string>>();\n for (const [tag, tagRoutes] of routesByTag) {\n const refs = new Set<string>();\n for (const route of tagRoutes) {\n collectRouteRefs(route, refs);\n }\n modelsByTag.set(tag, refs);\n }\n\n // Step 3: Determine which tag each model belongs to\n const modelNameToModel = new Map(models.map(m => [m.name, m]));\n const modelAssignment = new Map<string, string>(); // modelName → tag or 'shared'\n\n for (const model of models) {\n const tags: string[] = [];\n for (const [tag, refs] of modelsByTag) {\n if (refs.has(model.name)) {\n tags.push(tag);\n }\n }\n\n if (tags.length === 0) {\n // Orphan model → shared\n modelAssignment.set(model.name, 'shared');\n } else if (tags.length === 1) {\n // Single tag reference → that tag's file\n modelAssignment.set(model.name, tags[0]!);\n } else {\n // Multi-tag reference → shared\n modelAssignment.set(model.name, 'shared');\n }\n }\n\n // Also check transitive: models referenced by shared models should also be shared\n // (simple one-pass — could iterate to fixed point for deep chains)\n for (const model of models) {\n if (modelAssignment.get(model.name) === 'shared') {\n const refs = new Set<string>();\n collectModelRefs(model, refs);\n for (const ref of refs) {\n if (modelNameToModel.has(ref)) {\n const currentTag = modelAssignment.get(ref);\n // Only promote to shared if it was assigned to a specific tag\n // (don't override if already shared)\n if (currentTag && currentTag !== 'shared') {\n // Check if another tag also references this model\n const otherTags = [...modelsByTag.entries()].filter(([t, r]) => t !== currentTag && r.has(ref)).map(([t]) => t);\n if (otherTags.length > 0) {\n modelAssignment.set(ref, 'shared');\n }\n }\n }\n }\n }\n }\n\n // Step 4: Build CkRootNode per tag\n const result = new Map<string, CkRootNode>();\n const allTags = new Set([...routesByTag.keys(), ...new Set(modelAssignment.values())]);\n\n for (const tag of allTags) {\n const tagModels = models.filter(m => modelAssignment.get(m.name) === tag);\n const tagRoutes = routesByTag.get(tag) ?? [];\n\n if (tagModels.length === 0 && tagRoutes.length === 0) continue;\n\n const filename = sanitizeFilename(tag);\n result.set(`${filename}.ck`, {\n kind: 'ckRoot',\n meta: tag !== 'shared' ? { area: tag } : {},\n services: {},\n models: tagModels,\n routes: tagRoutes,\n file: `${filename}.ck`,\n });\n }\n\n return result;\n}\n\n/**\n * Create a single CkRootNode with all models and routes.\n */\nexport function mergeIntoSingle(models: ModelNode[], routes: OpRouteNode[], filename: string = 'api'): CkRootNode {\n return {\n kind: 'ckRoot',\n meta: {},\n services: {},\n models,\n routes,\n file: `${filename}.ck`,\n };\n}\n\n// ─── Reference Collection ─────────────────────────────────────────────────\n\nfunction collectRouteRefs(route: OpRouteNode, refs: Set<string>): void {\n if (route.params) {\n collectParamSourceRefs(route.params, refs);\n }\n for (const op of route.operations) {\n if (op.query) collectParamSourceRefs(op.query, refs);\n if (op.headers) collectParamSourceRefs(op.headers, refs);\n if (op.request) {\n for (const body of op.request.bodies) collectTypeRefs(body.bodyType, refs);\n }\n for (const resp of op.responses) {\n if (resp.bodyType) collectTypeRefs(resp.bodyType, refs);\n }\n }\n}\n\nfunction collectParamSourceRefs(source: unknown, refs: Set<string>): void {\n if (typeof source === 'string') {\n refs.add(source);\n return;\n }\n if (Array.isArray(source)) {\n for (const param of source) {\n if (param && typeof param === 'object' && 'type' in param) {\n collectTypeRefs(param.type as ContractTypeNode, refs);\n }\n }\n return;\n }\n if (source && typeof source === 'object' && 'kind' in source) {\n collectTypeRefs(source as ContractTypeNode, refs);\n }\n}\n\nfunction collectTypeRefs(type: ContractTypeNode, refs: Set<string>): void {\n switch (type.kind) {\n case 'ref':\n refs.add(type.name);\n break;\n case 'array':\n collectTypeRefs(type.item, refs);\n break;\n case 'tuple':\n for (const item of type.items) collectTypeRefs(item, refs);\n break;\n case 'record':\n collectTypeRefs(type.key, refs);\n collectTypeRefs(type.value, refs);\n break;\n case 'union':\n case 'discriminatedUnion':\n case 'intersection':\n for (const member of type.members) collectTypeRefs(member, refs);\n break;\n case 'inlineObject':\n for (const field of type.fields) collectTypeRefs(field.type, refs);\n break;\n case 'lazy':\n collectTypeRefs(type.inner, refs);\n break;\n }\n}\n\nfunction collectModelRefs(model: ModelNode, refs: Set<string>): void {\n if (model.bases) for (const b of model.bases) refs.add(b);\n if (model.type) collectTypeRefs(model.type, refs);\n for (const field of model.fields) {\n collectTypeRefs(field.type, refs);\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction sanitizeFilename(tag: string): string {\n return (\n tag\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'default'\n );\n}\n","import type {\n CkRootNode,\n ModelNode,\n FieldNode,\n ContractTypeNode,\n OpRouteNode,\n OpOperationNode,\n OpRequestNode,\n OpResponseNode,\n ParamSource,\n SecurityNode,\n SecurityFields,\n ObjectMode,\n RouteModifier,\n} from '@contractkit/core';\n\nconst INDENT = ' '; // 4 spaces\n\n// ─── Public API ───────────────────────────────────────────────────────────\n\nexport interface SerializeOptions {\n /** Emit descriptions as inline # comments. Default: true. */\n includeComments?: boolean;\n}\n\nexport function astToCk(root: CkRootNode, options: SerializeOptions = {}): string {\n const { includeComments = true } = options;\n const ctx: Ctx = { includeComments };\n const parts: string[] = [];\n\n // Options block\n const optionsBlock = serializeOptions(root);\n if (optionsBlock) parts.push(optionsBlock);\n\n // Models\n for (const model of root.models) {\n parts.push(serializeModel(model, ctx));\n }\n\n // Routes\n for (const route of root.routes) {\n parts.push(serializeRoute(route, ctx));\n }\n\n return parts.join('\\n\\n') + '\\n';\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────\n\ninterface Ctx {\n includeComments: boolean;\n}\n\n// ─── Options block ────────────────────────────────────────────────────────\n\nfunction serializeOptions(root: CkRootNode): string | null {\n const hasKeys = Object.keys(root.meta).length > 0;\n const hasServices = root.services && Object.keys(root.services).length > 0;\n const hasSecurity = root.security !== undefined;\n\n if (!hasKeys && !hasServices && !hasSecurity) return null;\n\n const lines: string[] = ['options {'];\n\n if (hasKeys) {\n lines.push(`${INDENT}keys: {`);\n for (const [key, value] of Object.entries(root.meta)) {\n lines.push(`${INDENT}${INDENT}${key}: ${value}`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasServices) {\n lines.push(`${INDENT}services: {`);\n for (const [name, path] of Object.entries(root.services)) {\n lines.push(`${INDENT}${INDENT}${name}: \"${path}\"`);\n }\n lines.push(`${INDENT}}`);\n }\n\n if (hasSecurity) {\n lines.push(`${INDENT}security: {`);\n if (root.security === 'none') {\n lines.push(`${INDENT}${INDENT}none`);\n } else {\n const sec = root.security as SecurityFields;\n if (sec.policy !== undefined) {\n const value = sec.policy === false ? 'none' : sec.policy;\n lines.push(`${INDENT}${INDENT}policy: ${value}`);\n }\n }\n lines.push(`${INDENT}}`);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\n// ─── Models ───────────────────────────────────────────────────────────────\n\nfunction serializeModel(model: ModelNode, ctx: Ctx): string {\n const parts: string[] = [];\n\n // Modifiers: format(input=snake) mode(loose) deprecated\n const prefixes: string[] = [];\n if (model.inputCase && model.inputCase !== 'camel') {\n prefixes.push(`format(input=${model.inputCase})`);\n }\n if (model.mode && model.mode !== 'strict') {\n prefixes.push(`mode(${model.mode})`);\n }\n if (model.deprecated) {\n prefixes.push('deprecated');\n }\n\n const prefix = prefixes.length > 0 ? prefixes.join(' ') + ' ' : '';\n const comment = ctx.includeComments && model.description ? ` # ${model.description}` : '';\n\n // Type alias: contract Name: typeExpression\n if (model.type) {\n parts.push(`contract ${prefix}${model.name}: ${serializeType(model.type)}${comment}`);\n return parts.join('');\n }\n\n // Inheritance: contract Name: Base1 & Base2 & { ... }\n if (model.bases && model.bases.length > 0) {\n parts.push(`contract ${prefix}${model.name}: ${model.bases.join(' & ')} & {${comment}`);\n } else {\n parts.push(`contract ${prefix}${model.name}: {${comment}`);\n }\n\n for (const field of model.fields) {\n parts.push(serializeField(field, 1, ctx));\n }\n\n parts.push('}');\n return parts.join('\\n');\n}\n\nfunction serializeField(field: FieldNode, depth: number, ctx: Ctx): string {\n const indent = INDENT.repeat(depth);\n const optional = field.optional ? '?' : '';\n const visibility = field.visibility !== 'normal' ? `${field.visibility} ` : '';\n const deprecated = field.deprecated ? 'deprecated ' : '';\n\n let typeStr = serializeType(field.type);\n\n // Nullable fields: if the type doesn't already contain null, append `| null`\n if (field.nullable && !typeContainsNull(field.type)) {\n typeStr = `${typeStr} | null`;\n }\n\n const defaultVal = field.default !== undefined ? ` = ${serializeDefault(field.default)}` : '';\n const comment = ctx.includeComments && field.description ? ` # ${field.description}` : '';\n\n return `${indent}${field.name}${optional}: ${deprecated}${visibility}${typeStr}${defaultVal}${comment}`;\n}\n\nfunction typeContainsNull(type: ContractTypeNode): boolean {\n if (type.kind === 'scalar' && type.name === 'null') return true;\n if (type.kind === 'union') return type.members.some(typeContainsNull);\n return false;\n}\n\nfunction serializeDefault(value: string | number | boolean): string {\n if (typeof value === 'string') {\n // If it looks like an identifier (e.g. enum value), don't quote it\n if (/^[a-zA-Z_$][a-zA-Z0-9_$\\-.]*$/.test(value)) return value;\n return `\"${value}\"`;\n }\n return String(value);\n}\n\n// ─── Types ────────────────────────────────────────────────────────────────\n\nexport function serializeType(type: ContractTypeNode): string {\n switch (type.kind) {\n case 'scalar':\n return serializeScalar(type);\n case 'array':\n return serializeArray(type);\n case 'tuple':\n return `tuple(${type.items.map(serializeType).join(', ')})`;\n case 'record':\n return `record(${serializeType(type.key)}, ${serializeType(type.value)})`;\n case 'enum':\n return `enum(${type.values.join(', ')})`;\n case 'literal':\n return serializeLiteral(type);\n case 'union':\n return type.members.map(serializeType).join(' | ');\n case 'discriminatedUnion':\n return `discriminated(by=${type.discriminator}, ${type.members.map(serializeType).join(' | ')})`;\n case 'intersection':\n return type.members.map(serializeType).join(' & ');\n case 'ref':\n return type.name;\n case 'inlineObject':\n return serializeInlineObject(type);\n case 'lazy':\n return `lazy(${serializeType(type.inner)})`;\n }\n}\n\nfunction serializeScalar(type: {\n name: string;\n min?: number | bigint | string;\n max?: number | bigint | string;\n len?: number;\n regex?: string;\n format?: string;\n}): string {\n const args: string[] = [];\n if (type.len !== undefined) args.push(`length=${type.len}`);\n if (type.min !== undefined) args.push(typeof type.min === 'string' ? `min=\"${type.min}\"` : `min=${type.min}`);\n if (type.max !== undefined) args.push(typeof type.max === 'string' ? `max=\"${type.max}\"` : `max=${type.max}`);\n if (type.regex !== undefined) args.push(`regex=${type.regex}`);\n if (type.format !== undefined) args.push(`format=${type.format}`);\n\n if (args.length === 0) return type.name;\n return `${type.name}(${args.join(', ')})`;\n}\n\nfunction serializeArray(type: { item: ContractTypeNode; min?: number; max?: number }): string {\n const args: string[] = [serializeType(type.item)];\n if (type.min !== undefined) args.push(`min=${type.min}`);\n if (type.max !== undefined) args.push(`max=${type.max}`);\n return `array(${args.join(', ')})`;\n}\n\nfunction serializeLiteral(type: { value: string | number | boolean }): string {\n if (typeof type.value === 'string') return `literal(\"${type.value}\")`;\n return `literal(${type.value})`;\n}\n\nfunction serializeInlineObject(type: { fields: FieldNode[]; mode?: ObjectMode }): string {\n const modePrefix = type.mode ? `mode(${type.mode}) ` : '';\n if (type.fields.length === 0) return `${modePrefix}{}`;\n\n const lines: string[] = [`${modePrefix}{`];\n for (const field of type.fields) {\n lines.push(serializeField(field, 2, { includeComments: true }));\n }\n lines.push(`${INDENT}}`);\n return lines.join('\\n');\n}\n\n// ─── Routes ───────────────────────────────────────────────────────────────\n\nfunction serializeRoute(route: OpRouteNode, ctx: Ctx): string {\n const lines: string[] = [];\n\n const modStr = serializeModifiers(route.modifiers);\n const comment = ctx.includeComments && route.description ? ` # ${route.description}` : '';\n lines.push(`operation${modStr} ${route.path}: {${comment}`);\n\n // Route-level params\n if (route.params) {\n serializeParamSource(lines, 'params', route.params, route.paramsMode, 1, ctx);\n }\n\n // Route-level security\n if (route.security !== undefined) {\n serializeSecurityBlock(lines, route.security, 1, ctx);\n }\n\n // Operations\n for (const op of route.operations) {\n serializeOperation(lines, op, 1, ctx);\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\nfunction serializeOperation(lines: string[], op: OpOperationNode, depth: number, ctx: Ctx): string[] {\n const indent = INDENT.repeat(depth);\n const modStr = serializeModifiers(op.modifiers);\n const comment = ctx.includeComments && op.description ? ` # ${op.description}` : '';\n lines.push(`${indent}${op.method}${modStr}: {${comment}`);\n\n const inner = INDENT.repeat(depth + 1);\n\n // Service\n if (op.service) {\n lines.push(`${inner}service: ${op.service}`);\n }\n\n // SDK\n if (op.sdk) {\n lines.push(`${inner}sdk: ${op.sdk}`);\n }\n\n // Signature\n if (op.signature) {\n const sigComment = ctx.includeComments && op.signatureDescription ? ` # ${op.signatureDescription}` : '';\n lines.push(`${inner}signature: ${op.signature}${sigComment}`);\n }\n\n // Security\n if (op.security !== undefined) {\n serializeSecurityBlock(lines, op.security, depth + 1, ctx);\n }\n\n // Query\n if (op.query) {\n serializeParamSource(lines, 'query', op.query, op.queryMode, depth + 1, ctx);\n }\n\n // Headers\n if (op.headers) {\n serializeParamSource(lines, 'headers', op.headers, op.headersMode, depth + 1, ctx);\n }\n\n // Request\n if (op.request) {\n serializeRequest(lines, op.request, depth + 1);\n }\n\n // Responses\n if (op.responses.length > 0) {\n serializeResponses(lines, op.responses, depth + 1);\n }\n\n lines.push(`${indent}}`);\n return lines;\n}\n\nfunction serializeModifiers(modifiers?: RouteModifier[]): string {\n if (!modifiers || modifiers.length === 0) return '';\n return `(${modifiers.join(', ')})`;\n}\n\nfunction serializeParamSource(lines: string[], keyword: string, source: ParamSource, mode: ObjectMode | undefined, depth: number, ctx: Ctx): void {\n const indent = INDENT.repeat(depth);\n\n // String reference: `query: TypeName`\n if (source.kind === 'ref') {\n lines.push(`${indent}${keyword}: ${source.name}`);\n return;\n }\n\n // ContractTypeNode reference\n if (source.kind === 'type') {\n lines.push(`${indent}${keyword}: ${serializeType(source.node)}`);\n return;\n }\n\n // Inline param declarations: `params: { name: type }`\n const modeStr = mode ? `mode(${mode}) ` : '';\n lines.push(`${indent}${keyword}: ${modeStr}{`);\n for (const param of source.nodes) {\n const optional = param.optional ? '?' : '';\n let typeStr = serializeType(param.type);\n if (param.nullable && !typeContainsNull(param.type)) {\n typeStr = `${typeStr} | null`;\n }\n const defaultVal = param.default !== undefined ? ` = ${serializeDefault(param.default)}` : '';\n const comment = ctx.includeComments && param.description ? ` # ${param.description}` : '';\n lines.push(`${INDENT.repeat(depth + 1)}${param.name}${optional}: ${typeStr}${defaultVal}${comment}`);\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeRequest(lines: string[], request: OpRequestNode, depth: number): void {\n const indent = INDENT.repeat(depth);\n lines.push(`${indent}request: {`);\n for (const body of request.bodies) {\n lines.push(`${INDENT.repeat(depth + 1)}${body.contentType}: ${serializeType(body.bodyType)}`);\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeResponses(lines: string[], responses: OpResponseNode[], depth: number): void {\n const indent = INDENT.repeat(depth);\n lines.push(`${indent}response: {`);\n for (const resp of responses) {\n const hasBody = resp.bodyType && resp.contentType;\n const hasHeaders = resp.headers && resp.headers.length > 0;\n if (hasBody || hasHeaders) {\n lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}: {`);\n if (hasBody) {\n lines.push(`${INDENT.repeat(depth + 2)}${resp.contentType}: ${serializeType(resp.bodyType!)}`);\n }\n if (hasHeaders) {\n lines.push(`${INDENT.repeat(depth + 2)}headers: {`);\n for (const h of resp.headers!) {\n const opt = h.optional ? '?' : '';\n const trail = h.description ? ` # ${h.description}` : '';\n lines.push(`${INDENT.repeat(depth + 3)}${h.name}${opt}: ${serializeType(h.type)}${trail}`);\n }\n lines.push(`${INDENT.repeat(depth + 2)}}`);\n }\n lines.push(`${INDENT.repeat(depth + 1)}}`);\n } else {\n lines.push(`${INDENT.repeat(depth + 1)}${resp.statusCode}:`);\n }\n }\n lines.push(`${indent}}`);\n}\n\nfunction serializeSecurityBlock(lines: string[], security: SecurityNode, depth: number, ctx: Ctx): void {\n const indent = INDENT.repeat(depth);\n if (security === 'none') {\n lines.push(`${indent}security: none`);\n return;\n }\n\n const sec = security as SecurityFields;\n if (sec.policy !== undefined) {\n const comment = ctx.includeComments && sec.policyDescription ? ` # ${sec.policyDescription}` : '';\n const value = sec.policy === false ? 'none' : sec.policy;\n lines.push(`${indent}security: {`);\n lines.push(`${INDENT.repeat(depth + 1)}policy: ${value}${comment}`);\n lines.push(`${indent}}`);\n } else {\n lines.push(`${indent}security: {}`);\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport type { ConvertOptions, ConvertResult, NormalizedDocument } from './types.js';\nimport { WarningCollector } from './warnings.js';\nimport { normalize } from './normalize.js';\nimport { detectCircularRefs } from './circular-refs.js';\nimport { schemasToModels, sanitizeName } from './schema-to-ast.js';\nimport type { SchemaContext } from './schema-to-ast.js';\nimport { pathsToRoutes } from './paths-to-ast.js';\nimport { splitByTag, mergeIntoSingle } from './tag-splitter.js';\nimport { astToCk } from './ast-to-ck.js';\nimport type { NormalizedSchema } from './types.js';\nimport type { ModelNode } from '@contractkit/core';\n\n/**\n * Convert an OpenAPI spec (2.0, 3.0, or 3.1) to Contract Kit .ck source files.\n */\nexport async function convertOpenApiToCk(options: ConvertOptions): Promise<ConvertResult> {\n const { split = 'by-tag', includeComments = true } = options;\n const warnings = new WarningCollector(options.onWarning);\n\n // Step 1: Parse the input into a document object\n const rawDoc = await parseInput(options.input);\n\n // Step 2: Normalize to 3.1 shape\n const doc = normalize(rawDoc, warnings);\n\n // Step 3: Sanitize schema names\n const schemas = sanitizeSchemaNames(doc, warnings);\n\n // Step 4: Detect circular references\n const circularRefs = detectCircularRefs(schemas);\n\n // Step 5: Convert schemas to model AST nodes\n const extractedModels: ModelNode[] = [];\n const schemaCtx: SchemaContext = {\n circularRefs,\n warnings,\n path: '#/components/schemas',\n includeComments,\n namedSchemas: schemas,\n extractedModels,\n inlineCounter: 0,\n };\n\n const models = schemasToModels(schemas, schemaCtx);\n\n // Step 6: Convert paths to route AST nodes\n const { routes, routeTags } = pathsToRoutes(doc, {\n circularRefs,\n warnings,\n includeComments,\n namedSchemas: schemas,\n extractedModels,\n globalSecurity: doc.security,\n });\n\n // Step 7: Split or merge\n const files = new Map<string, string>();\n\n if (split === 'by-tag') {\n const ckRoots = splitByTag(models, routes, routeTags);\n for (const [filename, root] of ckRoots) {\n files.set(filename, astToCk(root, { includeComments }));\n }\n } else {\n const root = mergeIntoSingle(models, routes);\n files.set('api.ck', astToCk(root, { includeComments }));\n }\n\n return { files, warnings: warnings.warnings };\n}\n\n// ─── Input Parsing ────────────────────────────────────────────────────────\n\nasync function parseInput(input: string | Record<string, unknown>): Promise<Record<string, unknown>> {\n // Already a parsed object\n if (typeof input === 'object') {\n return input;\n }\n\n // Try as a file path first\n try {\n const content = readFileSync(input, 'utf-8');\n return parseJsonOrYaml(content);\n } catch {\n // Not a file path — try parsing as JSON/YAML string\n return parseJsonOrYaml(input);\n }\n}\n\nfunction parseJsonOrYaml(content: string): Record<string, unknown> {\n // Try JSON first (faster)\n try {\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n // Fall back to YAML\n return parseYaml(content) as Record<string, unknown>;\n }\n}\n\n// ─── Schema Name Sanitization ─────────────────────────────────────────────\n\nfunction sanitizeSchemaNames(doc: NormalizedDocument, warnings: WarningCollector): Record<string, NormalizedSchema> {\n const original = doc.components?.schemas ?? {};\n const sanitized: Record<string, NormalizedSchema> = {};\n const nameMap = new Map<string, string>(); // original → sanitized\n\n for (const name of Object.keys(original)) {\n const clean = sanitizeName(name, warnings);\n if (sanitized[clean]) {\n warnings.warn(`#/components/schemas/${name}`, `Name collision after sanitization: \"${name}\" and another schema both map to \"${clean}\"`);\n // Disambiguate with a suffix\n let i = 2;\n while (sanitized[`${clean}${i}`]) i++;\n nameMap.set(name, `${clean}${i}`);\n sanitized[`${clean}${i}`] = original[name] as NormalizedSchema;\n } else {\n nameMap.set(name, clean);\n sanitized[clean] = original[name] as NormalizedSchema;\n }\n }\n\n // Update $refs in the document to use sanitized names\n if (nameMap.size > 0) {\n updateRefs(doc, nameMap);\n }\n\n return sanitized;\n}\n\nfunction updateRefs(obj: unknown, nameMap: Map<string, string>): void {\n if (!obj || typeof obj !== 'object') return;\n if (Array.isArray(obj)) {\n for (const item of obj) updateRefs(item, nameMap);\n return;\n }\n\n const record = obj as Record<string, unknown>;\n if (typeof record.$ref === 'string') {\n const match = record.$ref.match(/^#\\/components\\/schemas\\/(.+)$/);\n if (match?.[1] && nameMap.has(match[1])) {\n record.$ref = `#/components/schemas/${nameMap.get(match[1])}`;\n }\n }\n\n for (const value of Object.values(record)) {\n updateRefs(value, nameMap);\n }\n}\n","import type { Warning } from './types.js';\n\nexport class WarningCollector {\n readonly warnings: Warning[] = [];\n private onWarning?: (w: Warning) => void;\n\n constructor(onWarning?: (w: Warning) => void) {\n this.onWarning = onWarning;\n }\n\n warn(path: string, message: string): void {\n this.add({ path, message, severity: 'warn' });\n }\n\n info(path: string, message: string): void {\n this.add({ path, message, severity: 'info' });\n }\n\n private add(warning: Warning): void {\n this.warnings.push(warning);\n this.onWarning?.(warning);\n }\n}\n"],"mappings":";;;;AAWO,SAASA,UAAUC,KAA8BC,UAA0B;AAC9E,QAAMC,UAAUC,cAAcH,GAAAA;AAE9B,MAAIE,YAAY,OAAO;AACnB,WAAOE,kBAAkBJ,KAAKC,QAAAA;EAClC;AACA,MAAIC,YAAY,OAAO;AACnB,WAAOG,eAAeL,KAAsCC,QAAAA;EAChE;AAEA,SAAOD;AACX;AAXgBD;AAahB,SAASI,cAAcH,KAA4B;AAC/C,MAAI,OAAOA,IAAIM,YAAY,YAAYN,IAAIM,QAAQC,WAAW,GAAA,EAAM,QAAO;AAC3E,MAAI,OAAOP,IAAIQ,YAAY,UAAU;AACjC,QAAIR,IAAIQ,QAAQD,WAAW,KAAA,EAAQ,QAAO;EAC9C;AACA,SAAO;AACX;AANSJ;AAUT,SAASC,kBAAkBJ,KAA8BC,UAA0B;AAC/E,QAAMQ,OAAQT,IAAIS,QAAoC;IAAEC,OAAO;IAAYR,SAAS;EAAQ;AAC5F,QAAMS,WAAYX,IAAIW,YAAuB;AAC7C,QAAMC,UAAWZ,IAAIY,WAAwB;IAAC;;AAC9C,QAAMC,OAAQb,IAAIa,QAAmB;AACrC,QAAMC,iBAAkBd,IAAIe,YAAyB;IAAC;;AACtD,QAAMC,iBAAkBhB,IAAIiB,YAAyB;IAAC;;AAEtD,QAAMC,SAA6B;IAC/BV,SAAS;IACTC,MAAM;MACFC,OAAQD,KAAKC,SAAoB;MACjCR,SAAUO,KAAKP,WAAsB;MACrCiB,aAAaV,KAAKU;IACtB;IACAC,SAAS;MAAC;QAAEC,KAAK,GAAGT,QAAQ,CAAA,CAAE,MAAMC,IAAAA,GAAOF,QAAAA;MAAW;;IACtDW,OAAO,CAAC;IACRC,YAAY;MACRC,SAAS,CAAC;MACVC,iBAAiB,CAAC;IACtB;IACAC,MAAO1B,IAAI0B,QAAuC,CAAA;EACtD;AAGA,QAAMC,cAAe3B,IAAI2B,eAA2C,CAAC;AACrE,aAAW,CAACC,MAAMC,MAAAA,KAAWC,OAAOC,QAAQJ,WAAAA,GAAc;AACtDT,WAAOK,WAAYC,QAASI,IAAAA,IAAQI,oBAAoBH,MAAAA;EAC5D;AAGA,QAAMI,UAAWjC,IAAIkC,uBAAmD,CAAC;AACzE,aAAW,CAACN,MAAMO,MAAAA,KAAWL,OAAOC,QAAQE,OAAAA,GAAU;AAClDf,WAAOK,WAAYE,gBAAiBG,IAAAA,IAAQQ,uBAAuBD,MAAAA;EACvE;AAGA,QAAMb,QAAStB,IAAIsB,SAAqD,CAAC;AACzE,aAAW,CAACe,MAAMC,QAAAA,KAAaR,OAAOC,QAAQT,KAAAA,GAAQ;AAClDJ,WAAOI,MAAOe,IAAAA,IAAQE,mBAAmBD,UAAUxB,gBAAgBE,gBAAgBf,QAAAA;EACvF;AAGA,MAAID,IAAIwC,UAAU;AACdtB,WAAOsB,WAAWxC,IAAIwC;EAC1B;AAEA,SAAOtB;AACX;AAhDSd;AAkDT,SAASmC,mBACLD,UACAxB,gBACAE,gBACAf,UAA0B;AAE1B,QAAMwC,UAAU;IAAC;IAAO;IAAQ;IAAO;IAAS;IAAU;IAAQ;;AAClE,QAAMC,aAAsC,CAAC;AAG7C,QAAMC,aAAcL,SAASM,cAA4B,CAAA;AAEzD,aAAWC,UAAUJ,SAAS;AAC1B,UAAMK,KAAKR,SAASO,MAAAA;AACpB,QAAI,CAACC,GAAI;AAET,UAAMC,aAAcD,GAAG/B,YAAyBD;AAChD,UAAMkC,aAAcF,GAAG7B,YAAyBD;AAChD,UAAMiC,SAAS;SAAIN;SAAiBG,GAAGF,cAA4B,CAAA;;AAGnE,UAAMM,gBAA2B,CAAA;AACjC,QAAIC;AAEJ,eAAWC,SAASH,QAAqC;AACrD,UAAIG,MAAMC,OAAO,QAAQ;AACrB,cAAMC,cAAcP,WAAW,CAAA,KAAM;AACrCI,sBAAc;UACVhC,aAAaiC,MAAMjC;UACnBoC,UAAUH,MAAMG,YAAY;UAC5BC,SAAS;YACL,CAACF,WAAAA,GAAc;cACXzB,QAAQG,oBAAqBoB,MAAMvB,UAAsC,CAAC,CAAA;YAC9E;UACJ;QACJ;MACJ,WAAWuB,MAAMC,OAAO,YAAY;AAChCpD,iBAASQ,KAAK,WAAWgD,kBAAkBZ,MAAAA,CAAAA,IAAW,kEAAA;AAEtD,YAAI,CAACM,aAAa;AACdA,wBAAc;YACVK,SAAS;cACL,uBAAuB;gBACnB3B,QAAQ;kBAAE6B,MAAM;kBAAUC,YAAY,CAAC;kBAAGJ,UAAU,CAAA;gBAAe;cACvE;YACJ;UACJ;QACJ;AACA,cAAMK,aAAcT,YAAYK,QAAoD,qBAAA,EAAwB3B;AAI5G,cAAMgC,QAAQD,WAAWD;AACzBE,cAAMT,MAAMxB,IAAI,IAAcI,oBAAoBoB,KAAAA;AAClD,YAAIA,MAAMG,UAAU;AACfK,qBAAWL,SAAsBO,KAAKV,MAAMxB,IAAI;QACrD;MACJ,OAAO;AAEH,cAAMmC,kBAAkB;UAAE,GAAGX;QAAM;AACnC,YAAIA,MAAMM,MAAM;AACZK,0BAAgBlC,SAASG,oBAAoB;YACzC0B,MAAMN,MAAMM;YACZM,QAAQZ,MAAMY;YACdC,MAAMb,MAAMa;YACZC,OAAOd,MAAMc;YACbC,SAASf,MAAMe;YACfC,SAAShB,MAAMgB;YACfC,SAASjB,MAAMiB;YACfC,WAAWlB,MAAMkB;YACjBC,WAAWnB,MAAMmB;YACjBC,SAASpB,MAAMoB;UACnB,CAAA;AACA,iBAAOT,gBAAgBL;AACvB,iBAAOK,gBAAgBC;AACvB,iBAAOD,gBAAgBE;AACvB,iBAAOF,gBAAgBG;QAC3B;AACAhB,sBAAcY,KAAKC,eAAAA;MACvB;IACJ;AAGA,UAAMU,YAAqC,CAAC;AAC5C,UAAMC,cAAe5B,GAAG2B,aAAyD,CAAC;AAClF,eAAW,CAACE,MAAMC,IAAAA,KAAS9C,OAAOC,QAAQ2C,WAAAA,GAAc;AACpD,YAAMpB,cAAcN,WAAW,CAAA,KAAM;AACrC,YAAM6B,UAAUC,wBAAwBF,KAAKC,OAAO;AACpD,YAAME,gBAAyC;QAC3C5D,aAAayD,KAAKzD,eAAe;MACrC;AACA,UAAIyD,KAAK/C,QAAQ;AACbkD,sBAAcvB,UAAU;UACpB,CAACF,WAAAA,GAAc;YACXzB,QAAQG,oBAAoB4C,KAAK/C,MAAM;UAC3C;QACJ;MACJ;AACA,UAAIgD,SAAS;AACTE,sBAAcF,UAAUA;MAC5B;AACAJ,gBAAUE,IAAAA,IAAQI;IACtB;AAEArC,eAAWG,MAAAA,IAAU;MACjBmC,aAAalC,GAAGkC;MAChBC,SAASnC,GAAGmC;MACZ9D,aAAa2B,GAAG3B;MAChBO,MAAMoB,GAAGpB;MACTkB,YAAYM,cAAcgC,SAAS,IAAIhC,gBAAgBiC;MACvDhC;MACAsB;MACAjC,UAAUM,GAAGN;MACb4C,YAAYtC,GAAGsC;IACnB;EACJ;AAEA,SAAO1C;AACX;AAtHSH;AA4HT,SAASuC,wBACLD,SAA4D;AAE5D,MAAI,CAACA,QAAS,QAAOM;AACrB,QAAME,MAA+C,CAAC;AACtD,aAAW,CAACzD,MAAM0D,MAAAA,KAAWxD,OAAOC,QAAQ8C,OAAAA,GAAU;AAClD,QAAI,CAACS,UAAU,OAAOA,WAAW,SAAU;AAC3C,UAAM,EAAEnE,aAAauC,MAAMM,QAAQE,OAAO,GAAGqB,KAAAA,IAASD;AACtD,UAAMzD,SAAkC;MAAE,GAAG0D;IAAK;AAClD,QAAI7B,SAASyB,OAAWtD,QAAO6B,OAAOA;AACtC,QAAIM,WAAWmB,OAAWtD,QAAOmC,SAASA;AAC1C,QAAIE,UAAUiB,OAAWtD,QAAOqC,QAAQA;AACxC,UAAMxB,aAAsC,CAAC;AAC7C,QAAIvB,gBAAgBgE,OAAWzC,YAAWvB,cAAcA;AACxD,QAAIW,OAAO0D,KAAK3D,MAAAA,EAAQqD,SAAS,EAAGxC,YAAWb,SAASG,oBAAoBH,MAAAA;AAC5EwD,QAAIzD,IAAAA,IAAQc;EAChB;AACA,SAAOZ,OAAO0D,KAAKH,GAAAA,EAAKH,SAAS,IAAIG,MAAMF;AAC/C;AAlBSL;AAoBT,SAAS1C,uBAAuBD,QAA+B;AAC3D,QAAMuB,OAAOvB,OAAOuB;AACpB,MAAIA,SAAS,SAAS;AAClB,WAAO;MAAEA,MAAM;MAAQvB,QAAQ;IAAQ;EAC3C;AACA,MAAIuB,SAAS,UAAU;AACnB,WAAO;MAAEA,MAAM;MAAU9B,MAAMO,OAAOP;MAAMyB,IAAIlB,OAAOkB;IAAG;EAC9D;AACA,MAAIK,SAAS,UAAU;AACnB,UAAM+B,OAAOtD,OAAOsD;AACpB,UAAMC,QAAiC,CAAC;AACxC,QAAID,SAAS,YAAY;AACrBC,YAAMC,WAAW;QAAEC,kBAAkBzD,OAAOyD;QAAkBC,QAAQ1D,OAAO0D,UAAU,CAAC;MAAE;IAC9F,WAAWJ,SAAS,YAAY;AAC5BC,YAAMI,WAAW;QAAEC,UAAU5D,OAAO4D;QAAUF,QAAQ1D,OAAO0D,UAAU,CAAC;MAAE;IAC9E,WAAWJ,SAAS,eAAe;AAC/BC,YAAMM,oBAAoB;QAAED,UAAU5D,OAAO4D;QAAUF,QAAQ1D,OAAO0D,UAAU,CAAC;MAAE;IACvF,WAAWJ,SAAS,cAAc;AAC9BC,YAAMO,oBAAoB;QACtBL,kBAAkBzD,OAAOyD;QACzBG,UAAU5D,OAAO4D;QACjBF,QAAQ1D,OAAO0D,UAAU,CAAC;MAC9B;IACJ;AACA,WAAO;MAAEnC,MAAM;MAAUgC;IAAM;EACnC;AACA,SAAOvD;AACX;AA3BSC;AA+BT,SAAS/B,eAAeL,KAAyBkG,WAA2B;AAExE,MAAIlG,IAAIuB,YAAYC,SAAS;AACzB,eAAW,CAACI,MAAMC,MAAAA,KAAWC,OAAOC,QAAQ/B,IAAIuB,WAAWC,OAAO,GAAG;AACjExB,UAAIuB,WAAWC,QAAQI,IAAAA,IAAQI,oBAAoBH,MAAAA;IACvD;EACJ;AAGA,MAAI7B,IAAIsB,OAAO;AACX,eAAWgB,YAAYR,OAAOqE,OAAOnG,IAAIsB,KAAK,GAAG;AAC7C8E,+BAAyB9D,QAAAA;IAC7B;EACJ;AAEAtC,MAAIQ,UAAU;AACd,SAAOR;AACX;AAjBSK;AAmBT,SAAS+F,yBAAyB9D,UAAiC;AAC/D,QAAMG,UAAU;IAAC;IAAO;IAAQ;IAAO;IAAS;IAAU;IAAQ;;AAClE,aAAWI,UAAUJ,SAAS;AAC1B,UAAMK,KAAKR,SAASO,MAAAA;AACpB,QAAI,CAACC,GAAI;AAGT,UAAMG,SAAUH,GAAGF,cAA4C,CAAA;AAC/D,eAAWQ,SAASH,QAAQ;AACxB,UAAIG,MAAMvB,QAAQ;AACduB,cAAMvB,SAASG,oBAAoBoB,MAAMvB,MAAM;MACnD;IACJ;AAGA,UAAMwE,UAAUvD,GAAGK;AACnB,QAAIkD,SAAS7C,SAAS;AAClB,iBAAW8C,aAAaxE,OAAOqE,OAAOE,QAAQ7C,OAAO,GAA8C;AAC/F,YAAI8C,UAAUzE,QAAQ;AAClByE,oBAAUzE,SAASG,oBAAoBsE,UAAUzE,MAAM;QAC3D;MACJ;IACJ;AAGA,UAAM4C,YAAa3B,GAAG2B,aAAyD,CAAC;AAChF,eAAWG,QAAQ9C,OAAOqE,OAAO1B,SAAAA,GAAY;AACzC,UAAIG,KAAKpB,SAAS;AACd,mBAAW8C,aAAaxE,OAAOqE,OAAOvB,KAAKpB,OAAO,GAA8C;AAC5F,cAAI8C,UAAUzE,QAAQ;AAClByE,sBAAUzE,SAASG,oBAAoBsE,UAAUzE,MAAM;UAC3D;QACJ;MACJ;IACJ;EACJ;AACJ;AApCSuE;AA0CT,SAASpE,oBAAoBH,QAA+B;AACxD,MAAI,CAACA,UAAU,OAAOA,WAAW,SAAU,QAAOA;AAElD,QAAMX,SAAS;IAAE,GAAGW;EAAO;AAG3B,MAAIX,OAAOqF,aAAa,QAAQ,OAAOrF,OAAOwC,SAAS,UAAU;AAC7DxC,WAAOwC,OAAO;MAACxC,OAAOwC;MAAM;;AAC5B,WAAOxC,OAAOqF;EAClB;AAMA,MAAIrF,OAAOyC,cAAc,OAAOzC,OAAOyC,eAAe,UAAU;AAC5D,UAAME,QAAQ3C,OAAOyC;AACrB,eAAW,CAAC6C,KAAKC,GAAAA,KAAQ3E,OAAOC,QAAQ8B,KAAAA,GAAQ;AAC5CA,YAAM2C,GAAAA,IAAOxE,oBAAoByE,GAAAA;IACrC;EACJ;AACA,MAAIvF,OAAOgD,SAAS,OAAOhD,OAAOgD,UAAU,YAAY,CAACwC,MAAMC,QAAQzF,OAAOgD,KAAK,GAAG;AAClFhD,WAAOgD,QAAQlC,oBAAoBd,OAAOgD,KAAK;EACnD;AACA,MAAIhD,OAAO0F,wBAAwB,OAAO1F,OAAO0F,yBAAyB,UAAU;AAChF1F,WAAO0F,uBAAuB5E,oBAAoBd,OAAO0F,oBAAoB;EACjF;AACA,aAAWC,YAAY;IAAC;IAAS;IAAS;KAAmB;AACzD,QAAIH,MAAMC,QAAQzF,OAAO2F,QAAAA,CAAS,GAAG;AACjC3F,aAAO2F,QAAAA,IAAa3F,OAAO2F,QAAAA,EAAwCC,IAAI9E,mBAAAA;IAC3E;EACJ;AAEA,SAAOd;AACX;AAlCSc;AAoCT,SAASyB,kBAAkBsD,GAAS;AAChC,SAAOA,EAAEC,QAAQ,MAAM,IAAA,EAAMA,QAAQ,OAAO,IAAA;AAChD;AAFSvD;;;AC/VF,SAASwD,mBAAmBC,SAAgC;AAC/D,QAAMC,WAAW,oBAAIC,IAAAA;AACrB,QAAMC,WAAW,oBAAID,IAAAA;AACrB,QAAME,UAAU,oBAAIF,IAAAA;AAEpB,WAASG,MAAMC,MAAY;AACvB,QAAIF,QAAQG,IAAID,IAAAA,EAAO;AACvB,QAAIH,SAASI,IAAID,IAAAA,GAAO;AACpBL,eAASO,IAAIF,IAAAA;AACb;IACJ;AAEAH,aAASK,IAAIF,IAAAA;AACb,UAAMG,SAAST,QAAQM,IAAAA;AACvB,QAAIG,UAAU,OAAOA,WAAW,UAAU;AACtC,iBAAWC,OAAOC,YAAYF,MAAAA,GAAoC;AAC9D,cAAMG,UAAUC,eAAeH,GAAAA;AAC/B,YAAIE,WAAWZ,QAAQY,OAAAA,GAAU;AAC7BP,gBAAMO,OAAAA;QACV;MACJ;IACJ;AACAT,aAASW,OAAOR,IAAAA;AAChBF,YAAQI,IAAIF,IAAAA;EAChB;AAnBSD;AAqBT,aAAWC,QAAQS,OAAOC,KAAKhB,OAAAA,GAAU;AACrCK,UAAMC,IAAAA;EACV;AAEA,SAAOL;AACX;AA/BgBF;AAoChB,SAASY,YAAYM,KAA4B;AAC7C,QAAMC,OAAiB,CAAA;AAEvB,WAASC,KAAKC,KAAY;AACtB,QAAI,CAACA,OAAO,OAAOA,QAAQ,SAAU;AACrC,QAAIC,MAAMC,QAAQF,GAAAA,GAAM;AACpB,iBAAWG,QAAQH,IAAKD,MAAKI,IAAAA;AAC7B;IACJ;AACA,UAAMC,SAASJ;AACf,QAAI,OAAOI,OAAOC,SAAS,UAAU;AACjCP,WAAKQ,KAAKF,OAAOC,IAAI;IACzB;AACA,eAAWE,KAAKZ,OAAOa,OAAOJ,MAAAA,GAAS;AACnCL,WAAKQ,CAAAA;IACT;EACJ;AAbSR;AAeTA,OAAKF,GAAAA;AACL,SAAOC;AACX;AApBSP;AA0BF,SAASE,eAAeH,KAAW;AACtC,QAAMmB,QAAQnB,IAAImB,MAAM,gDAAA;AACxB,SAAOA,QAAQ,CAAA;AACnB;AAHgBhB;;;AC3ChB,IAAMiB,MAAsB;EAAEC,MAAM;EAAIC,MAAM;AAAE;AAIhD,IAAMC,mBAA2D;EAC7DC,OAAO;EACPC,KAAK;EACLC,KAAK;EACLC,MAAM;EACNC,MAAM;EACN,aAAa;EACbC,MAAM;EACNC,QAAQ;EACRC,OAAO;AACX;AAOO,SAASC,gBAAgBC,SAA2CC,KAAkB;AACzF,QAAMC,SAAsB,CAAA;AAE5B,aAAW,CAACC,MAAMC,MAAAA,KAAWC,OAAOC,QAAQN,OAAAA,GAAU;AAClD,UAAMO,WAAW;MAAE,GAAGN;MAAKO,MAAM,wBAAwBL,IAAAA;IAAO;AAChE,UAAMM,QAAQC,cAAcP,MAAMC,QAAQG,QAAAA;AAC1C,QAAIE,MAAOP,QAAOS,KAAKF,KAAAA;EAC3B;AAGAP,SAAOS,KAAI,GAAIV,IAAIW,eAAe;AAElC,SAAOV;AACX;AAbgBH;AAkBhB,SAASW,cAAcP,MAAcC,QAA0BH,KAAkB;AAC7EY,kBAAgBT,QAAQH,GAAAA;AAExB,QAAMa,cAAcb,IAAIc,kBAAkBX,OAAOU,cAAcE;AAG/D,MAAIZ,OAAOa,SAASb,OAAOa,MAAMC,WAAW,GAAG;AAC3C,UAAM,CAACC,OAAOC,MAAAA,IAAUhB,OAAOa;AAC/B,UAAMI,YAAYF,OAAOG,OAAOH,QAAQC,QAAQE,OAAOF,SAAS;AAChE,UAAMG,eAAeJ,OAAOG,OAAOF,SAASD;AAE5C,QAAIE,WAAWC,QAAQC,cAAcC,YAAY;AAC7C,YAAMC,WAAWC,eAAeL,UAAUC,IAAI;AAC9C,UAAIG,UAAU;AACV,cAAME,SAASC,yBAAyBL,cAActB,GAAAA;AACtD,eAAO;UACH4B,MAAM;UACN1B;UACA2B,OAAO;YAACL;;UACRE;UACAb;UACAiB,KAAK5C;QACT;MACJ;IACJ;EACJ;AAGA,MAAIiB,OAAOoB,cAAepB,OAAO4B,SAAS,YAAY,CAAC5B,OAAO6B,sBAAuB;AACjF,UAAMN,SAASC,yBAAyBxB,QAAQH,GAAAA;AAChD,WAAO;MACH4B,MAAM;MACN1B;MACAwB;MACAb;MACAiB,KAAK5C;IACT;EACJ;AAGA,QAAM+C,WAAWC,iBAAiB/B,QAAQH,GAAAA;AAC1C,SAAO;IACH4B,MAAM;IACN1B;IACAwB,QAAQ,CAAA;IACRK,MAAME;IACNpB;IACAiB,KAAK5C;EACT;AACJ;AAjDSuB;AAsDF,SAASyB,iBAAiB/B,QAA0BH,KAAkB;AAEzE,MAAIG,OAAOkB,MAAM;AACb,UAAMc,UAAUV,eAAetB,OAAOkB,IAAI;AAC1C,QAAIc,SAAS;AACT,UAAInC,IAAIoC,aAAaC,IAAIF,OAAAA,GAAU;AAC/B,eAAO;UAAEP,MAAM;UAAQU,OAAO;YAAEV,MAAM;YAAO1B,MAAMiC;UAAQ;QAAE;MACjE;AACA,aAAO;QAAEP,MAAM;QAAO1B,MAAMiC;MAAQ;IACxC;AACAnC,QAAIuC,SAASC,KAAKxC,IAAIO,MAAM,sBAAsBJ,OAAOkB,IAAI,EAAE;AAC/D,WAAO;MAAEO,MAAM;MAAU1B,MAAM;IAAU;EAC7C;AAGA,MAAIC,OAAOsC,UAAU1B,QAAW;AAC5B,WAAO;MAAEa,MAAM;MAAWc,OAAOvC,OAAOsC;IAAmC;EAC/E;AAGA,MAAItC,OAAOwC,MAAM;AACb,WAAO;MAAEf,MAAM;MAAQgB,QAAQzC,OAAOwC,KAAKE,IAAIC,MAAAA;IAAQ;EAC3D;AAGA,MAAI3C,OAAO4C,SAAS5C,OAAO4C,MAAM9B,SAAS,GAAG;AACzC,QAAId,OAAO6C,eAAeC,cAAc;AACpC,aAAOC,qBAAqB/C,OAAO4C,OAAO5C,OAAO6C,cAAcC,cAAcjD,GAAAA;IACjF;AACA,WAAOmD,QAAQhD,OAAO4C,OAAO/C,GAAAA;EACjC;AACA,MAAIG,OAAOiD,SAASjD,OAAOiD,MAAMnC,SAAS,GAAG;AACzC,QAAId,OAAO6C,eAAeC,cAAc;AACpC,aAAOC,qBAAqB/C,OAAOiD,OAAOjD,OAAO6C,cAAcC,cAAcjD,GAAAA;IACjF;AACA,WAAOmD,QAAQhD,OAAOiD,OAAOpD,GAAAA;EACjC;AAGA,MAAIG,OAAOa,SAASb,OAAOa,MAAMC,SAAS,GAAG;AACzC,QAAId,OAAOa,MAAMC,WAAW,GAAG;AAC3B,aAAOiB,iBAAiB/B,OAAOa,MAAM,CAAA,GAAKhB,GAAAA;IAC9C;AACA,WAAO;MACH4B,MAAM;MACNyB,SAASlD,OAAOa,MAAM6B,IAAIS,CAAAA,MAAKpB,iBAAiBoB,GAAGtD,GAAAA,CAAAA;IACvD;EACJ;AAGA,QAAMuD,QAAQC,mBAAmBrD,MAAAA;AAEjC,MAAIoD,UAAU,MAAM;AAEhB,QAAIpD,OAAOoB,YAAY;AACnB,aAAOkC,qBAAqBtD,QAAQH,GAAAA;IACxC;AACA,WAAO;MAAE4B,MAAM;MAAU1B,MAAM;IAAU;EAC7C;AAEA,QAAM,EAAEwD,UAAUC,SAAQ,IAAKJ;AAE/B,MAAItB;AAEJ,UAAQyB,UAAAA;IACJ,KAAK;AACDzB,iBAAW2B,mBAAmBzD,MAAAA;AAC9B;IACJ,KAAK;AACD8B,iBAAW4B,oBAAoB1D,MAAAA;AAC/B;IACJ,KAAK;AACD8B,iBAAW6B,mBAAmB3D,MAAAA;AAC9B;IACJ,KAAK;AACD8B,iBAAW;QAAEL,MAAM;QAAU1B,MAAM;MAAU;AAC7C;IACJ,KAAK;AACD+B,iBAAW;QAAEL,MAAM;QAAU1B,MAAM;MAAO;AAC1C;IACJ,KAAK;AACD+B,iBAAW8B,kBAAkB5D,QAAQH,GAAAA;AACrC;IACJ,KAAK;AACDiC,iBAAW+B,mBAAmB7D,QAAQH,GAAAA;AACtC;IACJ;AACIA,UAAIuC,SAASC,KAAKxC,IAAIO,MAAM,iBAAiBmD,QAAAA,EAAU;AACvDzB,iBAAW;QAAEL,MAAM;QAAU1B,MAAM;MAAU;EACrD;AAEA,MAAIyD,UAAU;AACV,WAAO;MAAE/B,MAAM;MAASyB,SAAS;QAACpB;QAAU;UAAEL,MAAM;UAAU1B,MAAM;QAAO;;IAAG;EAClF;AAEA,SAAO+B;AACX;AAhGgBC;AAoGhB,SAAS0B,mBAAmBzD,QAAwB;AAEhD,MAAIA,OAAO8D,QAAQ;AACf,UAAMC,aAAa7E,iBAAiBc,OAAO8D,MAAM;AACjD,QAAIC,YAAY;AACZ,aAAO;QAAEtC,MAAM;QAAU1B,MAAMgE;MAAW;IAC9C;EACJ;AAEA,QAAMC,OAAgC,CAAC;AACvC,MAAIhE,OAAOiE,cAAcrD,UAAaZ,OAAOkE,cAActD,UAAaZ,OAAOiE,cAAcjE,OAAOkE,WAAW;AAC3GF,SAAKG,MAAMnE,OAAOiE;EACtB,OAAO;AACH,QAAIjE,OAAOiE,cAAcrD,OAAWoD,MAAKI,MAAMpE,OAAOiE;AACtD,QAAIjE,OAAOkE,cAActD,OAAWoD,MAAKK,MAAMrE,OAAOkE;EAC1D;AACA,MAAIlE,OAAOsE,QAASN,MAAKO,QAAQ,IAAIvE,OAAOsE,OAAO;AACnD,MAAItE,OAAO8D,UAAU,CAAC5E,iBAAiBc,OAAO8D,MAAM,EAAGE,MAAKF,SAAS9D,OAAO8D;AAE5E,SAAO;IAAErC,MAAM;IAAU1B,MAAM;IAAU,GAAGiE;EAAK;AACrD;AApBSP;AAsBT,SAASC,oBAAoB1D,QAAwB;AACjD,QAAMD,OAA+BC,OAAO8D,WAAW,UAAU,WAAW;AAC5E,QAAME,OAAgC,CAAC;AACvC,MAAIhE,OAAOwE,YAAY5D,OAAWoD,MAAKI,MAAMpE,OAAOwE;AACpD,MAAIxE,OAAOyE,YAAY7D,OAAWoD,MAAKK,MAAMrE,OAAOyE;AACpD,SAAO;IAAEhD,MAAM;IAAU1B;IAAM,GAAGiE;EAAK;AAC3C;AANSN;AAQT,SAASC,mBAAmB3D,QAAwB;AAChD,QAAMgE,OAAgC,CAAC;AACvC,MAAIhE,OAAOwE,YAAY5D,OAAWoD,MAAKI,MAAMpE,OAAOwE;AACpD,MAAIxE,OAAOyE,YAAY7D,OAAWoD,MAAKK,MAAMrE,OAAOyE;AACpD,SAAO;IAAEhD,MAAM;IAAU1B,MAAM;IAAU,GAAGiE;EAAK;AACrD;AALSL;AAOT,SAASC,kBAAkB5D,QAA0BH,KAAkB;AAEnE,MAAIG,OAAO0E,eAAe1E,OAAO0E,YAAY5D,SAAS,GAAG;AACrD,WAAO;MACHW,MAAM;MACNkD,OAAO3E,OAAO0E,YAAYhC,IAAIS,CAAAA,MAAKpB,iBAAiBoB,GAAGtD,GAAAA,CAAAA;IAC3D;EACJ;AAEA,QAAM+E,OAAO5E,OAAO2E,QAAQ5C,iBAAiB/B,OAAO2E,OAAO9E,GAAAA,IAAO;IAAE4B,MAAM;IAAmB1B,MAAM;EAAmB;AACtH,QAAMiE,OAAuC,CAAC;AAC9C,MAAIhE,OAAO6E,aAAajE,OAAWoD,MAAKI,MAAMpE,OAAO6E;AACrD,MAAI7E,OAAO8E,aAAalE,OAAWoD,MAAKK,MAAMrE,OAAO8E;AAErD,SAAO;IAAErD,MAAM;IAASmD;IAAM,GAAGZ;EAAK;AAC1C;AAfSJ;AAiBT,SAASC,mBAAmB7D,QAA0BH,KAAkB;AAEpE,MAAIG,OAAO6B,wBAAwB,OAAO7B,OAAO6B,yBAAyB,YAAY,CAAC7B,OAAOoB,YAAY;AACtG,WAAO;MACHK,MAAM;MACNsD,KAAK;QAAEtD,MAAM;QAAU1B,MAAM;MAAS;MACtCwC,OAAOR,iBAAiB/B,OAAO6B,sBAAsBhC,GAAAA;IACzD;EACJ;AAGA,MAAIG,OAAOoB,YAAY;AACnB,WAAOkC,qBAAqBtD,QAAQH,GAAAA;EACxC;AAGA,SAAO;IAAE4B,MAAM;IAAU1B,MAAM;EAAS;AAC5C;AAjBS8D;AAmBT,SAASP,qBAAqBtD,QAA0BH,KAAkB;AACtE,QAAM0B,SAASC,yBAAyBxB,QAAQH,GAAAA;AAChD,SAAO;IAAE4B,MAAM;IAAgBF;EAAO;AAC1C;AAHS+B;AAOT,SAAS9B,yBAAyBxB,QAA0BH,KAAkB;AAC1E,QAAMuB,aAAapB,OAAOoB,cAAc,CAAC;AACzC,QAAM4D,WAAW,IAAIC,IAAIjF,OAAOgF,YAAY,CAAA,CAAE;AAC9C,QAAMzD,SAAsB,CAAA;AAE5B,aAAW,CAACxB,MAAMmF,UAAAA,KAAejF,OAAOC,QAAQkB,UAAAA,GAAa;AACzD,UAAM+D,UAAU;MAAE,GAAGtF;MAAKO,MAAM,GAAGP,IAAIO,IAAI,eAAeL,IAAAA;IAAO;AACjE,UAAMqF,YAAYrD,iBAAiBmD,YAAYC,OAAAA;AAG/C,QAAI3B,WAAW;AACf,QAAI6B,gBAAgBD;AACpB,QAAIA,UAAU3D,SAAS,SAAS;AAC5B,YAAM6D,UAAUF,UAAUlC,QAAQqC,OAAOC,CAAAA,MAAK,EAAEA,EAAE/D,SAAS,YAAY+D,EAAEzF,SAAS,OAAK;AACvF,UAAIuF,QAAQxE,SAASsE,UAAUlC,QAAQpC,QAAQ;AAC3C0C,mBAAW;AACX6B,wBAAgBC,QAAQxE,WAAW,IAAIwE,QAAQ,CAAA,IAAM;UAAE7D,MAAM;UAASyB,SAASoC;QAAQ;MAC3F;IACJ;AAEA,UAAMG,aAAaP,WAAWQ,WAAY,aAAuBR,WAAWS,YAAa,cAAyB;AAElHpE,WAAOhB,KAAK;MACRR;MACA6F,UAAU,CAACZ,SAAS9C,IAAInC,IAAAA;MACxByD;MACAiC;MACA7D,MAAMyD;MACNQ,SAASX,WAAWW;MACpBC,YAAYZ,WAAWY;MACvBpF,aAAab,IAAIc,kBAAkBuE,WAAWxE,cAAcE;MAC5De,KAAK5C;IACT,CAAA;EACJ;AAEA,SAAOwC;AACX;AApCSC;AAwCT,SAAS6B,mBAAmBrD,QAAwB;AAChD,MAAI,CAACA,OAAO4B,KAAM,QAAO;AAEzB,MAAI,OAAO5B,OAAO4B,SAAS,UAAU;AACjC,WAAO;MAAE2B,UAAUvD,OAAO4B;MAAM4B,UAAU;IAAM;EACpD;AAEA,MAAIuC,MAAMC,QAAQhG,OAAO4B,IAAI,GAAG;AAC5B,UAAMwB,QAAQpD,OAAO4B;AACrB,UAAM0D,UAAUlC,MAAMmC,OAAOU,CAAAA,MAAKA,MAAM,MAAA;AACxC,UAAMzC,WAAWJ,MAAM8C,SAAS,MAAA;AAChC,QAAIZ,QAAQxE,WAAW,GAAG;AACtB,aAAO;QAAEyC,UAAU+B,QAAQ,CAAA;QAAK9B;MAAS;IAC7C;AAEA,QAAI8B,QAAQxE,WAAW,GAAG;AACtB,aAAO;QAAEyC,UAAU;QAAQC,UAAU;MAAM;IAC/C;AAEA,WAAO;MAAED,UAAU+B,QAAQ,CAAA;MAAK9B;IAAS;EAC7C;AAEA,SAAO;AACX;AAvBSH;AAyBT,SAASL,QAAQpD,SAA6BC,KAAkB;AAC5D,QAAMqD,UAAUtD,QAAQ8C,IAAIS,CAAAA,MAAKpB,iBAAiBoB,GAAGtD,GAAAA,CAAAA;AACrD,MAAIqD,QAAQpC,WAAW,EAAG,QAAOoC,QAAQ,CAAA;AACzC,SAAO;IAAEzB,MAAM;IAASyB;EAAQ;AACpC;AAJSF;AAMT,SAASD,qBAAqBnD,SAA6BiD,eAAuBhD,KAAkB;AAChG,QAAMqD,UAAUtD,QAAQ8C,IAAIS,CAAAA,MAAKpB,iBAAiBoB,GAAGtD,GAAAA,CAAAA;AACrD,MAAIqD,QAAQpC,WAAW,EAAG,QAAOoC,QAAQ,CAAA;AACzC,SAAO;IAAEzB,MAAM;IAAsBoB;IAAeK;EAAQ;AAChE;AAJSH;AAMT,SAAStC,gBAAgBT,QAA0BH,KAAkB;AACjE,MAAIG,OAAOmG,IAAKtG,KAAIuC,SAASC,KAAKxC,IAAIO,MAAM,yCAAA;AAC5C,MAAIJ,OAAOoG,aAAcvG,KAAIuC,SAASiE,KAAKxG,IAAIO,MAAM,yCAAA;AACrD,MAAIJ,OAAOsG,IAAKzG,KAAIuC,SAASC,KAAKxC,IAAIO,MAAM,wCAAA;AAChD;AAJSK;AASF,SAAS8F,mBACZvG,QACAwG,eACA3G,KAAkB;AAGlB,MAAIG,OAAOkB,MAAM;AACb,WAAO;MAAEY,UAAUC,iBAAiB/B,QAAQH,GAAAA;IAAK;EACrD;AAGA,MAAIG,OAAOoB,cAAepB,OAAO4B,SAAS,YAAY5B,OAAO6B,yBAAyBjB,QAAY;AAC9F,UAAMW,SAASC,yBAAyBxB,QAAQH,GAAAA;AAChD,UAAMQ,QAAmB;MACrBoB,MAAM;MACN1B,MAAMyG;MACNjF;MACAb,aAAab,IAAIc,kBAAkBX,OAAOU,cAAcE;MACxDe,KAAK5C;IACT;AACA,WAAO;MACH+C,UAAU;QAAEL,MAAM;QAAO1B,MAAMyG;MAAc;MAC7CnG;IACJ;EACJ;AAGA,SAAO;IAAEyB,UAAUC,iBAAiB/B,QAAQH,GAAAA;EAAK;AACrD;AA5BgB0G;AAiCT,SAASE,aAAa1G,MAAcqC,UAA0B;AAEjE,QAAMsE,UAAU3G,KACX4G,QAAQ,mBAAmB,GAAA,EAC3BC,MAAM,KAAA,EACNrB,OAAOsB,OAAAA,EACPnE,IAAIoE,CAAAA,SAAQA,KAAKC,OAAO,CAAA,EAAGC,YAAW,IAAKF,KAAKG,MAAM,CAAA,CAAA,EACtDC,KAAK,EAAA;AAEV,MAAIR,YAAY3G,MAAM;AAClBqC,aAASiE,KAAK,wBAAwBtG,IAAAA,IAAQ,2BAA2BA,IAAAA,aAAY2G,OAAAA,GAAU;EACnG;AAEA,SAAOA,WAAW;AACtB;AAdgBD;;;ACxYhB,IAAMU,OAAsB;EAAEC,MAAM;EAAIC,MAAM;AAAE;AAChD,IAAMC,eAA6B;EAAC;EAAO;EAAQ;EAAO;EAAS;;AAmB5D,SAASC,cAAcC,KAAyBC,KAAiB;AACpE,QAAMC,SAAwB,CAAA;AAC9B,QAAMC,YAAY,oBAAIC,IAAAA;AACtB,QAAMC,QAAQL,IAAIK,SAAS,CAAC;AAE5B,aAAW,CAACC,MAAMC,QAAAA,KAAaC,OAAOC,QAAQJ,KAAAA,GAAQ;AAClD,QAAI,CAACE,SAAU;AACf,UAAMG,SAASC,gBAAgBL,MAAMC,UAAUN,GAAAA;AAC/C,QAAIS,QAAQ;AACRR,aAAOU,KAAKF,OAAOG,KAAK;AACxBV,gBAAUW,IAAIJ,OAAOG,OAAOH,OAAOK,GAAG;IAC1C;EACJ;AAEA,SAAO;IAAEb;IAAQC;EAAU;AAC/B;AAfgBJ;AAmBhB,SAASY,gBAAgBL,MAAcC,UAA8BN,KAAiB;AAClF,QAAMe,aAAgC,CAAA;AACtC,MAAIC,aAAa;AAGjB,QAAMC,cAAcX,SAASY,cAAc,CAAA,GAAIC,OAAOC,CAAAA,MAAKA,EAAEC,OAAO,MAAA;AAEpE,aAAWC,UAAUzB,cAAc;AAC/B,UAAM0B,KAAKjB,SAASgB,MAAAA;AACpB,QAAI,CAACC,GAAI;AAET,UAAMC,SAASC,gBAAgBH,QAAQC,IAAIlB,MAAML,GAAAA;AACjDe,eAAWJ,KAAKa,MAAAA;AAGhB,QAAID,GAAGG,QAAQH,GAAGG,KAAKC,SAAS,KAAKX,eAAe,WAAW;AAC3DA,mBAAaO,GAAGG,KAAK,CAAA;IACzB;EACJ;AAEA,MAAIX,WAAWY,WAAW,EAAG,QAAO;AAGpC,QAAMC,SAASC,gBAAgBxB,MAAMY,YAAYX,UAAUN,GAAAA;AAE3D,QAAMY,QAAqB;IACvBP;IACAU;IACAe,KAAKpC;EACT;AAEA,MAAIkC,OAAOD,SAAS,GAAG;AACnBf,UAAMgB,SAAS;MAAEG,MAAM;MAAUC,OAAOJ;IAAO;EACnD;AAEA,MAAItB,SAAS2B,eAAejC,IAAIkC,iBAAiB;AAC7CtB,UAAMqB,cAAc3B,SAAS2B;EACjC;AAEA,SAAO;IAAErB;IAAOE,KAAKE;EAAW;AACpC;AAxCSN;AA4CT,SAASe,gBAAgBH,QAAoBC,IAAyBlB,MAAcL,KAAiB;AACjG,QAAMmC,aAAa,WAAWC,mBAAkB/B,IAAAA,CAAAA,IAASiB,MAAAA;AACzD,QAAMe,YAAYC,cAActC,KAAKmC,UAAAA;AAErC,QAAMI,OAAwB;IAC1BjB;IACAkB,WAAW,CAAA;IACXV,KAAKpC;EACT;AAGA,MAAI6B,GAAGkB,aAAa;AAChBF,SAAKG,MAAMnB,GAAGkB;EAClB;AAGA,MAAIlB,GAAGU,eAAejC,IAAIkC,iBAAiB;AACvCK,SAAKN,cAAcV,GAAGU;EAC1B;AAGA,MAAIV,GAAGoB,YAAY;AACfJ,SAAKK,YAAY;MAAC;;EACtB;AAGA,QAAMC,cAA6B,CAAA;AACnC,QAAMC,eAA8B,CAAA;AAEpC,aAAWC,SAASxB,GAAGL,cAAc,CAAA,GAAI;AACrC,QAAI6B,MAAM1B,OAAO,SAAS;AACtBwB,kBAAYlC,KAAKqC,gBAAgBD,OAAOV,SAAAA,CAAAA;IAC5C,WAAWU,MAAM1B,OAAO,UAAU;AAC9ByB,mBAAanC,KAAKqC,gBAAgBD,OAAOV,SAAAA,CAAAA;IAC7C;EACJ;AAEA,MAAIQ,YAAYlB,SAAS,GAAG;AACxBY,SAAKU,QAAQ;MAAElB,MAAM;MAAUC,OAAOa;IAAY;EACtD;AACA,MAAIC,aAAanB,SAAS,GAAG;AACzBY,SAAKW,UAAU;MAAEnB,MAAM;MAAUC,OAAOc;IAAa;EACzD;AAGA,MAAIvB,GAAG4B,aAAa;AAChBZ,SAAKa,UAAUC,kBAAkB9B,GAAG4B,aAAa5B,GAAGkB,eAAe,GAAGnB,MAAAA,GAASgC,aAAajD,IAAAA,CAAAA,IAASgC,WAAWrC,GAAAA;EACpH;AAGA,QAAMwC,YAAYjB,GAAGiB,aAAa,CAAC;AACnC,aAAW,CAACe,MAAMC,IAAAA,KAASjD,OAAOC,QAAQgC,SAAAA,GAAY;AAClD,UAAMiB,aAAaC,SAASH,MAAM,EAAA;AAClC,QAAII,MAAMF,UAAAA,EAAa;AACvB,UAAMG,WAAWC,eAAeJ,YAAYD,MAAMjC,GAAGkB,eAAe,GAAGnB,MAAAA,GAASgC,aAAajD,IAAAA,CAAAA,IAASgC,WAAWrC,GAAAA;AACjHuC,SAAKC,UAAU7B,KAAKiD,QAAAA;EACxB;AAGA,MAAIrC,GAAGuC,aAAaC,QAAW;AAC3BxB,SAAKuB,WAAWE,gBAAgBzC,GAAGuC,QAAQ;EAC/C;AAEA,SAAOvB;AACX;AAhESd;AAoET,SAASI,gBAAgBxB,MAAc4D,iBAAwC3D,UAA8BN,KAAiB;AAC1H,QAAMqC,YAAYC,cAActC,KAAK,WAAWoC,mBAAkB/B,IAAAA,CAAAA,EAAO;AAGzE,QAAM6D,WAAW,oBAAI/D,IAAAA;AAErB,aAAWiB,KAAK6C,iBAAiB;AAC7BC,aAASrD,IAAIO,EAAE+C,MAAM/C,CAAAA;EACzB;AAGA,aAAWE,UAAUzB,cAAc;AAC/B,UAAM0B,KAAKjB,SAASgB,MAAAA;AACpB,QAAI,CAACC,IAAIL,WAAY;AACrB,eAAWE,KAAKG,GAAGL,YAAY;AAC3B,UAAIE,EAAEC,OAAO,UAAU,CAAC6C,SAASE,IAAIhD,EAAE+C,IAAI,GAAG;AAC1CD,iBAASrD,IAAIO,EAAE+C,MAAM/C,CAAAA;MACzB;IACJ;EACJ;AAGA,QAAMiD,gBAAgB;OAAIhE,KAAKiE,SAAS,cAAA;IAAiBC,IAAIC,CAAAA,MAAKA,EAAE,CAAA,CAAE;AAEtE,SAAOH,cAAcE,IAAIJ,CAAAA,SAAAA;AACrB,UAAMpB,QAAQmB,SAASO,IAAIN,IAAAA;AAC3B,QAAIpB,OAAO;AACP,aAAOC,gBAAgBD,OAAOV,SAAAA;IAClC;AAEA,WAAO;MACH8B;MACAO,UAAU;MACVC,UAAU;MACVC,MAAM;QAAE7C,MAAM;QAAmBoC,MAAM;MAAkB;MACzDrC,KAAKpC;IACT;EACJ,CAAA;AACJ;AAtCSmC;AAwCT,SAASmB,gBAAgBD,OAA4B/C,KAAkB;AACnE,QAAM4E,OAAO7B,MAAM8B,SAASC,iBAAiB/B,MAAM8B,QAAQ7E,GAAAA,IAAO;IAAE+B,MAAM;IAAmBoC,MAAM;EAAkB;AAErH,SAAO;IACHA,MAAMpB,MAAMoB;IACZO,UAAU3B,MAAM1B,OAAO,UAAU,CAAC0B,MAAMgC;IACxCJ,UAAU;IACVC;IACA3C,aAAajC,IAAIkC,kBAAkBa,MAAMd,cAAc8B;IACvDjC,KAAKpC;EACT;AACJ;AAXSsD;AAeT,SAASK,kBACL2B,SACAC,eACA5C,WACArC,KAAiB;AAEjB,QAAMkF,UAAUF,QAAQE;AACxB,MAAI,CAACA,QAAS,QAAOnB;AAErB,QAAMoB,YAAY,oBAAIC,IAAY;IAAC;IAAoB;IAAqC;GAAsB;AAClH,QAAMC,SAAkC,CAAA;AAExC,aAAW,CAACC,aAAaC,SAAAA,KAAchF,OAAOC,QAAQ0E,OAAAA,GAAU;AAC5D,QAAI,CAACC,UAAUf,IAAIkB,WAAAA,KAAgB,CAACC,WAAWV,OAAQ;AACvD,UAAM,EAAEW,UAAUC,MAAK,IAAKC,mBAAmBH,UAAUV,QAAQ,GAAGvB,aAAa2B,aAAAA,CAAAA,WAAyB5C,SAAAA;AAC1G,QAAIoD,OAAO;AACPzF,UAAI2F,gBAAgBhF,KAAK8E,KAAAA;IAC7B;AACAJ,WAAO1E,KAAK;MACR2E;MACAM,UAAUJ;IACd,CAAA;EACJ;AAEA,MAAIH,OAAO1D,WAAW,EAAG,QAAOoC;AAChC,SAAO;IAAEsB;EAAO;AACpB;AA1BShC;AA8BT,SAASQ,eACLJ,YACAD,MACAyB,eACA5C,WACArC,KAAiB;AAEjB,QAAMkD,UAAU2C,uBAAuBrC,KAAKN,SAASb,SAAAA;AAErD,MAAI,CAACmB,KAAK0B,SAAS;AACf,WAAOhC,UAAU;MAAEO;MAAYP;IAAQ,IAAI;MAAEO;IAAW;EAC5D;AAGA,QAAM,CAAC6B,aAAaC,SAAAA,IAAahF,OAAOC,QAAQgD,KAAK0B,OAAO,EAAE,CAAA,KAAM,CAAA;AACpE,MAAI,CAACI,eAAe,CAACC,WAAWV,QAAQ;AACpC,WAAO3B,UAAU;MAAEO;MAAYP;IAAQ,IAAI;MAAEO;IAAW;EAC5D;AAEA,QAAM,EAAE+B,UAAUC,MAAK,IAAKC,mBAAmBH,UAAUV,QAAQ,GAAGvB,aAAa2B,aAAAA,CAAAA,WAAyBxB,UAAAA,IAAcpB,SAAAA;AAExH,MAAIoD,OAAO;AACPzF,QAAI2F,gBAAgBhF,KAAK8E,KAAAA;EAC7B;AAEA,SAAO;IACHhC;IACA6B;IACAM,UAAUJ;IACV,GAAItC,UAAU;MAAEA;IAAQ,IAAI,CAAC;EACjC;AACJ;AA/BSW;AAiCT,SAASgC,uBAAuB3C,SAAwCb,WAAwB;AAC5F,MAAI,CAACa,QAAS,QAAOa;AACrB,QAAM+B,MAA8B,CAAA;AACpC,aAAW,CAAC3B,MAAM4B,MAAAA,KAAWxF,OAAOC,QAAQ0C,OAAAA,GAAU;AAClD,QAAI,CAAC6C,OAAQ;AACb,UAAMnB,OAAOmB,OAAOlB,SAASC,iBAAiBiB,OAAOlB,QAAQxC,SAAAA,IAAa;MAAEN,MAAM;MAAmBoC,MAAM;IAAkB;AAC7H2B,QAAInF,KAAK;MACLwD;MACAO,UAAU,CAACqB,OAAOhB;MAClBH;MACA3C,aAAaI,UAAUH,kBAAkB6D,OAAO9D,cAAc8B;IAClE,CAAA;EACJ;AACA,SAAO+B,IAAInE,SAAS,IAAImE,MAAM/B;AAClC;AAdS8B;AAkBT,SAAS7B,gBAAgBF,UAAoC;AAEzD,MAAIA,SAASnC,WAAW,GAAG;AACvB,WAAO;EACX;AAIA,SAAO;IAAEG,KAAKpC;EAAI;AACtB;AATSsE;AAaT,SAAS1B,cAActC,KAAmBK,MAAY;AAClD,SAAO;IACH2F,cAAchG,IAAIgG;IAClBC,UAAUjG,IAAIiG;IACd5F;IACA6B,iBAAiBlC,IAAIkC;IACrBgE,cAAclG,IAAIkG;IAClBP,iBAAiB3F,IAAI2F;IACrBQ,eAAe;EACnB;AACJ;AAVS7D;AAYT,SAASgB,aAAa8C,OAAa;AAC/B,SAAOA,MACFC,QAAQ,iBAAiB,GAAA,EACzBC,MAAM,KAAA,EACNnF,OAAOoF,OAAAA,EACPhC,IAAIiC,CAAAA,SAAQA,KAAKC,OAAO,CAAA,EAAGC,YAAW,IAAKF,KAAKG,MAAM,CAAA,CAAA,EACtDC,KAAK,EAAA;AACd;AAPStD;AAST,SAASlB,mBAAkByE,GAAS;AAChC,SAAOA,EAAER,QAAQ,MAAM,IAAA,EAAMA,QAAQ,OAAO,IAAA;AAChD;AAFSjE,OAAAA,oBAAAA;;;AC9UF,SAAS0E,WAAWC,QAAqBC,QAAuBC,WAAmC;AAEtG,QAAMC,cAAc,oBAAIC,IAAAA;AACxB,aAAWC,SAASJ,QAAQ;AACxB,UAAMK,MAAMJ,UAAUK,IAAIF,KAAAA,KAAU;AACpC,UAAMG,QAAQL,YAAYI,IAAID,GAAAA,KAAQ,CAAA;AACtCE,UAAMC,KAAKJ,KAAAA;AACXF,gBAAYO,IAAIJ,KAAKE,KAAAA;EACzB;AAGA,QAAMG,cAAc,oBAAIP,IAAAA;AACxB,aAAW,CAACE,KAAKM,SAAAA,KAAcT,aAAa;AACxC,UAAMU,OAAO,oBAAIC,IAAAA;AACjB,eAAWT,SAASO,WAAW;AAC3BG,uBAAiBV,OAAOQ,IAAAA;IAC5B;AACAF,gBAAYD,IAAIJ,KAAKO,IAAAA;EACzB;AAGA,QAAMG,mBAAmB,IAAIZ,IAAIJ,OAAOiB,IAAIC,CAAAA,MAAK;IAACA,EAAEC;IAAMD;GAAE,CAAA;AAC5D,QAAME,kBAAkB,oBAAIhB,IAAAA;AAE5B,aAAWiB,SAASrB,QAAQ;AACxB,UAAMsB,OAAiB,CAAA;AACvB,eAAW,CAAChB,KAAKO,IAAAA,KAASF,aAAa;AACnC,UAAIE,KAAKU,IAAIF,MAAMF,IAAI,GAAG;AACtBG,aAAKb,KAAKH,GAAAA;MACd;IACJ;AAEA,QAAIgB,KAAKE,WAAW,GAAG;AAEnBJ,sBAAgBV,IAAIW,MAAMF,MAAM,QAAA;IACpC,WAAWG,KAAKE,WAAW,GAAG;AAE1BJ,sBAAgBV,IAAIW,MAAMF,MAAMG,KAAK,CAAA,CAAE;IAC3C,OAAO;AAEHF,sBAAgBV,IAAIW,MAAMF,MAAM,QAAA;IACpC;EACJ;AAIA,aAAWE,SAASrB,QAAQ;AACxB,QAAIoB,gBAAgBb,IAAIc,MAAMF,IAAI,MAAM,UAAU;AAC9C,YAAMN,OAAO,oBAAIC,IAAAA;AACjBW,uBAAiBJ,OAAOR,IAAAA;AACxB,iBAAWa,OAAOb,MAAM;AACpB,YAAIG,iBAAiBO,IAAIG,GAAAA,GAAM;AAC3B,gBAAMC,aAAaP,gBAAgBb,IAAImB,GAAAA;AAGvC,cAAIC,cAAcA,eAAe,UAAU;AAEvC,kBAAMC,YAAY;iBAAIjB,YAAYkB,QAAO;cAAIC,OAAO,CAAC,CAACC,GAAGC,CAAAA,MAAOD,MAAMJ,cAAcK,EAAET,IAAIG,GAAAA,CAAAA,EAAMT,IAAI,CAAC,CAACc,CAAAA,MAAOA,CAAAA;AAC7G,gBAAIH,UAAUJ,SAAS,GAAG;AACtBJ,8BAAgBV,IAAIgB,KAAK,QAAA;YAC7B;UACJ;QACJ;MACJ;IACJ;EACJ;AAGA,QAAMO,SAAS,oBAAI7B,IAAAA;AACnB,QAAM8B,UAAU,oBAAIpB,IAAI;OAAIX,YAAYgC,KAAI;OAAO,IAAIrB,IAAIM,gBAAgBgB,OAAM,CAAA;GAAI;AAErF,aAAW9B,OAAO4B,SAAS;AACvB,UAAMG,YAAYrC,OAAO8B,OAAOZ,CAAAA,MAAKE,gBAAgBb,IAAIW,EAAEC,IAAI,MAAMb,GAAAA;AACrE,UAAMM,YAAYT,YAAYI,IAAID,GAAAA,KAAQ,CAAA;AAE1C,QAAI+B,UAAUb,WAAW,KAAKZ,UAAUY,WAAW,EAAG;AAEtD,UAAMc,WAAWC,iBAAiBjC,GAAAA;AAClC2B,WAAOvB,IAAI,GAAG4B,QAAAA,OAAe;MACzBE,MAAM;MACNC,MAAMnC,QAAQ,WAAW;QAAEoC,MAAMpC;MAAI,IAAI,CAAC;MAC1CqC,UAAU,CAAC;MACX3C,QAAQqC;MACRpC,QAAQW;MACRgC,MAAM,GAAGN,QAAAA;IACb,CAAA;EACJ;AAEA,SAAOL;AACX;AAzFgBlC;AA8FT,SAAS8C,gBAAgB7C,QAAqBC,QAAuBqC,WAAmB,OAAK;AAChG,SAAO;IACHE,MAAM;IACNC,MAAM,CAAC;IACPE,UAAU,CAAC;IACX3C;IACAC;IACA2C,MAAM,GAAGN,QAAAA;EACb;AACJ;AATgBO;AAahB,SAAS9B,iBAAiBV,OAAoBQ,MAAiB;AAC3D,MAAIR,MAAMyC,QAAQ;AACdC,2BAAuB1C,MAAMyC,QAAQjC,IAAAA;EACzC;AACA,aAAWmC,MAAM3C,MAAM4C,YAAY;AAC/B,QAAID,GAAGE,MAAOH,wBAAuBC,GAAGE,OAAOrC,IAAAA;AAC/C,QAAImC,GAAGG,QAASJ,wBAAuBC,GAAGG,SAAStC,IAAAA;AACnD,QAAImC,GAAGI,SAAS;AACZ,iBAAWC,QAAQL,GAAGI,QAAQE,OAAQC,iBAAgBF,KAAKG,UAAU3C,IAAAA;IACzE;AACA,eAAW4C,QAAQT,GAAGU,WAAW;AAC7B,UAAID,KAAKD,SAAUD,iBAAgBE,KAAKD,UAAU3C,IAAAA;IACtD;EACJ;AACJ;AAdSE;AAgBT,SAASgC,uBAAuBY,QAAiB9C,MAAiB;AAC9D,MAAI,OAAO8C,WAAW,UAAU;AAC5B9C,SAAK+C,IAAID,MAAAA;AACT;EACJ;AACA,MAAIE,MAAMC,QAAQH,MAAAA,GAAS;AACvB,eAAWI,SAASJ,QAAQ;AACxB,UAAII,SAAS,OAAOA,UAAU,YAAY,UAAUA,OAAO;AACvDR,wBAAgBQ,MAAMC,MAA0BnD,IAAAA;MACpD;IACJ;AACA;EACJ;AACA,MAAI8C,UAAU,OAAOA,WAAW,YAAY,UAAUA,QAAQ;AAC1DJ,oBAAgBI,QAA4B9C,IAAAA;EAChD;AACJ;AAhBSkC;AAkBT,SAASQ,gBAAgBS,MAAwBnD,MAAiB;AAC9D,UAAQmD,KAAKxB,MAAI;IACb,KAAK;AACD3B,WAAK+C,IAAII,KAAK7C,IAAI;AAClB;IACJ,KAAK;AACDoC,sBAAgBS,KAAKC,MAAMpD,IAAAA;AAC3B;IACJ,KAAK;AACD,iBAAWoD,QAAQD,KAAKE,MAAOX,iBAAgBU,MAAMpD,IAAAA;AACrD;IACJ,KAAK;AACD0C,sBAAgBS,KAAKG,KAAKtD,IAAAA;AAC1B0C,sBAAgBS,KAAKI,OAAOvD,IAAAA;AAC5B;IACJ,KAAK;IACL,KAAK;IACL,KAAK;AACD,iBAAWwD,UAAUL,KAAKM,QAASf,iBAAgBc,QAAQxD,IAAAA;AAC3D;IACJ,KAAK;AACD,iBAAW0D,SAASP,KAAKQ,OAAQjB,iBAAgBgB,MAAMP,MAAMnD,IAAAA;AAC7D;IACJ,KAAK;AACD0C,sBAAgBS,KAAKS,OAAO5D,IAAAA;AAC5B;EACR;AACJ;AA3BS0C;AA6BT,SAAS9B,iBAAiBJ,OAAkBR,MAAiB;AACzD,MAAIQ,MAAMqD,MAAO,YAAWC,KAAKtD,MAAMqD,MAAO7D,MAAK+C,IAAIe,CAAAA;AACvD,MAAItD,MAAM2C,KAAMT,iBAAgBlC,MAAM2C,MAAMnD,IAAAA;AAC5C,aAAW0D,SAASlD,MAAMmD,QAAQ;AAC9BjB,oBAAgBgB,MAAMP,MAAMnD,IAAAA;EAChC;AACJ;AANSY;AAUT,SAASc,iBAAiBjC,KAAW;AACjC,SACIA,IACKsE,YAAW,EACXC,QAAQ,eAAe,GAAA,EACvBA,QAAQ,OAAO,GAAA,EACfA,QAAQ,UAAU,EAAA,KAAO;AAEtC;AARStC;;;AC/KT,IAAMuC,SAAS;AASR,SAASC,QAAQC,MAAkBC,UAA4B,CAAC,GAAC;AACpE,QAAM,EAAEC,kBAAkB,KAAI,IAAKD;AACnC,QAAME,MAAW;IAAED;EAAgB;AACnC,QAAME,QAAkB,CAAA;AAGxB,QAAMC,eAAeC,iBAAiBN,IAAAA;AACtC,MAAIK,aAAcD,OAAMG,KAAKF,YAAAA;AAG7B,aAAWG,SAASR,KAAKS,QAAQ;AAC7BL,UAAMG,KAAKG,eAAeF,OAAOL,GAAAA,CAAAA;EACrC;AAGA,aAAWQ,SAASX,KAAKY,QAAQ;AAC7BR,UAAMG,KAAKM,eAAeF,OAAOR,GAAAA,CAAAA;EACrC;AAEA,SAAOC,MAAMU,KAAK,MAAA,IAAU;AAChC;AApBgBf;AA8BhB,SAASO,iBAAiBN,MAAgB;AACtC,QAAMe,UAAUC,OAAOC,KAAKjB,KAAKkB,IAAI,EAAEC,SAAS;AAChD,QAAMC,cAAcpB,KAAKqB,YAAYL,OAAOC,KAAKjB,KAAKqB,QAAQ,EAAEF,SAAS;AACzE,QAAMG,cAActB,KAAKuB,aAAaC;AAEtC,MAAI,CAACT,WAAW,CAACK,eAAe,CAACE,YAAa,QAAO;AAErD,QAAMG,QAAkB;IAAC;;AAEzB,MAAIV,SAAS;AACTU,UAAMlB,KAAK,GAAGT,MAAAA,SAAe;AAC7B,eAAW,CAAC4B,KAAKC,KAAAA,KAAUX,OAAOY,QAAQ5B,KAAKkB,IAAI,GAAG;AAClDO,YAAMlB,KAAK,GAAGT,MAAAA,GAASA,MAAAA,GAAS4B,GAAAA,KAAQC,KAAAA,EAAO;IACnD;AACAF,UAAMlB,KAAK,GAAGT,MAAAA,GAAS;EAC3B;AAEA,MAAIsB,aAAa;AACbK,UAAMlB,KAAK,GAAGT,MAAAA,aAAmB;AACjC,eAAW,CAAC+B,MAAMC,IAAAA,KAASd,OAAOY,QAAQ5B,KAAKqB,QAAQ,GAAG;AACtDI,YAAMlB,KAAK,GAAGT,MAAAA,GAASA,MAAAA,GAAS+B,IAAAA,MAAUC,IAAAA,GAAO;IACrD;AACAL,UAAMlB,KAAK,GAAGT,MAAAA,GAAS;EAC3B;AAEA,MAAIwB,aAAa;AACbG,UAAMlB,KAAK,GAAGT,MAAAA,aAAmB;AACjC,QAAIE,KAAKuB,aAAa,QAAQ;AAC1BE,YAAMlB,KAAK,GAAGT,MAAAA,GAASA,MAAAA,MAAY;IACvC,OAAO;AACH,YAAMiC,MAAM/B,KAAKuB;AACjB,UAAIQ,IAAIC,WAAWR,QAAW;AAC1B,cAAMG,QAAQI,IAAIC,WAAW,QAAQ,SAASD,IAAIC;AAClDP,cAAMlB,KAAK,GAAGT,MAAAA,GAASA,MAAAA,WAAiB6B,KAAAA,EAAO;MACnD;IACJ;AACAF,UAAMlB,KAAK,GAAGT,MAAAA,GAAS;EAC3B;AAEA2B,QAAMlB,KAAK,GAAA;AACX,SAAOkB,MAAMX,KAAK,IAAA;AACtB;AAzCSR;AA6CT,SAASI,eAAeF,OAAkBL,KAAQ;AAC9C,QAAMC,QAAkB,CAAA;AAGxB,QAAM6B,WAAqB,CAAA;AAC3B,MAAIzB,MAAM0B,aAAa1B,MAAM0B,cAAc,SAAS;AAChDD,aAAS1B,KAAK,gBAAgBC,MAAM0B,SAAS,GAAG;EACpD;AACA,MAAI1B,MAAM2B,QAAQ3B,MAAM2B,SAAS,UAAU;AACvCF,aAAS1B,KAAK,QAAQC,MAAM2B,IAAI,GAAG;EACvC;AACA,MAAI3B,MAAM4B,YAAY;AAClBH,aAAS1B,KAAK,YAAA;EAClB;AAEA,QAAM8B,SAASJ,SAASd,SAAS,IAAIc,SAASnB,KAAK,GAAA,IAAO,MAAM;AAChE,QAAMwB,UAAUnC,IAAID,mBAAmBM,MAAM+B,cAAc,MAAM/B,MAAM+B,WAAW,KAAK;AAGvF,MAAI/B,MAAMgC,MAAM;AACZpC,UAAMG,KAAK,YAAY8B,MAAAA,GAAS7B,MAAMqB,IAAI,KAAKY,cAAcjC,MAAMgC,IAAI,CAAA,GAAIF,OAAAA,EAAS;AACpF,WAAOlC,MAAMU,KAAK,EAAA;EACtB;AAGA,MAAIN,MAAMkC,SAASlC,MAAMkC,MAAMvB,SAAS,GAAG;AACvCf,UAAMG,KAAK,YAAY8B,MAAAA,GAAS7B,MAAMqB,IAAI,KAAKrB,MAAMkC,MAAM5B,KAAK,KAAA,CAAA,OAAawB,OAAAA,EAAS;EAC1F,OAAO;AACHlC,UAAMG,KAAK,YAAY8B,MAAAA,GAAS7B,MAAMqB,IAAI,MAAMS,OAAAA,EAAS;EAC7D;AAEA,aAAWK,SAASnC,MAAMoC,QAAQ;AAC9BxC,UAAMG,KAAKsC,eAAeF,OAAO,GAAGxC,GAAAA,CAAAA;EACxC;AAEAC,QAAMG,KAAK,GAAA;AACX,SAAOH,MAAMU,KAAK,IAAA;AACtB;AArCSJ;AAuCT,SAASmC,eAAeF,OAAkBG,OAAe3C,KAAQ;AAC7D,QAAM4C,SAASjD,OAAOkD,OAAOF,KAAAA;AAC7B,QAAMG,WAAWN,MAAMM,WAAW,MAAM;AACxC,QAAMC,aAAaP,MAAMO,eAAe,WAAW,GAAGP,MAAMO,UAAU,MAAM;AAC5E,QAAMd,aAAaO,MAAMP,aAAa,gBAAgB;AAEtD,MAAIe,UAAUV,cAAcE,MAAMH,IAAI;AAGtC,MAAIG,MAAMS,YAAY,CAACC,iBAAiBV,MAAMH,IAAI,GAAG;AACjDW,cAAU,GAAGA,OAAAA;EACjB;AAEA,QAAMG,aAAaX,MAAMY,YAAY/B,SAAY,MAAMgC,iBAAiBb,MAAMY,OAAO,CAAA,KAAM;AAC3F,QAAMjB,UAAUnC,IAAID,mBAAmByC,MAAMJ,cAAc,MAAMI,MAAMJ,WAAW,KAAK;AAEvF,SAAO,GAAGQ,MAAAA,GAASJ,MAAMd,IAAI,GAAGoB,QAAAA,KAAab,UAAAA,GAAac,UAAAA,GAAaC,OAAAA,GAAUG,UAAAA,GAAahB,OAAAA;AAClG;AAjBSO;AAmBT,SAASQ,iBAAiBb,MAAsB;AAC5C,MAAIA,KAAKiB,SAAS,YAAYjB,KAAKX,SAAS,OAAQ,QAAO;AAC3D,MAAIW,KAAKiB,SAAS,QAAS,QAAOjB,KAAKkB,QAAQC,KAAKN,gBAAAA;AACpD,SAAO;AACX;AAJSA;AAMT,SAASG,iBAAiB7B,OAAgC;AACtD,MAAI,OAAOA,UAAU,UAAU;AAE3B,QAAI,gCAAgCiC,KAAKjC,KAAAA,EAAQ,QAAOA;AACxD,WAAO,IAAIA,KAAAA;EACf;AACA,SAAOkC,OAAOlC,KAAAA;AAClB;AAPS6B;AAWF,SAASf,cAAcD,MAAsB;AAChD,UAAQA,KAAKiB,MAAI;IACb,KAAK;AACD,aAAOK,gBAAgBtB,IAAAA;IAC3B,KAAK;AACD,aAAOuB,eAAevB,IAAAA;IAC1B,KAAK;AACD,aAAO,SAASA,KAAKwB,MAAMC,IAAIxB,aAAAA,EAAe3B,KAAK,IAAA,CAAA;IACvD,KAAK;AACD,aAAO,UAAU2B,cAAcD,KAAKd,GAAG,CAAA,KAAMe,cAAcD,KAAKb,KAAK,CAAA;IACzE,KAAK;AACD,aAAO,QAAQa,KAAK0B,OAAOpD,KAAK,IAAA,CAAA;IACpC,KAAK;AACD,aAAOqD,iBAAiB3B,IAAAA;IAC5B,KAAK;AACD,aAAOA,KAAKkB,QAAQO,IAAIxB,aAAAA,EAAe3B,KAAK,KAAA;IAChD,KAAK;AACD,aAAO,oBAAoB0B,KAAK4B,aAAa,KAAK5B,KAAKkB,QAAQO,IAAIxB,aAAAA,EAAe3B,KAAK,KAAA,CAAA;IAC3F,KAAK;AACD,aAAO0B,KAAKkB,QAAQO,IAAIxB,aAAAA,EAAe3B,KAAK,KAAA;IAChD,KAAK;AACD,aAAO0B,KAAKX;IAChB,KAAK;AACD,aAAOwC,sBAAsB7B,IAAAA;IACjC,KAAK;AACD,aAAO,QAAQC,cAAcD,KAAK8B,KAAK,CAAA;EAC/C;AACJ;AA3BgB7B;AA6BhB,SAASqB,gBAAgBtB,MAOxB;AACG,QAAM+B,OAAiB,CAAA;AACvB,MAAI/B,KAAKgC,QAAQhD,OAAW+C,MAAKhE,KAAK,UAAUiC,KAAKgC,GAAG,EAAE;AAC1D,MAAIhC,KAAKiC,QAAQjD,OAAW+C,MAAKhE,KAAK,OAAOiC,KAAKiC,QAAQ,WAAW,QAAQjC,KAAKiC,GAAG,MAAM,OAAOjC,KAAKiC,GAAG,EAAE;AAC5G,MAAIjC,KAAKkC,QAAQlD,OAAW+C,MAAKhE,KAAK,OAAOiC,KAAKkC,QAAQ,WAAW,QAAQlC,KAAKkC,GAAG,MAAM,OAAOlC,KAAKkC,GAAG,EAAE;AAC5G,MAAIlC,KAAKmC,UAAUnD,OAAW+C,MAAKhE,KAAK,SAASiC,KAAKmC,KAAK,EAAE;AAC7D,MAAInC,KAAKoC,WAAWpD,OAAW+C,MAAKhE,KAAK,UAAUiC,KAAKoC,MAAM,EAAE;AAEhE,MAAIL,KAAKpD,WAAW,EAAG,QAAOqB,KAAKX;AACnC,SAAO,GAAGW,KAAKX,IAAI,IAAI0C,KAAKzD,KAAK,IAAA,CAAA;AACrC;AAjBSgD;AAmBT,SAASC,eAAevB,MAA4D;AAChF,QAAM+B,OAAiB;IAAC9B,cAAcD,KAAKqC,IAAI;;AAC/C,MAAIrC,KAAKiC,QAAQjD,OAAW+C,MAAKhE,KAAK,OAAOiC,KAAKiC,GAAG,EAAE;AACvD,MAAIjC,KAAKkC,QAAQlD,OAAW+C,MAAKhE,KAAK,OAAOiC,KAAKkC,GAAG,EAAE;AACvD,SAAO,SAASH,KAAKzD,KAAK,IAAA,CAAA;AAC9B;AALSiD;AAOT,SAASI,iBAAiB3B,MAA0C;AAChE,MAAI,OAAOA,KAAKb,UAAU,SAAU,QAAO,YAAYa,KAAKb,KAAK;AACjE,SAAO,WAAWa,KAAKb,KAAK;AAChC;AAHSwC;AAKT,SAASE,sBAAsB7B,MAAgD;AAC3E,QAAMsC,aAAatC,KAAKL,OAAO,QAAQK,KAAKL,IAAI,OAAO;AACvD,MAAIK,KAAKI,OAAOzB,WAAW,EAAG,QAAO,GAAG2D,UAAAA;AAExC,QAAMrD,QAAkB;IAAC,GAAGqD,UAAAA;;AAC5B,aAAWnC,SAASH,KAAKI,QAAQ;AAC7BnB,UAAMlB,KAAKsC,eAAeF,OAAO,GAAG;MAAEzC,iBAAiB;IAAK,CAAA,CAAA;EAChE;AACAuB,QAAMlB,KAAK,GAAGT,MAAAA,GAAS;AACvB,SAAO2B,MAAMX,KAAK,IAAA;AACtB;AAVSuD;AAcT,SAASxD,eAAeF,OAAoBR,KAAQ;AAChD,QAAMsB,QAAkB,CAAA;AAExB,QAAMsD,SAASC,mBAAmBrE,MAAMsE,SAAS;AACjD,QAAM3C,UAAUnC,IAAID,mBAAmBS,MAAM4B,cAAc,MAAM5B,MAAM4B,WAAW,KAAK;AACvFd,QAAMlB,KAAK,YAAYwE,MAAAA,IAAUpE,MAAMmB,IAAI,MAAMQ,OAAAA,EAAS;AAG1D,MAAI3B,MAAMuE,QAAQ;AACdC,yBAAqB1D,OAAO,UAAUd,MAAMuE,QAAQvE,MAAMyE,YAAY,GAAGjF,GAAAA;EAC7E;AAGA,MAAIQ,MAAMY,aAAaC,QAAW;AAC9B6D,2BAAuB5D,OAAOd,MAAMY,UAAU,GAAGpB,GAAAA;EACrD;AAGA,aAAWmF,MAAM3E,MAAM4E,YAAY;AAC/BC,uBAAmB/D,OAAO6D,IAAI,GAAGnF,GAAAA;EACrC;AAEAsB,QAAMlB,KAAK,GAAA;AACX,SAAOkB,MAAMX,KAAK,IAAA;AACtB;AAxBSD;AA0BT,SAAS2E,mBAAmB/D,OAAiB6D,IAAqBxC,OAAe3C,KAAQ;AACrF,QAAM4C,SAASjD,OAAOkD,OAAOF,KAAAA;AAC7B,QAAMiC,SAASC,mBAAmBM,GAAGL,SAAS;AAC9C,QAAM3C,UAAUnC,IAAID,mBAAmBoF,GAAG/C,cAAc,MAAM+C,GAAG/C,WAAW,KAAK;AACjFd,QAAMlB,KAAK,GAAGwC,MAAAA,GAASuC,GAAGG,MAAM,GAAGV,MAAAA,MAAYzC,OAAAA,EAAS;AAExD,QAAMgC,QAAQxE,OAAOkD,OAAOF,QAAQ,CAAA;AAGpC,MAAIwC,GAAGI,SAAS;AACZjE,UAAMlB,KAAK,GAAG+D,KAAAA,YAAiBgB,GAAGI,OAAO,EAAE;EAC/C;AAGA,MAAIJ,GAAGK,KAAK;AACRlE,UAAMlB,KAAK,GAAG+D,KAAAA,QAAagB,GAAGK,GAAG,EAAE;EACvC;AAGA,MAAIL,GAAGM,WAAW;AACd,UAAMC,aAAa1F,IAAID,mBAAmBoF,GAAGQ,uBAAuB,MAAMR,GAAGQ,oBAAoB,KAAK;AACtGrE,UAAMlB,KAAK,GAAG+D,KAAAA,cAAmBgB,GAAGM,SAAS,GAAGC,UAAAA,EAAY;EAChE;AAGA,MAAIP,GAAG/D,aAAaC,QAAW;AAC3B6D,2BAAuB5D,OAAO6D,GAAG/D,UAAUuB,QAAQ,GAAG3C,GAAAA;EAC1D;AAGA,MAAImF,GAAGS,OAAO;AACVZ,yBAAqB1D,OAAO,SAAS6D,GAAGS,OAAOT,GAAGU,WAAWlD,QAAQ,GAAG3C,GAAAA;EAC5E;AAGA,MAAImF,GAAGW,SAAS;AACZd,yBAAqB1D,OAAO,WAAW6D,GAAGW,SAASX,GAAGY,aAAapD,QAAQ,GAAG3C,GAAAA;EAClF;AAGA,MAAImF,GAAGa,SAAS;AACZC,qBAAiB3E,OAAO6D,GAAGa,SAASrD,QAAQ,CAAA;EAChD;AAGA,MAAIwC,GAAGe,UAAUlF,SAAS,GAAG;AACzBmF,uBAAmB7E,OAAO6D,GAAGe,WAAWvD,QAAQ,CAAA;EACpD;AAEArB,QAAMlB,KAAK,GAAGwC,MAAAA,GAAS;AACvB,SAAOtB;AACX;AAnDS+D;AAqDT,SAASR,mBAAmBC,WAA2B;AACnD,MAAI,CAACA,aAAaA,UAAU9D,WAAW,EAAG,QAAO;AACjD,SAAO,IAAI8D,UAAUnE,KAAK,IAAA,CAAA;AAC9B;AAHSkE;AAKT,SAASG,qBAAqB1D,OAAiB8E,SAAiBC,QAAqBrE,MAA8BW,OAAe3C,KAAQ;AACtI,QAAM4C,SAASjD,OAAOkD,OAAOF,KAAAA;AAG7B,MAAI0D,OAAO/C,SAAS,OAAO;AACvBhC,UAAMlB,KAAK,GAAGwC,MAAAA,GAASwD,OAAAA,KAAYC,OAAO3E,IAAI,EAAE;AAChD;EACJ;AAGA,MAAI2E,OAAO/C,SAAS,QAAQ;AACxBhC,UAAMlB,KAAK,GAAGwC,MAAAA,GAASwD,OAAAA,KAAY9D,cAAc+D,OAAOC,IAAI,CAAA,EAAG;AAC/D;EACJ;AAGA,QAAMC,UAAUvE,OAAO,QAAQA,IAAAA,OAAW;AAC1CV,QAAMlB,KAAK,GAAGwC,MAAAA,GAASwD,OAAAA,KAAYG,OAAAA,GAAU;AAC7C,aAAWC,SAASH,OAAOI,OAAO;AAC9B,UAAM3D,WAAW0D,MAAM1D,WAAW,MAAM;AACxC,QAAIE,UAAUV,cAAckE,MAAMnE,IAAI;AACtC,QAAImE,MAAMvD,YAAY,CAACC,iBAAiBsD,MAAMnE,IAAI,GAAG;AACjDW,gBAAU,GAAGA,OAAAA;IACjB;AACA,UAAMG,aAAaqD,MAAMpD,YAAY/B,SAAY,MAAMgC,iBAAiBmD,MAAMpD,OAAO,CAAA,KAAM;AAC3F,UAAMjB,UAAUnC,IAAID,mBAAmByG,MAAMpE,cAAc,MAAMoE,MAAMpE,WAAW,KAAK;AACvFd,UAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAK6D,MAAM9E,IAAI,GAAGoB,QAAAA,KAAaE,OAAAA,GAAUG,UAAAA,GAAahB,OAAAA,EAAS;EACvG;AACAb,QAAMlB,KAAK,GAAGwC,MAAAA,GAAS;AAC3B;AA7BSoC;AA+BT,SAASiB,iBAAiB3E,OAAiB0E,SAAwBrD,OAAa;AAC5E,QAAMC,SAASjD,OAAOkD,OAAOF,KAAAA;AAC7BrB,QAAMlB,KAAK,GAAGwC,MAAAA,YAAkB;AAChC,aAAW8D,QAAQV,QAAQW,QAAQ;AAC/BrF,UAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAK+D,KAAKE,WAAW,KAAKtE,cAAcoE,KAAKG,QAAQ,CAAA,EAAG;EAChG;AACAvF,QAAMlB,KAAK,GAAGwC,MAAAA,GAAS;AAC3B;AAPSqD;AAST,SAASE,mBAAmB7E,OAAiB4E,WAA6BvD,OAAa;AACnF,QAAMC,SAASjD,OAAOkD,OAAOF,KAAAA;AAC7BrB,QAAMlB,KAAK,GAAGwC,MAAAA,aAAmB;AACjC,aAAWkE,QAAQZ,WAAW;AAC1B,UAAMa,UAAUD,KAAKD,YAAYC,KAAKF;AACtC,UAAMI,aAAaF,KAAKhB,WAAWgB,KAAKhB,QAAQ9E,SAAS;AACzD,QAAI+F,WAAWC,YAAY;AACvB1F,YAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAKmE,KAAKG,UAAU,KAAK;AAC7D,UAAIF,SAAS;AACTzF,cAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAKmE,KAAKF,WAAW,KAAKtE,cAAcwE,KAAKD,QAAQ,CAAA,EAAI;MACjG;AACA,UAAIG,YAAY;AACZ1F,cAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,YAAc;AAClD,mBAAWuE,KAAKJ,KAAKhB,SAAU;AAC3B,gBAAMqB,MAAMD,EAAEpE,WAAW,MAAM;AAC/B,gBAAMsE,QAAQF,EAAE9E,cAAc,MAAM8E,EAAE9E,WAAW,KAAK;AACtDd,gBAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAKuE,EAAExF,IAAI,GAAGyF,GAAAA,KAAQ7E,cAAc4E,EAAE7E,IAAI,CAAA,GAAI+E,KAAAA,EAAO;QAC7F;AACA9F,cAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAK;MAC7C;AACArB,YAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAK;IAC7C,OAAO;AACHrB,YAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,GAAKmE,KAAKG,UAAU,GAAG;IAC/D;EACJ;AACA3F,QAAMlB,KAAK,GAAGwC,MAAAA,GAAS;AAC3B;AA1BSuD;AA4BT,SAASjB,uBAAuB5D,OAAiBF,UAAwBuB,OAAe3C,KAAQ;AAC5F,QAAM4C,SAASjD,OAAOkD,OAAOF,KAAAA;AAC7B,MAAIvB,aAAa,QAAQ;AACrBE,UAAMlB,KAAK,GAAGwC,MAAAA,gBAAsB;AACpC;EACJ;AAEA,QAAMhB,MAAMR;AACZ,MAAIQ,IAAIC,WAAWR,QAAW;AAC1B,UAAMc,UAAUnC,IAAID,mBAAmB6B,IAAIyF,oBAAoB,MAAMzF,IAAIyF,iBAAiB,KAAK;AAC/F,UAAM7F,QAAQI,IAAIC,WAAW,QAAQ,SAASD,IAAIC;AAClDP,UAAMlB,KAAK,GAAGwC,MAAAA,aAAmB;AACjCtB,UAAMlB,KAAK,GAAGT,OAAOkD,OAAOF,QAAQ,CAAA,CAAA,WAAanB,KAAAA,GAAQW,OAAAA,EAAS;AAClEb,UAAMlB,KAAK,GAAGwC,MAAAA,GAAS;EAC3B,OAAO;AACHtB,UAAMlB,KAAK,GAAGwC,MAAAA,cAAoB;EACtC;AACJ;AAjBSsC;;;ACjZT,SAASoC,oBAAoB;AAC7B,SAASC,SAASC,iBAAiB;;;ACC5B,IAAMC,mBAAN,MAAMA;EAAb,OAAaA;;;EACAC,WAAsB,CAAA;EACvBC;EAER,YAAYA,WAAkC;AAC1C,SAAKA,YAAYA;EACrB;EAEAC,KAAKC,MAAcC,SAAuB;AACtC,SAAKC,IAAI;MAAEF;MAAMC;MAASE,UAAU;IAAO,CAAA;EAC/C;EAEAC,KAAKJ,MAAcC,SAAuB;AACtC,SAAKC,IAAI;MAAEF;MAAMC;MAASE,UAAU;IAAO,CAAA;EAC/C;EAEQD,IAAIG,SAAwB;AAChC,SAAKR,SAASS,KAAKD,OAAAA;AACnB,SAAKP,YAAYO,OAAAA;EACrB;AACJ;;;ADLA,eAAsBE,mBAAmBC,SAAuB;AAC5D,QAAM,EAAEC,QAAQ,UAAUC,kBAAkB,KAAI,IAAKF;AACrD,QAAMG,WAAW,IAAIC,iBAAiBJ,QAAQK,SAAS;AAGvD,QAAMC,SAAS,MAAMC,WAAWP,QAAQQ,KAAK;AAG7C,QAAMC,MAAMC,UAAUJ,QAAQH,QAAAA;AAG9B,QAAMQ,UAAUC,oBAAoBH,KAAKN,QAAAA;AAGzC,QAAMU,eAAeC,mBAAmBH,OAAAA;AAGxC,QAAMI,kBAA+B,CAAA;AACrC,QAAMC,YAA2B;IAC7BH;IACAV;IACAc,MAAM;IACNf;IACAgB,cAAcP;IACdI;IACAI,eAAe;EACnB;AAEA,QAAMC,SAASC,gBAAgBV,SAASK,SAAAA;AAGxC,QAAM,EAAEM,QAAQC,UAAS,IAAKC,cAAcf,KAAK;IAC7CI;IACAV;IACAD;IACAgB,cAAcP;IACdI;IACAU,gBAAgBhB,IAAIiB;EACxB,CAAA;AAGA,QAAMC,QAAQ,oBAAIC,IAAAA;AAElB,MAAI3B,UAAU,UAAU;AACpB,UAAM4B,UAAUC,WAAWV,QAAQE,QAAQC,SAAAA;AAC3C,eAAW,CAACQ,UAAUC,IAAAA,KAASH,SAAS;AACpCF,YAAMM,IAAIF,UAAUG,QAAQF,MAAM;QAAE9B;MAAgB,CAAA,CAAA;IACxD;EACJ,OAAO;AACH,UAAM8B,OAAOG,gBAAgBf,QAAQE,MAAAA;AACrCK,UAAMM,IAAI,UAAUC,QAAQF,MAAM;MAAE9B;IAAgB,CAAA,CAAA;EACxD;AAEA,SAAO;IAAEyB;IAAOxB,UAAUA,SAASA;EAAS;AAChD;AAtDsBJ;AA0DtB,eAAeQ,WAAWC,OAAuC;AAE7D,MAAI,OAAOA,UAAU,UAAU;AAC3B,WAAOA;EACX;AAGA,MAAI;AACA,UAAM4B,UAAUC,aAAa7B,OAAO,OAAA;AACpC,WAAO8B,gBAAgBF,OAAAA;EAC3B,QAAQ;AAEJ,WAAOE,gBAAgB9B,KAAAA;EAC3B;AACJ;AAdeD;AAgBf,SAAS+B,gBAAgBF,SAAe;AAEpC,MAAI;AACA,WAAOG,KAAKC,MAAMJ,OAAAA;EACtB,QAAQ;AAEJ,WAAOK,UAAUL,OAAAA;EACrB;AACJ;AARSE;AAYT,SAAS1B,oBAAoBH,KAAyBN,UAA0B;AAC5E,QAAMuC,WAAWjC,IAAIkC,YAAYhC,WAAW,CAAC;AAC7C,QAAMiC,YAA8C,CAAC;AACrD,QAAMC,UAAU,oBAAIjB,IAAAA;AAEpB,aAAWkB,QAAQC,OAAOC,KAAKN,QAAAA,GAAW;AACtC,UAAMO,QAAQC,aAAaJ,MAAM3C,QAAAA;AACjC,QAAIyC,UAAUK,KAAAA,GAAQ;AAClB9C,eAASgD,KAAK,wBAAwBL,IAAAA,IAAQ,uCAAuCA,IAAAA,qCAAyCG,KAAAA,GAAQ;AAEtI,UAAIG,IAAI;AACR,aAAOR,UAAU,GAAGK,KAAAA,GAAQG,CAAAA,EAAG,EAAGA;AAClCP,cAAQZ,IAAIa,MAAM,GAAGG,KAAAA,GAAQG,CAAAA,EAAG;AAChCR,gBAAU,GAAGK,KAAAA,GAAQG,CAAAA,EAAG,IAAIV,SAASI,IAAAA;IACzC,OAAO;AACHD,cAAQZ,IAAIa,MAAMG,KAAAA;AAClBL,gBAAUK,KAAAA,IAASP,SAASI,IAAAA;IAChC;EACJ;AAGA,MAAID,QAAQQ,OAAO,GAAG;AAClBC,eAAW7C,KAAKoC,OAAAA;EACpB;AAEA,SAAOD;AACX;AA1BShC;AA4BT,SAAS0C,WAAWC,KAAcV,SAA4B;AAC1D,MAAI,CAACU,OAAO,OAAOA,QAAQ,SAAU;AACrC,MAAIC,MAAMC,QAAQF,GAAAA,GAAM;AACpB,eAAWG,QAAQH,IAAKD,YAAWI,MAAMb,OAAAA;AACzC;EACJ;AAEA,QAAMc,SAASJ;AACf,MAAI,OAAOI,OAAOC,SAAS,UAAU;AACjC,UAAMC,QAAQF,OAAOC,KAAKC,MAAM,gCAAA;AAChC,QAAIA,QAAQ,CAAA,KAAMhB,QAAQiB,IAAID,MAAM,CAAA,CAAE,GAAG;AACrCF,aAAOC,OAAO,wBAAwBf,QAAQkB,IAAIF,MAAM,CAAA,CAAE,CAAA;IAC9D;EACJ;AAEA,aAAWG,SAASjB,OAAOkB,OAAON,MAAAA,GAAS;AACvCL,eAAWU,OAAOnB,OAAAA;EACtB;AACJ;AAlBSS;","names":["normalize","doc","warnings","version","detectVersion","normalizeSwagger2","normalizeOas30","swagger","startsWith","openapi","info","title","basePath","schemes","host","globalConsumes","consumes","globalProduces","produces","result","description","servers","url","paths","components","schemas","securitySchemes","tags","definitions","name","schema","Object","entries","normalizeNullable30","secDefs","securityDefinitions","scheme","convertSecurityScheme2","path","pathItem","normalizePathItem2","security","methods","normalized","pathParams","parameters","method","op","opConsumes","opProduces","params","nonBodyParams","requestBody","param","in","contentType","required","content","encodePathSegment","type","properties","formSchema","props","push","normalizedParam","format","enum","items","default","minimum","maximum","minLength","maxLength","pattern","responses","opResponses","code","resp","headers","convertResponseHeaders2","responseEntry","operationId","summary","length","undefined","deprecated","out","header","rest","keys","flow","flows","implicit","authorizationUrl","scopes","password","tokenUrl","clientCredentials","authorizationCode","_warnings","values","normalizePathItemSchemas","reqBody","mediaType","nullable","key","val","Array","isArray","additionalProperties","combiner","map","s","replace","detectCircularRefs","schemas","circular","Set","visiting","visited","visit","name","has","add","schema","ref","collectRefs","refName","extractRefName","delete","Object","keys","obj","refs","walk","val","Array","isArray","item","record","$ref","push","v","values","match","LOC","file","line","FORMAT_TO_SCALAR","email","uri","url","uuid","date","time","binary","int64","schemasToModels","schemas","ctx","models","name","schema","Object","entries","modelCtx","path","model","schemaToModel","push","extractedModels","warnUnsupported","description","includeComments","undefined","allOf","length","first","second","refMember","$ref","objectMember","properties","baseName","extractRefName","fields","schemaPropertiesToFields","kind","bases","loc","type","additionalProperties","typeNode","schemaToTypeNode","refName","circularRefs","has","inner","warnings","warn","const","value","enum","values","map","String","oneOf","discriminator","propertyName","toDiscriminatedUnion","toUnion","anyOf","members","s","types","normalizeTypeField","schemaToInlineObject","baseType","nullable","stringSchemaToType","integerSchemaToType","numberSchemaToType","arraySchemaToType","objectSchemaToType","format","scalarName","mods","minLength","maxLength","len","min","max","pattern","regex","minimum","maximum","prefixItems","items","item","minItems","maxItems","key","required","Set","propSchema","propCtx","fieldType","effectiveType","nonNull","filter","m","visibility","readOnly","writeOnly","optional","default","deprecated","Array","isArray","t","includes","xml","externalDocs","info","not","extractInlineModel","suggestedName","sanitizeName","cleaned","replace","split","Boolean","part","charAt","toUpperCase","slice","join","LOC","file","line","HTTP_METHODS","pathsToRoutes","doc","ctx","routes","routeTags","Map","paths","path","pathItem","Object","entries","result","pathItemToRoute","push","route","set","tag","operations","primaryTag","pathParams","parameters","filter","p","in","method","op","opNode","operationToNode","tags","length","params","buildPathParams","loc","kind","nodes","description","includeComments","pathPrefix","encodePathSegment","schemaCtx","makeSchemaCtx","node","responses","operationId","sdk","deprecated","modifiers","queryParams","headerParams","param","parameterToNode","query","headers","requestBody","request","requestBodyToNode","toPascalCase","code","resp","statusCode","parseInt","isNaN","respNode","responseToNode","security","undefined","convertSecurity","pathLevelParams","paramMap","name","has","templateNames","matchAll","map","m","get","optional","nullable","type","schema","schemaToTypeNode","required","reqBody","operationName","content","supported","Set","bodies","contentType","mediaType","typeNode","model","extractInlineModel","extractedModels","bodyType","convertResponseHeaders","out","header","circularRefs","warnings","namedSchemas","inlineCounter","input","replace","split","Boolean","part","charAt","toUpperCase","slice","join","s","splitByTag","models","routes","routeTags","routesByTag","Map","route","tag","get","group","push","set","modelsByTag","tagRoutes","refs","Set","collectRouteRefs","modelNameToModel","map","m","name","modelAssignment","model","tags","has","length","collectModelRefs","ref","currentTag","otherTags","entries","filter","t","r","result","allTags","keys","values","tagModels","filename","sanitizeFilename","kind","meta","area","services","file","mergeIntoSingle","params","collectParamSourceRefs","op","operations","query","headers","request","body","bodies","collectTypeRefs","bodyType","resp","responses","source","add","Array","isArray","param","type","item","items","key","value","member","members","field","fields","inner","bases","b","toLowerCase","replace","INDENT","astToCk","root","options","includeComments","ctx","parts","optionsBlock","serializeOptions","push","model","models","serializeModel","route","routes","serializeRoute","join","hasKeys","Object","keys","meta","length","hasServices","services","hasSecurity","security","undefined","lines","key","value","entries","name","path","sec","policy","prefixes","inputCase","mode","deprecated","prefix","comment","description","type","serializeType","bases","field","fields","serializeField","depth","indent","repeat","optional","visibility","typeStr","nullable","typeContainsNull","defaultVal","default","serializeDefault","kind","members","some","test","String","serializeScalar","serializeArray","items","map","values","serializeLiteral","discriminator","serializeInlineObject","inner","args","len","min","max","regex","format","item","modePrefix","modStr","serializeModifiers","modifiers","params","serializeParamSource","paramsMode","serializeSecurityBlock","op","operations","serializeOperation","method","service","sdk","signature","sigComment","signatureDescription","query","queryMode","headers","headersMode","request","serializeRequest","responses","serializeResponses","keyword","source","node","modeStr","param","nodes","body","bodies","contentType","bodyType","resp","hasBody","hasHeaders","statusCode","h","opt","trail","policyDescription","readFileSync","parse","parseYaml","WarningCollector","warnings","onWarning","warn","path","message","add","severity","info","warning","push","convertOpenApiToCk","options","split","includeComments","warnings","WarningCollector","onWarning","rawDoc","parseInput","input","doc","normalize","schemas","sanitizeSchemaNames","circularRefs","detectCircularRefs","extractedModels","schemaCtx","path","namedSchemas","inlineCounter","models","schemasToModels","routes","routeTags","pathsToRoutes","globalSecurity","security","files","Map","ckRoots","splitByTag","filename","root","set","astToCk","mergeIntoSingle","content","readFileSync","parseJsonOrYaml","JSON","parse","parseYaml","original","components","sanitized","nameMap","name","Object","keys","clean","sanitizeName","warn","i","size","updateRefs","obj","Array","isArray","item","record","$ref","match","has","get","value","values"]}
|
package/dist/index.js
CHANGED
package/dist/plugin.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractkit/openapi-to-ck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Convert OpenAPI specs (2.0/3.0/3.1) to Contract Kit .ck files",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Marooned Software",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@scalar/openapi-parser": "^0.26.1",
|
|
31
31
|
"yaml": "^2.8.3",
|
|
32
|
-
"@contractkit/core": "0.
|
|
32
|
+
"@contractkit/core": "0.18.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@repo/config-eslint": "0.3.1",
|
package/src/ast-to-ck.ts
CHANGED
|
@@ -84,8 +84,9 @@ function serializeOptions(root: CkRootNode): string | null {
|
|
|
84
84
|
lines.push(`${INDENT}${INDENT}none`);
|
|
85
85
|
} else {
|
|
86
86
|
const sec = root.security as SecurityFields;
|
|
87
|
-
if (sec.
|
|
88
|
-
|
|
87
|
+
if (sec.policy !== undefined) {
|
|
88
|
+
const value = sec.policy === false ? 'none' : sec.policy;
|
|
89
|
+
lines.push(`${INDENT}${INDENT}policy: ${value}`);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
lines.push(`${INDENT}}`);
|
|
@@ -406,10 +407,11 @@ function serializeSecurityBlock(lines: string[], security: SecurityNode, depth:
|
|
|
406
407
|
}
|
|
407
408
|
|
|
408
409
|
const sec = security as SecurityFields;
|
|
409
|
-
if (sec.
|
|
410
|
-
const comment = ctx.includeComments && sec.
|
|
410
|
+
if (sec.policy !== undefined) {
|
|
411
|
+
const comment = ctx.includeComments && sec.policyDescription ? ` # ${sec.policyDescription}` : '';
|
|
412
|
+
const value = sec.policy === false ? 'none' : sec.policy;
|
|
411
413
|
lines.push(`${indent}security: {`);
|
|
412
|
-
lines.push(`${INDENT.repeat(depth + 1)}
|
|
414
|
+
lines.push(`${INDENT.repeat(depth + 1)}policy: ${value}${comment}`);
|
|
413
415
|
lines.push(`${indent}}`);
|
|
414
416
|
} else {
|
|
415
417
|
lines.push(`${indent}security: {}`);
|
package/src/paths-to-ast.ts
CHANGED
|
@@ -315,8 +315,8 @@ function convertSecurity(security: Record<string, string[]>[]): SecurityNode {
|
|
|
315
315
|
return 'none';
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
// The DSL's security model is simpler — OpenAPI scopes/roles don't map onto
|
|
319
|
-
// so any non-empty security requirement is collapsed to "authenticated,
|
|
318
|
+
// The DSL's security model is simpler — OpenAPI scopes/roles don't map onto named policies,
|
|
319
|
+
// so any non-empty security requirement is collapsed to "authenticated, default policy".
|
|
320
320
|
return { loc: LOC };
|
|
321
321
|
}
|
|
322
322
|
|
package/tests/ast-to-ck.test.ts
CHANGED
|
@@ -327,12 +327,12 @@ describe('route serialization', () => {
|
|
|
327
327
|
expect(result).toContain(' security: none');
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
-
it('serializes security with
|
|
330
|
+
it('serializes security with policy', () => {
|
|
331
331
|
const root = ckRoot({
|
|
332
332
|
routes: [
|
|
333
333
|
opRoute('/admin', [
|
|
334
334
|
opOperation('get', {
|
|
335
|
-
security: {
|
|
335
|
+
security: { policy: 'adminWrite', loc: { file: 'test.ck', line: 1 } },
|
|
336
336
|
responses: [opResponse(200, refType('Data'), 'application/json')],
|
|
337
337
|
}),
|
|
338
338
|
]),
|
|
@@ -340,7 +340,7 @@ describe('route serialization', () => {
|
|
|
340
340
|
});
|
|
341
341
|
const result = astToCk(root);
|
|
342
342
|
expect(result).toContain(' security: {');
|
|
343
|
-
expect(result).toContain('
|
|
343
|
+
expect(result).toContain(' policy: adminWrite');
|
|
344
344
|
});
|
|
345
345
|
|
|
346
346
|
it('serializes service and sdk fields', () => {
|