@kekonic/diagrams-layout 1.0.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["rangesOverlap","EPS","centerOf"],"sources":["../src/measure/font-measurer.ts","../src/measure/text-measurer.ts","../src/measure/table-measure.ts","../src/measure/measure.ts","../src/layout/constants.ts","../src/layout/group-bounds.ts","../src/direction/index.ts","../src/topology/analyze.ts","../src/layout/elk/edge-priority.ts","../src/layout/elk/elk-ports.ts","../src/layout/elk/polish-edges.ts","../src/layout/elk/build-elk-graph.ts","../src/layout/elk/elk-engine.ts","../src/layout/attach-endpoints.ts","../src/layout/region-arrange.ts","../src/layout/route-orthogonal-avoid.ts","../src/layout/elk/layout-arranged.ts","../src/layout/sequence/layout-sequence.ts","../src/layout/elk/layout-with-elk.ts","../src/layout-from-graph.ts","../src/measure/browser-font.ts","../src/layout/erd-snap.ts"],"sourcesContent":["import * as opentypeNs from \"opentype.js\";\nimport type { Font } from \"opentype.js\";\nimport type {\n TextMeasurer,\n TextMetrics,\n TextStyle,\n WrapOptions,\n WrappedText,\n} from \"./text-measurer.ts\";\nimport { LINE_HEIGHT } from \"./text-measurer.ts\";\n\ntype OpentypeApi = { parse: (buffer: Buffer | ArrayBuffer) => Font };\ntype OpentypeModule = { parse?: OpentypeApi[\"parse\"]; [key: string]: unknown };\nconst opentypeModule = opentypeNs as unknown as OpentypeModule;\nconst defaultExportKey: string = \"default\";\nconst opentype =\n typeof opentypeModule.parse === \"function\"\n ? (opentypeModule as OpentypeApi)\n : (opentypeModule[defaultExportKey] as OpentypeApi);\n\nlet cachedFont: Font | null | undefined;\n\nfunction loadDefaultFont(): opentype.Font | null {\n if (typeof document !== \"undefined\") return null;\n if (cachedFont !== undefined) return cachedFont;\n try {\n // Keep Node builtins out of browser bundles. Static `node:*` imports are\n // externalized by Vite and can throw as soon as the client module loads,\n // even though browsers take the canvas-measurement path instead.\n const runtimeProcess = (\n globalThis as typeof globalThis & {\n process?: { getBuiltinModule?: (id: string) => unknown };\n }\n ).process;\n const moduleBuiltin = runtimeProcess?.getBuiltinModule?.(\"module\") as\n | typeof import(\"node:module\")\n | undefined;\n const fsBuiltin = runtimeProcess?.getBuiltinModule?.(\"fs\") as\n | typeof import(\"node:fs\")\n | undefined;\n if (!moduleBuiltin || !fsBuiltin) return null;\n\n const { createRequire } = moduleBuiltin;\n const { readFileSync } = fsBuiltin;\n const nodeRequire = createRequire(import.meta.url);\n const fontPath = nodeRequire.resolve(\"@fontsource/inter/files/inter-latin-500-normal.woff\");\n const buffer = readFileSync(fontPath);\n cachedFont = opentype.parse(buffer);\n return cachedFont;\n } catch {\n cachedFont = null;\n return null;\n }\n}\n\nexport function createFontFileMeasurer(): TextMeasurer | null {\n const font = loadDefaultFont();\n if (!font) return null;\n\n return {\n measureText(text: string, style: TextStyle): TextMetrics {\n const scale = style.fontSize / font.unitsPerEm;\n let width = 0;\n for (const ch of text) {\n const glyph = font.charToGlyph(ch);\n width += (glyph.advanceWidth ?? 0) * scale;\n }\n const ascent = (font.ascender ?? font.unitsPerEm * 0.8) * scale;\n const descent = Math.abs(font.descender ?? font.unitsPerEm * 0.2) * scale;\n return { width, height: ascent + descent, ascent, descent };\n },\n\n wrapText(text: string, options: WrapOptions): WrappedText {\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n let maxW = 0;\n for (const word of words) {\n const test = current ? `${current} ${word}` : word;\n const w = this.measureText(test, options.style).width;\n if (w > options.maxWidth && current) {\n lines.push(current);\n maxW = Math.max(maxW, this.measureText(current, options.style).width);\n current = word;\n } else {\n current = test;\n }\n }\n if (current) {\n lines.push(current);\n maxW = Math.max(maxW, this.measureText(current, options.style).width);\n }\n const lineH = options.style.fontSize * LINE_HEIGHT;\n return {\n lines: lines.length ? lines : [text],\n width: maxW,\n height: (lines.length || 1) * lineH,\n };\n },\n };\n}\n","/** Shared font metrics — browser canvas and approximate server fallback. */\n\nimport { createFontFileMeasurer } from \"./font-measurer.ts\";\n\nexport type TextStyle = {\n fontSize: number;\n fontFamily: string;\n fontWeight?: string;\n};\n\nexport type TextMetrics = {\n width: number;\n height: number;\n ascent: number;\n descent: number;\n};\n\nexport type WrapOptions = {\n maxWidth: number;\n style: TextStyle;\n};\n\nexport type WrappedText = {\n lines: string[];\n width: number;\n height: number;\n};\n\nexport type TextMeasurer = {\n measureText(text: string, style: TextStyle): TextMetrics;\n wrapText(text: string, options: WrapOptions): WrappedText;\n};\n\nexport const DEFAULT_FONT_FAMILY = '\"Inter\", \"Segoe UI\", system-ui, sans-serif';\n/** Must match `.flow-node-title` / SVG titleSize (15px). */\nexport const DEFAULT_FONT_SIZE = 15;\nexport const LINE_HEIGHT = 1.2;\nconst CHAR_WIDTH_RATIO = 0.55;\n\nlet measurerUsesFallback = false;\n\nexport function measurerUsedApproximationFallback(): boolean {\n return measurerUsesFallback;\n}\n\nfunction createDefaultMeasurer(): TextMeasurer {\n if (typeof document !== \"undefined\") {\n return createCanvasMeasurer();\n }\n const fontMeasurer = createFontFileMeasurer();\n if (fontMeasurer) return fontMeasurer;\n measurerUsesFallback = true;\n return createApproximateMeasurer();\n}\n\nfunction createApproximateMeasurer(): TextMeasurer {\n return {\n measureText(text: string, style: TextStyle): TextMetrics {\n const width = text.length * style.fontSize * CHAR_WIDTH_RATIO;\n return {\n width,\n height: style.fontSize * LINE_HEIGHT,\n ascent: style.fontSize * 0.8,\n descent: style.fontSize * 0.2,\n };\n },\n wrapText(text: string, options: WrapOptions): WrappedText {\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n let maxW = 0;\n for (const word of words) {\n const test = current ? `${current} ${word}` : word;\n const w = test.length * options.style.fontSize * CHAR_WIDTH_RATIO;\n if (w > options.maxWidth && current) {\n lines.push(current);\n maxW = Math.max(maxW, current.length * options.style.fontSize * CHAR_WIDTH_RATIO);\n current = word;\n } else {\n current = test;\n }\n }\n if (current) {\n lines.push(current);\n maxW = Math.max(maxW, current.length * options.style.fontSize * CHAR_WIDTH_RATIO);\n }\n const lineH = options.style.fontSize * LINE_HEIGHT;\n return {\n lines: lines.length ? lines : [text],\n width: maxW,\n height: (lines.length || 1) * lineH,\n };\n },\n };\n}\n\nexport function createCanvasMeasurer(canvas?: HTMLCanvasElement): TextMeasurer {\n const c = canvas ?? (typeof document !== \"undefined\" ? document.createElement(\"canvas\") : null);\n const ctx = c?.getContext(\"2d\") ?? null;\n\n return {\n measureText(text: string, style: TextStyle): TextMetrics {\n if (ctx) {\n ctx.font = `${style.fontWeight ?? \"500\"} ${style.fontSize}px ${style.fontFamily}`;\n const m = ctx.measureText(text);\n const ascent = m.actualBoundingBoxAscent ?? style.fontSize * 0.8;\n const descent = m.actualBoundingBoxDescent ?? style.fontSize * 0.2;\n return { width: m.width, height: ascent + descent, ascent, descent };\n }\n const width = text.length * style.fontSize * CHAR_WIDTH_RATIO;\n return {\n width,\n height: style.fontSize * LINE_HEIGHT,\n ascent: style.fontSize * 0.8,\n descent: style.fontSize * 0.2,\n };\n },\n\n wrapText(text: string, options: WrapOptions): WrappedText {\n const words = text.split(/\\s+/);\n const lines: string[] = [];\n let current = \"\";\n let maxW = 0;\n for (const word of words) {\n const test = current ? `${current} ${word}` : word;\n const w = this.measureText(test, options.style).width;\n if (w > options.maxWidth && current) {\n lines.push(current);\n maxW = Math.max(maxW, this.measureText(current, options.style).width);\n current = word;\n } else {\n current = test;\n }\n }\n if (current) {\n lines.push(current);\n maxW = Math.max(maxW, this.measureText(current, options.style).width);\n }\n const lineH = options.style.fontSize * LINE_HEIGHT;\n return {\n lines: lines.length ? lines : [text],\n width: maxW,\n height: (lines.length || 1) * lineH,\n };\n },\n };\n}\n\nlet _defaultMeasurer: TextMeasurer | undefined;\n\nexport function resetDefaultMeasurer(): void {\n _defaultMeasurer = undefined;\n measurerUsesFallback = false;\n}\n\nfunction lazyDefaultMeasurer(): TextMeasurer {\n if (!_defaultMeasurer) _defaultMeasurer = createDefaultMeasurer();\n return _defaultMeasurer;\n}\n\nexport const defaultMeasurer: TextMeasurer = {\n measureText(text, style) {\n return lazyDefaultMeasurer().measureText(text, style);\n },\n wrapText(text, options) {\n return lazyDefaultMeasurer().wrapText(text, options);\n },\n};\n","import type { GraphNode, TableColumn } from \"@kekonic/diagrams-core\";\nimport { DEFAULT_FONT_FAMILY, type TextMeasurer } from \"./text-measurer.ts\";\n\n/** Dense ERD chrome — flatter and tighter than architecture cards. */\nexport const TABLE_PAD_X = 10;\nexport const TABLE_HEADER_H = 28;\nexport const TABLE_ROW_H = 20;\n/** Badge chip width — must match SVG render. */\nexport const TABLE_BADGE_W = 18;\nexport const TABLE_BADGE_GAP = 3;\n/**\n * Fixed key-badge gutter (fits PK+FK, or empty spacer).\n * Names always start at padX + KEY_COL regardless of how many key chips are present.\n */\nexport const TABLE_KEY_COL = TABLE_BADGE_W * 2 + TABLE_BADGE_GAP + 4;\nexport const TABLE_TYPE_GAP = 10;\nexport const TABLE_MIN_W = 180;\nexport const TABLE_RX = 4;\n/** Gap between type / NN / note in the right-side attrs cluster. */\nexport const TABLE_ATTR_GAP = 6;\n\nexport type TableMeasure = {\n width: number;\n height: number;\n headerHeight: number;\n rowHeight: number;\n labelLines: string[];\n};\n\nexport function isErdTableNode(node: GraphNode): boolean {\n return node.shape === \"table\" && Boolean(node.columns && node.columns.length > 0);\n}\n\nexport function columnAnchorY(tableTop: number, rowIndex: number, scale = 1): number {\n const headerH = TABLE_HEADER_H * scale;\n const rowH = TABLE_ROW_H * scale;\n return tableTop + headerH + rowIndex * rowH + rowH / 2;\n}\n\n/** SQL-ish type only — muted mono on the right (flags/notes are separate). */\nexport function columnTypeLabel(col: TableColumn): string {\n return col.type?.trim() ?? \"\";\n}\n\n/** Enum / comment secondary text — never joined into the type with bullets. */\nexport function columnNoteLabel(col: TableColumn): string {\n return col.note?.trim() ?? \"\";\n}\n\n/**\n * Size an ERD table card from its title + columns using the shared text measurer.\n */\nexport function measureTableNode(\n node: GraphNode,\n measurer: TextMeasurer,\n scale: number,\n effectiveMinW: number,\n _effectiveMaxW: number,\n): TableMeasure {\n const padX = TABLE_PAD_X * scale;\n const headerH = TABLE_HEADER_H * scale;\n const rowH = TABLE_ROW_H * scale;\n const keyCol = TABLE_KEY_COL * scale;\n const typeGap = TABLE_TYPE_GAP * scale;\n const attrGap = TABLE_ATTR_GAP * scale;\n const titleSize = 12 * scale;\n const colNameSize = 11 * scale;\n const colTypeSize = 10 * scale;\n const colNoteSize = 9.5 * scale;\n\n const titleMetrics = measurer.measureText(node.label, {\n fontSize: titleSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"700\",\n });\n\n let maxRowContent = 0;\n const columns = node.columns ?? [];\n for (const col of columns) {\n const nameW = measurer.measureText(col.name, {\n fontSize: colNameSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"600\",\n }).width;\n const typeLabel = columnTypeLabel(col);\n const noteLabel = columnNoteLabel(col);\n const typeW = typeLabel\n ? measurer.measureText(typeLabel, {\n fontSize: colTypeSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"500\",\n }).width\n : 0;\n const noteW = noteLabel\n ? measurer.measureText(noteLabel, {\n fontSize: colNoteSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"500\",\n }).width\n : 0;\n // Quiet \"NN\" on the type side (not in the key gutter), so names stay aligned.\n const nnW = col.notNull\n ? measurer.measureText(\"NN\", {\n fontSize: colTypeSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"700\",\n }).width\n : 0;\n const parts = [typeW, nnW, noteW].filter((w) => w > 0);\n const attrsW = parts.reduce((sum, w) => sum + w, 0) + Math.max(0, parts.length - 1) * attrGap;\n // Fixed key gutter + name + right attrs — badge count never shifts the name column.\n maxRowContent = Math.max(maxRowContent, keyCol + nameW + (attrsW ? typeGap + attrsW : 0));\n }\n\n const contentW = Math.max(titleMetrics.width + 8 * scale, maxRowContent) + padX * 2;\n // Size to content so right-anchored type/note never paint over the field name.\n // Kind default maxWidth is a soft preference elsewhere; ERD rows must fit their attrs.\n const width = Math.max(effectiveMinW, TABLE_MIN_W * scale, contentW);\n const height = headerH + Math.max(1, columns.length) * rowH;\n\n return {\n width,\n height,\n headerHeight: headerH,\n rowHeight: rowH,\n labelLines: [node.label],\n };\n}\n\n/** Key chips only (PK/FK/UK) — fixed left gutter; NN is not a key. */\nexport function tableKeyBadges(col: TableColumn): string[] {\n const badges: string[] = [];\n if (col.keys.includes(\"pk\")) badges.push(\"PK\");\n if (col.keys.includes(\"fk\")) badges.push(\"FK\");\n if (col.keys.includes(\"uk\")) badges.push(\"UK\");\n return badges;\n}\n","import type { Rect } from \"@kekonic/diagrams-core\";\nimport type { GraphModel } from \"@kekonic/diagrams-core\";\nimport { getKindDefaults, kindHasCapability, kindSubtitle } from \"@kekonic/diagrams-core\";\nimport {\n geometrySizeForContent,\n normalizeShapeId,\n relativeContentBox,\n resolveShapeGeometry,\n} from \"@kekonic/diagrams-geometry\";\nimport { iconDisplaySize, resolveIcon } from \"@kekonic/diagrams-icons\";\nimport {\n DEFAULT_FONT_FAMILY,\n DEFAULT_FONT_SIZE,\n type TextMeasurer,\n defaultMeasurer,\n} from \"./text-measurer.ts\";\nimport { measureTableNode } from \"./table-measure.ts\";\n\nexport type MeasuredNode = {\n nodeId: string;\n width: number;\n height: number;\n contentBox: Rect;\n labelLines: string[];\n /** C4 technology tag lines (usually one). */\n technologyLines?: string[];\n /** Wrapped C4 / architecture description body. */\n descriptionLines?: string[];\n};\n\nexport type MeasureOptions = {\n /** Reserve vertical space for kind subtitles when presentation opts into them. */\n reserveKindSubtitles?: boolean;\n};\n\nexport type MeasureResult = {\n nodes: MeasuredNode[];\n measureMs: number;\n};\n\nconst PADDING_X = 22;\nconst PADDING_Y = 20;\nconst RICH_PADDING_Y = 26;\nconst ICON_BLOCK = 28;\nconst SUBTITLE_HEIGHT = 15;\nconst TECHNOLOGY_HEIGHT = 14;\nconst DESCRIPTION_LINE_HEIGHT = 14;\nconst SECTION_GAP = 4;\nconst NOTE_HEIGHT = 14;\nconst MIN_ICON_COL = 32;\nconst CARD_ICON_HEIGHT = 20;\n/** Matches SVG `CARD_PAD + ICON_TEXT_GAP` (18 + 12). */\nconst CARD_ICON_PAD = 30;\nconst ICON_ONLY_SIZE = 64;\nconst ICON_ONLY_CAPTION = 16;\nconst SHAPE_EXTRA: Record<string, { w: number; h: number }> = {\n diamond: { w: 36, h: 36 },\n cylinder: { w: 10, h: 22 },\n hexagon: { w: 18, h: 10 },\n person: { w: 24, h: 0 },\n queue: { w: 18, h: 18 },\n parallelogram: { w: 24, h: 8 },\n trapezoid: { w: 20, h: 8 },\n triangle: { w: 16, h: 20 },\n document: { w: 8, h: 16 },\n \"folded-document\": { w: 8, h: 12 },\n cloud: { w: 28, h: 24 },\n circle: { w: 12, h: 12 },\n ellipse: { w: 16, h: 16 },\n boundary: { w: 8, h: 8 },\n};\n\n/** Left icon column width for card nodes (matches SVG placement). */\nexport function cardIconColumnWidth(iconId: string, scale = 1): number {\n const height = CARD_ICON_HEIGHT * scale;\n const resolved = resolveIcon(iconId);\n const { width } = iconDisplaySize(resolved ?? { width: 1, height: 1 }, height);\n return Math.max(MIN_ICON_COL * scale, width);\n}\n\nexport function measureGraph(\n graph: GraphModel,\n measurer: TextMeasurer = defaultMeasurer,\n options: MeasureOptions = {},\n): MeasureResult {\n const start = performance.now();\n const nodes: MeasuredNode[] = [];\n\n for (const node of graph.nodes) {\n const shape = normalizeShapeId(node.shape ?? \"rounded\");\n const geometry = resolveShapeGeometry(shape);\n const cardShape = shape === \"rounded\" || shape === \"rectangle\" || shape === \"pill\";\n const hasIcon = Boolean(node.icon && node.icon !== \"none\");\n const { defaults: kindDefaults } = getKindDefaults(node.kind);\n const iconOnly =\n kindHasCapability(node.kind, \"icon-only\") || kindDefaults.capabilities.includes(\"icon-only\");\n const scale = node.scale && node.scale > 0 ? node.scale : 1;\n const fontSize = DEFAULT_FONT_SIZE * scale;\n const padX = PADDING_X * scale;\n const hasRichCopy = Boolean(\n (node.technology && node.technology.trim()) || (node.description && node.description.trim()),\n );\n const padY = (hasRichCopy ? RICH_PADDING_Y : PADDING_Y) * scale;\n const minBoxH = 56 * scale;\n const effectiveMinW =\n (node.minWidth ?? kindDefaults.defaultMinWidth) * (node.minWidth ? 1 : scale);\n const effectiveMaxW =\n (node.maxWidth ?? kindDefaults.defaultMaxWidth) * (node.maxWidth ? 1 : scale);\n\n if (iconOnly) {\n const caption = node.labelAuthored\n ? measurer.wrapText(node.label, {\n maxWidth: effectiveMaxW - padX,\n style: {\n fontSize: fontSize * 0.72,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"700\",\n },\n })\n : { lines: [] as string[], width: 0, height: 0 };\n const side = Math.max(\n effectiveMinW,\n Math.min(\n effectiveMaxW,\n ICON_ONLY_SIZE * scale + (caption.height > 0 ? ICON_ONLY_CAPTION * scale : 0),\n ),\n );\n const height = Math.max(side, ICON_ONLY_SIZE * scale + caption.height);\n nodes.push({\n nodeId: node.id,\n width: side,\n height,\n contentBox: relativeContentBox(geometry, side, height),\n labelLines: caption.lines,\n });\n continue;\n }\n\n if (shape === \"table\" && node.columns && node.columns.length > 0) {\n const table = measureTableNode(node, measurer, scale, effectiveMinW, effectiveMaxW);\n nodes.push({\n nodeId: node.id,\n width: table.width,\n height: table.height,\n contentBox: relativeContentBox(geometry, table.width, table.height),\n labelLines: table.labelLines,\n });\n continue;\n }\n\n if (shape === \"diamond\") {\n const innerMaxW = (effectiveMaxW - padX * 2) * 0.58;\n const wrapped = measurer.wrapText(node.label, {\n maxWidth: innerMaxW,\n style: { fontSize, fontFamily: DEFAULT_FONT_FAMILY, fontWeight: \"800\" },\n });\n const longestLine = Math.max(\n ...wrapped.lines.map(\n (line) =>\n measurer.measureText(line, {\n fontSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"800\",\n }).width,\n ),\n wrapped.width,\n );\n const contentNeed = {\n width: longestLine + padX * 2,\n height: wrapped.height + padY * 2,\n };\n const sized = geometrySizeForContent(geometry, contentNeed, {\n width: Math.max(effectiveMinW, contentNeed.width * 1.7),\n height: Math.max(80 * scale, contentNeed.height * 1.9),\n });\n // maxWidth is a wrap preference — never clip below the measured content.\n const width = Math.max(effectiveMinW, sized.width);\n const height = Math.max(80 * scale, sized.height);\n nodes.push({\n nodeId: node.id,\n width,\n height,\n contentBox: relativeContentBox(geometry, width, height),\n labelLines: wrapped.lines,\n });\n continue;\n }\n\n const iconCol = cardShape && hasIcon && node.icon ? cardIconColumnWidth(node.icon, scale) : 0;\n const wrapped = measurer.wrapText(node.label, {\n maxWidth: effectiveMaxW - padX * 2 - iconCol,\n style: { fontSize, fontFamily: DEFAULT_FONT_FAMILY, fontWeight: \"800\" },\n });\n const extra = SHAPE_EXTRA[shape] ?? { w: 0, h: 0 };\n const iconW = cardShape && hasIcon ? iconCol + CARD_ICON_PAD * scale : hasIcon ? 8 * scale : 0;\n const iconH = hasIcon && !cardShape ? ICON_BLOCK * scale : 0;\n const authoredSubtitle = node.subtitle?.trim() ? node.subtitle.trim() : undefined;\n const wantsSubtitle =\n Boolean(authoredSubtitle) || node.showSubtitle === true || options.reserveKindSubtitles;\n // Reserve eyebrow space whenever the node asks for a subtitle (any shape).\n const subtitleH = wantsSubtitle ? SUBTITLE_HEIGHT * scale : 0;\n let subtitleW = 0;\n if (wantsSubtitle) {\n const subtitleSize = fontSize * (10.5 / DEFAULT_FONT_SIZE);\n const subtitleText = (authoredSubtitle ?? kindSubtitle(node.kind)).toUpperCase();\n const measured = measurer.measureText(subtitleText, {\n fontSize: subtitleSize,\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"600\",\n }).width;\n const tracking = Math.max(0, subtitleText.length - 1) * subtitleSize * 0.05;\n subtitleW = measured + tracking;\n }\n const noteH = node.note ? NOTE_HEIGHT * scale : 0;\n let noteW = 0;\n if (node.note) {\n noteW = measurer.measureText(node.note, {\n fontSize: fontSize * (9 / DEFAULT_FONT_SIZE),\n fontFamily: DEFAULT_FONT_FAMILY,\n fontWeight: \"400\",\n }).width;\n }\n const technology = node.technology?.trim() ? node.technology.trim() : undefined;\n const description = node.description?.trim() ? node.description.trim() : undefined;\n const textMaxW = effectiveMaxW - padX * 2 - iconCol;\n const sectionGap = SECTION_GAP * scale;\n\n let technologyLines: string[] | undefined;\n let technologyW = 0;\n let technologyH = 0;\n if (technology) {\n const techSize = fontSize * (11 / DEFAULT_FONT_SIZE);\n const techWrap = measurer.wrapText(technology, {\n maxWidth: textMaxW,\n style: { fontSize: techSize, fontFamily: DEFAULT_FONT_FAMILY, fontWeight: \"500\" },\n });\n technologyLines = techWrap.lines;\n technologyW = techWrap.width;\n technologyH = technologyLines.length * TECHNOLOGY_HEIGHT * scale;\n }\n\n let descriptionLines: string[] | undefined;\n let descriptionW = 0;\n let descriptionH = 0;\n if (description) {\n const descSize = fontSize * (11 / DEFAULT_FONT_SIZE);\n const descWrap = measurer.wrapText(description, {\n maxWidth: textMaxW,\n style: { fontSize: descSize, fontFamily: DEFAULT_FONT_FAMILY, fontWeight: \"500\" },\n });\n descriptionLines = descWrap.lines;\n descriptionW = descWrap.width;\n descriptionH = descriptionLines.length * DESCRIPTION_LINE_HEIGHT * scale;\n }\n\n const afterSubtitleGap = technologyLines || descriptionLines ? sectionGap : 0;\n const afterTechGap = technologyLines && descriptionLines ? sectionGap : 0;\n\n // Person: head is the glyph — don't reserve stack space for a nested icon unless authored.\n const personIconH =\n shape === \"person\" && hasIcon ? ICON_BLOCK * scale : shape === \"person\" ? 0 : iconH;\n const textStackH =\n wrapped.height +\n subtitleH +\n afterSubtitleGap +\n technologyH +\n afterTechGap +\n descriptionH +\n noteH;\n const contentW =\n Math.max(wrapped.width, subtitleW, technologyW, descriptionW, noteW) +\n padX * 2 +\n extra.w * scale +\n iconW;\n const contentH = textStackH + padY * 2 + extra.h * scale + personIconH;\n // maxWidth only guides wrapping — unbreakable words / notes may grow the box.\n let width = Math.max(effectiveMinW, contentW);\n // If minWidth stretches past content, grow height too so the node doesn't look flat-stretched.\n const stretch = contentW > 0 && width > contentW ? Math.min(width / contentW, 1.45) : 1;\n let height = Math.max(minBoxH, contentH * stretch);\n // Hex / queue need enough height so side points read as intentional, not pancakes.\n if (shape === \"hexagon\" || shape === \"queue\") {\n height = Math.max(height, width * 0.44);\n }\n // Cylinders keep a short-drum proportion so the lid isn't lost on wide labels.\n if (shape === \"cylinder\") {\n height = Math.max(height, Math.min(width * 0.55, 96 * scale));\n }\n // Capsule / rounded cards: grow AABB so getContentBounds still fits the text stack.\n if (cardShape) {\n const inner = {\n width: Math.max(wrapped.width, subtitleW, technologyW, descriptionW, noteW) + iconW,\n height: textStackH,\n };\n const sized = geometrySizeForContent(geometry, inner, { width, height });\n width = Math.max(width, sized.width);\n height = Math.max(height, sized.height);\n }\n // Material cloud is 24×16 (~3:2). Short labels + centered icons otherwise\n // yield near-square boxes that squash the lobes when the path fills the AABB.\n if (shape === \"cloud\") {\n const cloudAspect = 1.5;\n width = Math.max(width, height * cloudAspect);\n }\n // Person: torso = content box (widens with label); head stacks above.\n if (shape === \"person\") {\n const bodyW = Math.max(effectiveMinW, contentW);\n const bodyH = Math.max(56 * scale, textStackH + padY * 2 + personIconH);\n // Head + neck above the torso (mirrors personHeadStackHeight in geometry).\n const bodyHalfW = Math.max(18, bodyW / 2 - 2);\n const headR = Math.max(10, Math.min(22, bodyHalfW * 0.38));\n const headStack = headR * 2 + Math.max(2, headR * 0.18) + 6;\n width = bodyW;\n height = headStack + bodyH;\n }\n if (shape === \"circle\") {\n const side = Math.max(width, height);\n width = side;\n height = side;\n }\n\n nodes.push({\n nodeId: node.id,\n width,\n height,\n contentBox: relativeContentBox(geometry, width, height),\n labelLines: wrapped.lines,\n technologyLines,\n descriptionLines,\n });\n }\n\n return { nodes, measureMs: performance.now() - start };\n}\n","import type { BoxPadding, Density } from \"@kekonic/diagrams-core\";\n\nexport const DENSITY_GAP: Record<Density, number> = {\n compact: 56,\n normal: 88,\n spacious: 116,\n};\n\nexport const DEFAULT_GROUP_PADDING: BoxPadding = {\n top: 56,\n right: 40,\n bottom: 40,\n left: 40,\n};\n\n/** Chromeless layout planes — no label headroom. */\nexport const LAYOUT_ONLY_GROUP_PADDING: BoxPadding = {\n top: 20,\n right: 20,\n bottom: 20,\n left: 20,\n};\n\nexport const PADDING_HINTS: Record<string, BoxPadding> = {\n compact: { top: 36, right: 24, bottom: 24, left: 24 },\n normal: { top: 56, right: 40, bottom: 40, left: 40 },\n spacious: { top: 88, right: 60, bottom: 60, left: 60 },\n /** Iso-pixel platforms need extra pad so chunky cards + pipes clear the rim. */\n pixel: { top: 100, right: 80, bottom: 80, left: 80 },\n};\n\nexport const GROUP_SEPARATION_MARGIN = 40;\nexport const LAYOUT_MARGIN = 64;\nexport const DEFAULT_GROUP_GAP = 72;\n","import type { BoxPadding, GraphModel, Rect } from \"@kekonic/diagrams-core\";\nimport type { LaidOutGroup, LaidOutNode } from \"./types.ts\";\nimport { DEFAULT_GROUP_PADDING, LAYOUT_ONLY_GROUP_PADDING, PADDING_HINTS } from \"./constants.ts\";\n\nconst GROUP_LABEL_FONT_SIZE = 11;\nconst GROUP_LABEL_LETTER_SPACING = 0.08;\nconst GROUP_LABEL_PADDING_X = 14;\nconst GROUP_LABEL_PADDING_Y = 10;\nexport const GROUP_ICON_SIZE = 14;\nexport const GROUP_ICON_GAP = 6;\n\nexport function paddingForGroup(group: GraphModel[\"groups\"][0]): BoxPadding {\n const chromeless = group.chrome === false;\n if (group.paddingHint && PADDING_HINTS[group.paddingHint]) {\n const p = PADDING_HINTS[group.paddingHint]!;\n // No label band — flatten top to match the horizontal inset.\n if (chromeless) return { top: p.left, right: p.right, bottom: p.bottom, left: p.left };\n return p;\n }\n // Concrete px: `padding: 48` inside a group.\n if (group.paddingHint != null) {\n const n = Number(group.paddingHint);\n if (Number.isFinite(n) && n >= 0) {\n const box = { top: n, right: n, bottom: n, left: n };\n if (chromeless) return { top: n, right: n, bottom: n, left: n };\n return box;\n }\n }\n if (chromeless) return LAYOUT_ONLY_GROUP_PADDING;\n return DEFAULT_GROUP_PADDING;\n}\n\nexport function groupBoundsFromNodes(\n graph: GraphModel,\n laidOut: LaidOutNode[],\n padding: BoxPadding,\n): Map<string, Rect> {\n const nodeMap = new Map(laidOut.map((n) => [n.nodeId, n]));\n const result = new Map<string, Rect>();\n\n for (const group of graph.groups) {\n const memberBounds = group.nodeIds\n .map((id) => nodeMap.get(id)?.bounds)\n .filter((b): b is Rect => !!b);\n if (!memberBounds.length) continue;\n\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (const b of memberBounds) {\n minX = Math.min(minX, b.x);\n minY = Math.min(minY, b.y);\n maxX = Math.max(maxX, b.x + b.width);\n maxY = Math.max(maxY, b.y + b.height);\n }\n\n result.set(group.id, {\n x: minX - padding.left,\n y: minY - padding.top,\n width: maxX - minX + padding.left + padding.right,\n height: maxY - minY + padding.top + padding.bottom,\n });\n }\n\n return result;\n}\n\nexport function measureGroupLabelBox(label: string, bounds: Rect, hasIcon = false): Rect {\n const text = label.toUpperCase();\n const charWidth = GROUP_LABEL_FONT_SIZE * (0.55 + GROUP_LABEL_LETTER_SPACING * 0.3);\n const iconExtra = hasIcon ? GROUP_ICON_SIZE + GROUP_ICON_GAP : 0;\n const width = Math.min(\n Math.max(text.length * charWidth + 8 + iconExtra, 48),\n Math.max(bounds.width - 8, 48),\n );\n const height = GROUP_LABEL_FONT_SIZE + 8;\n return {\n x: bounds.x + GROUP_LABEL_PADDING_X,\n y: bounds.y + GROUP_LABEL_PADDING_Y,\n width,\n height,\n };\n}\n\nexport function computeGroupBounds(graph: GraphModel, laidOut: LaidOutNode[]): LaidOutGroup[] {\n const result: LaidOutGroup[] = [];\n\n for (const group of graph.groups) {\n const padding = paddingForGroup(group);\n const boundsMap = groupBoundsFromNodes(graph, laidOut, padding);\n const bounds = boundsMap.get(group.id);\n if (!bounds) continue;\n const hasIcon = Boolean(group.icon && group.icon !== \"none\" && group.chrome !== false);\n result.push({\n groupId: group.id,\n bounds,\n labelBox: measureGroupLabelBox(group.label, bounds, hasIcon),\n padding,\n });\n }\n return result;\n}\n","/**\n * Direction predicates for diagram flow (`LR`/`RL`/`TD`/`BT`).\n * Used by topology analysis and ELK option mapping — not edge geometry.\n */\n\nimport type { Direction } from \"@kekonic/diagrams-core\";\n\n/** True for left↔right flow (`LR` / `RL`). */\nexport function isHorizontal(direction: Direction): boolean {\n return direction === \"LR\" || direction === \"RL\";\n}\n\n/** True for top↔bottom flow (`TD` / `BT`). */\nexport function isVertical(direction: Direction): boolean {\n return direction === \"TD\" || direction === \"BT\";\n}\n","import type { GraphModel } from \"@kekonic/diagrams-core\";\nimport type { Direction } from \"@kekonic/diagrams-core\";\nimport { isVertical } from \"../direction/index.ts\";\n\nexport type DiagramTopology = {\n direction: Direction;\n isWorkflowTD: boolean;\n choiceNodes: string[];\n mergeNodes: string[];\n fanOutNodes: string[];\n choiceBranches: Set<string>;\n incoming: Map<string, number>;\n outgoing: Map<string, number>;\n};\n\nfunction buildEdgeCounts(graph: GraphModel): {\n incoming: Map<string, number>;\n outgoing: Map<string, number>;\n} {\n const incoming = new Map<string, number>();\n const outgoing = new Map<string, number>();\n\n for (const node of graph.nodes) {\n incoming.set(node.id, 0);\n outgoing.set(node.id, 0);\n }\n\n for (const edge of graph.edges) {\n outgoing.set(edge.from, (outgoing.get(edge.from) ?? 0) + 1);\n incoming.set(edge.to, (incoming.get(edge.to) ?? 0) + 1);\n }\n\n return { incoming, outgoing };\n}\n\nexport function analyzeDiagramTopology(graph: GraphModel, direction: Direction): DiagramTopology {\n const { incoming, outgoing } = buildEdgeCounts(graph);\n\n const choiceNodes: string[] = [];\n const choiceBranches = new Set<string>();\n for (const node of graph.nodes) {\n if (node.kind === \"choice\" && (outgoing.get(node.id) ?? 0) >= 2) {\n choiceNodes.push(node.id);\n choiceBranches.add(node.id);\n }\n }\n\n const mergeNodes: string[] = [];\n const fanOutNodes: string[] = [];\n for (const node of graph.nodes) {\n if ((incoming.get(node.id) ?? 0) >= 2) mergeNodes.push(node.id);\n if ((outgoing.get(node.id) ?? 0) >= 2) fanOutNodes.push(node.id);\n }\n\n const isWorkflowTD = isVertical(direction) && choiceNodes.length > 0;\n\n return {\n direction,\n isWorkflowTD,\n choiceNodes,\n mergeNodes,\n fanOutNodes,\n choiceBranches,\n incoming,\n outgoing,\n };\n}\n\nexport function incomingCount(topology: DiagramTopology, nodeId: string): number {\n return topology.incoming.get(nodeId) ?? 0;\n}\n\nexport function outgoingCount(topology: DiagramTopology, nodeId: string): number {\n return topology.outgoing.get(nodeId) ?? 0;\n}\n\nexport function isChoiceBranch(topology: DiagramTopology, nodeId: string): boolean {\n return topology.choiceBranches.has(nodeId);\n}\n","import type { GraphEdge } from \"@kekonic/diagrams-core\";\nimport { classifyBranch, type BranchKind } from \"@kekonic/diagrams-core\";\n\nexport type LayoutBranchCue = BranchKind;\n\nexport function layoutBranchCue(edge: Pick<GraphEdge, \"label\" | \"branch\">): LayoutBranchCue {\n return edge.branch ?? classifyBranch(edge.label);\n}\n\n/**\n * Prefer a straight happy-path spine; keep exception edges short instead of scenic.\n * Explicit GraphEdge.priority amplifies or dampens the cue.\n */\nexport function elkPriorityOptionsForEdge(edge: GraphEdge): Record<string, string> {\n const cue = layoutBranchCue(edge);\n let straightness = 3;\n let shortness = 3;\n\n if (edge.kind === \"failure\" || cue === \"no\") {\n straightness = 1;\n shortness = 9;\n } else if (cue === \"yes\") {\n straightness = 9;\n shortness = 5;\n } else if (!edge.label) {\n // Unlabeled flow edges form the spine.\n straightness = 7;\n shortness = 4;\n }\n\n if (edge.priority === \"high\") {\n straightness += 3;\n shortness += 2;\n } else if (edge.priority === \"low\") {\n straightness = Math.max(0, straightness - 4);\n if (cue !== \"no\" && edge.kind !== \"failure\") {\n shortness = Math.max(1, shortness - 1);\n }\n }\n\n return {\n \"elk.layered.priority.straightness\": String(straightness),\n \"elk.layered.priority.shortness\": String(shortness),\n };\n}\n","/**\n * Per-edge ELK ports from ShapeGeometry.\n *\n * Every non-mutual edge gets a dedicated source port and target port (never a\n * shared pin). Fan-in / fan-out distribute via getPortPosition(side, index, count)\n * on the flow entry / exit faces. Mutual A↔B pairs stay node→node so ELK can\n * free-attach both shafts in the layer corridor (FIXED_POS on reverse traffic\n * forces outside loops when model order ≠ layout order).\n *\n * FIXED_POS makes ELK plan from geometry positions; snapEdgeEndpointsToGeometry\n * then locks termini to the silhouette.\n */\n\nimport type { Direction, GraphEdge, GraphModel } from \"@kekonic/diagrams-core\";\nimport {\n normalizeShapeId,\n resolveShapeGeometry,\n type PortSide as GeometryPortSide,\n} from \"@kekonic/diagrams-geometry\";\nimport type { MeasuredNode } from \"../../measure/measure.ts\";\nimport type { ElkPort } from \"./elk-engine.ts\";\nimport { layoutBranchCue } from \"./edge-priority.ts\";\n\nexport type ElkPortSide = \"NORTH\" | \"SOUTH\" | \"EAST\" | \"WEST\";\n\nexport type EdgePortAssignment = {\n /** Ports keyed by node id (includes both in and out). */\n portsByNode: Map<string, ElkPort[]>;\n /** Edge id → source port id (`node:out:edge`). */\n edgeSourcePort: Map<string, string>;\n /** Edge id → target port id (`node:in:edge`). */\n edgeTargetPort: Map<string, string>;\n /** Nodes that carry ports (need FIXED_POS). */\n portedNodes: Set<string>;\n};\n\ntype PortSpec = {\n id: string;\n edgeId: string;\n side: ElkPortSide;\n /** Sort key within a face (branch cue + edge id). */\n rank: number;\n};\n\nexport function flowExitSide(direction: Direction): ElkPortSide {\n switch (direction) {\n case \"BT\":\n return \"NORTH\";\n case \"LR\":\n return \"EAST\";\n case \"RL\":\n return \"WEST\";\n case \"TD\":\n default:\n return \"SOUTH\";\n }\n}\n\nexport function flowEntrySide(direction: Direction): ElkPortSide {\n switch (direction) {\n case \"BT\":\n return \"SOUTH\";\n case \"LR\":\n return \"WEST\";\n case \"RL\":\n return \"EAST\";\n case \"TD\":\n default:\n return \"NORTH\";\n }\n}\n\nfunction elkSideToGeometry(side: ElkPortSide): GeometryPortSide {\n switch (side) {\n case \"NORTH\":\n return \"north\";\n case \"EAST\":\n return \"east\";\n case \"WEST\":\n return \"west\";\n case \"SOUTH\":\n default:\n return \"south\";\n }\n}\n\nexport function outPortId(nodeId: string, edgeId: string): string {\n return `${nodeId}:out:${edgeId}`;\n}\n\nexport function inPortId(nodeId: string, edgeId: string): string {\n return `${nodeId}:in:${edgeId}`;\n}\n\n/** Geometry-authored 1×1 FIXED_POS port centered on getPortPosition. */\nexport function makeGeometryPort(\n id: string,\n side: ElkPortSide,\n index: number,\n count: number,\n shapeId: string | undefined,\n width: number,\n height: number,\n): ElkPort {\n const geometry = resolveShapeGeometry(normalizeShapeId(shapeId));\n const local = { x: 0, y: 0, width, height };\n const pos = geometry.getPortPosition(\n { kind: \"side\", side: elkSideToGeometry(side), index, count },\n local,\n );\n return {\n id,\n x: pos.x - 0.5,\n y: pos.y - 0.5,\n width: 1,\n height: 1,\n layoutOptions: {\n \"elk.port.side\": side,\n \"elk.port.index\": String(index),\n },\n };\n}\n\nfunction outRank(edge: GraphEdge): number {\n const cue = layoutBranchCue(edge);\n if (cue === \"yes\") return 0;\n if (cue === \"no\") return 2;\n return 1;\n}\n\n/**\n * Edges that participate in a 2-cycle (A→B and B→A).\n * These stay node→node so ELK free-attaches parallel corridor shafts.\n */\nexport function mutualEdgeIds(graph: GraphModel): Set<string> {\n const ids = new Set<string>();\n for (const edge of graph.edges) {\n if (edge.from === edge.to) continue;\n const hasReverse = graph.edges.some(\n (o) => o.id !== edge.id && o.from === edge.to && o.to === edge.from,\n );\n if (hasReverse) ids.add(edge.id);\n }\n return ids;\n}\n\nfunction materializeFacePorts(\n specs: PortSpec[],\n shapeId: string | undefined,\n width: number,\n height: number,\n): ElkPort[] {\n const bySide = new Map<ElkPortSide, PortSpec[]>();\n for (const spec of specs) {\n const list = bySide.get(spec.side) ?? [];\n list.push(spec);\n bySide.set(spec.side, list);\n }\n const ports: ElkPort[] = [];\n for (const [side, list] of bySide) {\n list.sort((a, b) => a.rank - b.rank || a.edgeId.localeCompare(b.edgeId));\n const count = list.length;\n list.forEach((spec, index) => {\n ports.push(makeGeometryPort(spec.id, side, index, count, shapeId, width, height));\n });\n }\n return ports;\n}\n\n/**\n * Assign one out-port and one in-port per non-mutual edge.\n * Positions are distributed per face so N edges on a face ⇒ N distinct pins.\n */\nexport function assignEdgePorts(\n graph: GraphModel,\n measured: MeasuredNode[],\n direction: Direction,\n): EdgePortAssignment {\n const measureMap = new Map(measured.map((m) => [m.nodeId, m]));\n const shapeByNode = new Map(graph.nodes.map((n) => [n.id, n.shape]));\n const exit = flowExitSide(direction);\n const entry = flowEntrySide(direction);\n const mutual = mutualEdgeIds(graph);\n\n const outSpecsByNode = new Map<string, PortSpec[]>();\n const inSpecsByNode = new Map<string, PortSpec[]>();\n const edgeSourcePort = new Map<string, string>();\n const edgeTargetPort = new Map<string, string>();\n\n const push = (map: Map<string, PortSpec[]>, nodeId: string, spec: PortSpec) => {\n const list = map.get(nodeId) ?? [];\n list.push(spec);\n map.set(nodeId, list);\n };\n\n for (const edge of graph.edges) {\n // Mutual pairs: leave node→node so ELK can place both shafts in-corridor.\n if (mutual.has(edge.id)) continue;\n\n const sourceId = outPortId(edge.from, edge.id);\n const targetId = inPortId(edge.to, edge.id);\n edgeSourcePort.set(edge.id, sourceId);\n edgeTargetPort.set(edge.id, targetId);\n\n push(outSpecsByNode, edge.from, {\n id: sourceId,\n edgeId: edge.id,\n side: exit,\n rank: outRank(edge),\n });\n push(inSpecsByNode, edge.to, {\n id: targetId,\n edgeId: edge.id,\n side: entry,\n rank: 1,\n });\n }\n\n const portsByNode = new Map<string, ElkPort[]>();\n const portedNodes = new Set<string>();\n\n for (const node of graph.nodes) {\n const m = measureMap.get(node.id);\n if (!m) continue;\n const outs = outSpecsByNode.get(node.id) ?? [];\n const inns = inSpecsByNode.get(node.id) ?? [];\n if (!outs.length && !inns.length) continue;\n portedNodes.add(node.id);\n const shapeId = shapeByNode.get(node.id);\n portsByNode.set(node.id, [\n ...materializeFacePorts(outs, shapeId, m.width, m.height),\n ...materializeFacePorts(inns, shapeId, m.width, m.height),\n ]);\n }\n\n return { portsByNode, edgeSourcePort, edgeTargetPort, portedNodes };\n}\n","import type { Point, Rect } from \"@kekonic/diagrams-core\";\nimport type { LayoutEdgePath } from \"../types.ts\";\n\nconst COLINEAR_EPS = 0.75;\n\n/** Floor for edge↔node clearance (layout CSS-px) — room for a bend stub + arrow. */\nexport const MIN_EDGE_NODE_CLEARANCE = 28;\n\n/** Drop redundant colinear waypoints from orthogonal ELK polylines.\n * Unlike route-orthogonal-avoid's search collapse, this may drop stubs once\n * attach points are frozen by snapEdgeEndpointsToGeometry.\n */\nexport function collapseColinearPoints(points: Point[], eps = COLINEAR_EPS): Point[] {\n if (points.length < 3) return points;\n const out: Point[] = [points[0]!];\n for (let i = 1; i < points.length - 1; i++) {\n const a = out[out.length - 1]!;\n const b = points[i]!;\n const c = points[i + 1]!;\n const vertical = Math.abs(a.x - b.x) < eps && Math.abs(b.x - c.x) < eps;\n const horizontal = Math.abs(a.y - b.y) < eps && Math.abs(b.y - c.y) < eps;\n if (vertical || horizontal) continue;\n out.push(b);\n }\n out.push(points[points.length - 1]!);\n return out;\n}\n\nfunction rangesOverlap(a0: number, a1: number, b0: number, b1: number): boolean {\n return Math.min(a0, a1) <= Math.max(b0, b1) && Math.max(a0, a1) >= Math.min(b0, b1);\n}\n\n/** Move segment endpoints that are not path termini (attach points stay fixed). */\nfunction setSegmentCoord(out: Point[], segIndex: number, axis: \"x\" | \"y\", value: number): void {\n const i = segIndex;\n const last = out.length - 1;\n if (i > 0) out[i]![axis] = value;\n if (i + 1 < last) out[i + 1]![axis] = value;\n}\n\n/**\n * Shift orthogonal corridors that run inside the keep-out around node cards\n * so 90° corners aren't parked flush on a shape edge.\n * Path endpoints (port attaches) are never moved.\n */\nexport function clearOrthogonalCorridors(points: Point[], nodes: Rect[], pad: number): Point[] {\n if (points.length < 3 || nodes.length === 0 || pad <= 0) return points;\n const out = points.map((p) => ({ x: p.x, y: p.y }));\n\n // A few passes: one shift can put another segment into a neighbor keep-out.\n for (let pass = 0; pass < 3; pass++) {\n let moved = false;\n for (let i = 0; i < out.length - 1; i++) {\n // Leave attach stubs alone — shifting only the inner end makes a diagonal.\n if (i === 0 || i === out.length - 2) continue;\n const a = out[i]!;\n const b = out[i + 1]!;\n const vert = Math.abs(a.x - b.x) < COLINEAR_EPS;\n const horz = Math.abs(a.y - b.y) < COLINEAR_EPS;\n if (!vert && !horz) continue;\n\n for (const box of nodes) {\n const L = box.x;\n const R = box.x + box.width;\n const T = box.y;\n const B = box.y + box.height;\n\n if (vert) {\n const x = (a.x + b.x) / 2;\n if (!rangesOverlap(a.y, b.y, T - pad, B + pad)) continue;\n if (x > L - pad && x < L) {\n setSegmentCoord(out, i, \"x\", L - pad);\n moved = true;\n } else if (x > R && x < R + pad) {\n setSegmentCoord(out, i, \"x\", R + pad);\n moved = true;\n }\n } else {\n const y = (a.y + b.y) / 2;\n if (!rangesOverlap(a.x, b.x, L - pad, R + pad)) continue;\n if (y > T - pad && y < T) {\n setSegmentCoord(out, i, \"y\", T - pad);\n moved = true;\n } else if (y > B && y < B + pad) {\n setSegmentCoord(out, i, \"y\", B + pad);\n moved = true;\n }\n }\n }\n }\n if (!moved) break;\n }\n\n return out;\n}\n\n/**\n * Repair any residual non-orthogonal stubs (e.g. ELK diagonal tips) by inserting\n * one corner so metro/rounded stroke rendering never draws a slash to the port.\n */\nexport function ensureOrthogonalPoints(points: Point[], eps = COLINEAR_EPS): Point[] {\n if (points.length < 2) return points;\n const out: Point[] = [{ ...points[0]! }];\n for (let i = 1; i < points.length; i++) {\n const prev = out[out.length - 1]!;\n const curr = points[i]!;\n const dx = Math.abs(curr.x - prev.x);\n const dy = Math.abs(curr.y - prev.y);\n if (dx > eps && dy > eps) {\n // Prefer continuing the prior corridor axis when present.\n const before = out.length >= 2 ? out[out.length - 2]! : null;\n const preferVertical = before != null ? Math.abs(before.x - prev.x) < eps : dy >= dx;\n out.push(preferVertical ? { x: prev.x, y: curr.y } : { x: curr.x, y: prev.y });\n }\n out.push({ ...curr });\n }\n return collapseColinearPoints(out, eps);\n}\n\n/** Light cleanup — preserve ELK topology; keep bends clear of node cards. */\nexport function polishEdgePaths(\n paths: LayoutEdgePath[],\n nodes: Rect[] = [],\n edgeNodeClearance = MIN_EDGE_NODE_CLEARANCE,\n): LayoutEdgePath[] {\n const pad = Math.max(MIN_EDGE_NODE_CLEARANCE, edgeNodeClearance);\n return paths.map((path) => ({\n ...path,\n points: ensureOrthogonalPoints(\n collapseColinearPoints(clearOrthogonalCorridors(path.points, nodes, pad)),\n ),\n }));\n}\n","import type { Direction, GraphEdge, GraphModel, LayoutOptions } from \"@kekonic/diagrams-core\";\nimport type { MeasuredNode } from \"../../measure/measure.ts\";\nimport { DENSITY_GAP, DEFAULT_GROUP_GAP, LAYOUT_MARGIN } from \"../constants.ts\";\nimport { paddingForGroup } from \"../group-bounds.ts\";\nimport { analyzeDiagramTopology } from \"../../topology/analyze.ts\";\nimport type { ElkGraph, ElkNode } from \"./elk-engine.ts\";\nimport { elkPriorityOptionsForEdge } from \"./edge-priority.ts\";\nimport { assignEdgePorts } from \"./elk-ports.ts\";\nimport { MIN_EDGE_NODE_CLEARANCE } from \"./polish-edges.ts\";\n\n/** Defaults chosen for flowchart readability — override via LayoutOptions. */\nconst DEFAULT_NODE_PLACEMENT = \"balanced\";\n\nconst ELK_NODE_PLACEMENT: Record<\n NonNullable<LayoutOptions[\"nodePlacement\"]>,\n \"BRANDES_KOEPF\" | \"NETWORK_SIMPLEX\" | \"SIMPLE\"\n> = {\n straight: \"BRANDES_KOEPF\",\n balanced: \"NETWORK_SIMPLEX\",\n basic: \"SIMPLE\",\n};\nconst DEFAULT_THOROUGHNESS = 24;\n\nfunction elkDirection(direction: Direction): string {\n switch (direction) {\n case \"RL\":\n return \"LEFT\";\n case \"TD\":\n return \"DOWN\";\n case \"BT\":\n return \"UP\";\n case \"LR\":\n default:\n return \"RIGHT\";\n }\n}\n\nfunction spacing(options: LayoutOptions): number {\n const density = options.density ?? \"normal\";\n const scale = options.spacingScale ?? 1;\n const gap = DENSITY_GAP[density] ?? DENSITY_GAP.normal;\n return Math.round(gap * scale);\n}\n\nfunction aspectRatioFor(direction: Direction): string {\n return direction === \"TD\" || direction === \"BT\" ? \"0.72\" : \"1.55\";\n}\n\n/** Resolve ELK edge endpoint ref (node id or `node:…:edge`) to owning node id. */\nexport function endpointNodeId(ref: string): string {\n const colon = ref.indexOf(\":\");\n if (colon <= 0) return ref;\n return ref.slice(0, colon);\n}\n\n/**\n * Build an ELK JSON graph from Kekonic Diagrams measure + membership.\n * Maps semantic GraphModel → ELK; no raw elk bags on Graph JSON.\n *\n * Every edge is wired port→port: source on the flow-exit face, target on the\n * flow-entry face, with per-edge FIXED_POS pins from ShapeGeometry so fan-in\n * and fan-out never share a single attach point.\n */\nexport function buildElkGraph(\n graph: GraphModel,\n measured: MeasuredNode[],\n options: LayoutOptions,\n): ElkGraph {\n const measureMap = new Map(measured.map((m) => [m.nodeId, m]));\n const gap = spacing(options);\n const groupGap = options.groupGap ?? DEFAULT_GROUP_GAP;\n const direction = options.direction ?? \"LR\";\n // Never allow flush-to-card bends — tight presets still need a stub for arrows.\n const edgeNode = Math.max(\n MIN_EDGE_NODE_CLEARANCE,\n options.edgeNodeSpacing ?? Math.round(gap * 0.6),\n );\n const edgeEdge = Math.max(12, options.edgeEdgeSpacing ?? Math.max(18, Math.round(gap * 0.36)));\n // When the studio/DSL sets groupGap, treat it as an absolute spacing override\n // (otherwise Tight can never beat comfortable density).\n const nodeNode = options.groupGap != null ? groupGap : gap;\n const layerGap = options.groupGap != null ? Math.round(groupGap * 0.9) : gap;\n const nodePlacement =\n ELK_NODE_PLACEMENT[options.nodePlacement ?? DEFAULT_NODE_PLACEMENT] ??\n ELK_NODE_PLACEMENT.straight;\n\n const topology = analyzeDiagramTopology(graph, direction);\n const portAssignment = assignEdgePorts(graph, measured, direction);\n\n const topSwimlanes = graph.groups.filter((g) => g.kind === \"swimlane\" && g.parentId == null);\n const usePartitions = options.groupLayout === \"swimlane\" || topSwimlanes.length > 0;\n // Flat = membership boxes only (no compound ELK nesting). Cross-group edges stay much\n // straighter; INCLUDE_CHILDREN compounds invent vertical channel buses in the corridor.\n const flatMembership =\n options.groupLayout === \"flat\" || (usePartitions && options.groupLayout === \"swimlane\");\n const hierarchy = flatMembership ? \"SEPARATE_CHILDREN\" : \"INCLUDE_CHILDREN\";\n\n const swimlanePartition = new Map<string, number>();\n topSwimlanes.forEach((g, i) => {\n for (const nodeId of g.nodeIds) swimlanePartition.set(nodeId, i);\n const stack = [...g.childGroupIds];\n while (stack.length) {\n const cid = stack.pop()!;\n const child = graph.groups.find((x) => x.id === cid);\n if (!child) continue;\n for (const nodeId of child.nodeIds) swimlanePartition.set(nodeId, i);\n stack.push(...child.childGroupIds);\n }\n });\n const defaultPartition = topSwimlanes.length;\n\n const incoming = topology.incoming;\n const outgoing = topology.outgoing;\n\n const rootLayoutOptions: Record<string, string> = {\n \"elk.algorithm\": \"layered\",\n \"elk.direction\": elkDirection(direction),\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n \"elk.hierarchyHandling\": hierarchy,\n \"elk.aspectRatio\": aspectRatioFor(direction),\n \"elk.layered.thoroughness\": String(DEFAULT_THOROUGHNESS),\n \"elk.layered.crossingMinimization.strategy\": \"LAYER_SWEEP\",\n \"elk.layered.nodePlacement.strategy\": nodePlacement,\n \"elk.layered.nodePlacement.bk.edgeStraightening\": \"IMPROVE_STRAIGHTNESS\",\n \"elk.layered.nodePlacement.favorStraightEdges\": \"true\",\n \"elk.layered.compaction.postCompaction.strategy\": \"EDGE_LENGTH\",\n // false = only real turns (true *adds* dummy bend points — see ELK docs).\n \"elk.layered.unnecessaryBendpoints\": \"false\",\n // false (ELK default): reverse edges stay in the layer corridor when possible.\n // true forces feedback edges to route *around* the diagram (long A↔B loops).\n \"elk.layered.feedbackEdges\": \"false\",\n \"elk.layered.considerModelOrder.strategy\":\n options.considerModelOrder === false ? \"NONE\" : \"NODES_AND_EDGES\",\n // Do not attach edge labels to ELK — KDiagram places them after layout.\n // ELK inline labels create rectangular \"pockets\" on otherwise straight edges.\n \"elk.padding\": `[top=${LAYOUT_MARGIN},left=${LAYOUT_MARGIN},bottom=${LAYOUT_MARGIN},right=${LAYOUT_MARGIN}]`,\n \"elk.spacing.nodeNode\": String(nodeNode),\n \"elk.layered.spacing.nodeNodeBetweenLayers\": String(layerGap),\n \"elk.spacing.edgeNode\": String(edgeNode),\n \"elk.layered.spacing.edgeNodeBetweenLayers\": String(edgeNode),\n \"elk.spacing.edgeEdge\": String(edgeEdge),\n \"elk.layered.spacing.edgeEdgeBetweenLayers\": String(edgeEdge),\n \"elk.spacing.componentComponent\": String(groupGap),\n };\n\n if (usePartitions) {\n rootLayoutOptions[\"elk.partitioning.activate\"] = \"true\";\n }\n\n const crossGroupEdges = graph.edges.some((e) => {\n const a = graph.nodes.find((n) => n.id === e.from)?.groupId;\n const b = graph.nodes.find((n) => n.id === e.to)?.groupId;\n return a !== b;\n });\n if (crossGroupEdges && !flatMembership) {\n rootLayoutOptions[\"elk.layered.mergeHierarchyEdges\"] = \"true\";\n }\n\n const groupsByParent = new Map<string | undefined, typeof graph.groups>();\n for (const g of graph.groups) {\n // Flat / swimlane: do not nest compound ELK nodes; membership boxes are painted later.\n if (flatMembership) continue;\n const key = g.parentId;\n const list = groupsByParent.get(key) ?? [];\n list.push(g);\n groupsByParent.set(key, list);\n }\n\n const assignedNodes = new Set<string>();\n\n const nodeLayoutOptions = (nodeId: string): Record<string, string> => {\n const opts: Record<string, string> = {};\n const out = outgoing.get(nodeId) ?? 0;\n const inn = incoming.get(nodeId) ?? 0;\n if (out === 0 && inn > 0) opts[\"elk.layered.layering.layerConstraint\"] = \"LAST\";\n if (inn === 0 && out > 0) opts[\"elk.layered.layering.layerConstraint\"] = \"FIRST\";\n if (portAssignment.portedNodes.has(nodeId)) opts[\"elk.portConstraints\"] = \"FIXED_POS\";\n if (usePartitions) {\n opts[\"elk.partitioning.partition\"] = String(\n swimlanePartition.get(nodeId) ?? defaultPartition,\n );\n }\n return opts;\n };\n\n const buildLeaf = (nodeId: string, m: MeasuredNode): ElkNode => {\n const layoutOptions = nodeLayoutOptions(nodeId);\n const ports = portAssignment.portsByNode.get(nodeId);\n return {\n id: nodeId,\n width: m.width,\n height: m.height,\n ...(Object.keys(layoutOptions).length ? { layoutOptions } : {}),\n ...(ports?.length ? { ports } : {}),\n };\n };\n\n const buildGroupNode = (groupId: string): ElkNode => {\n const group = graph.groups.find((g) => g.id === groupId)!;\n const pad = paddingForGroup(group);\n const children: ElkNode[] = [];\n\n for (const nodeId of group.nodeIds) {\n const m = measureMap.get(nodeId);\n if (!m) continue;\n assignedNodes.add(nodeId);\n children.push(buildLeaf(nodeId, m));\n }\n\n for (const child of groupsByParent.get(groupId) ?? []) {\n children.push(buildGroupNode(child.id));\n }\n\n return {\n id: `group:${group.id}`,\n children,\n labels: group.label\n ? [{ id: `group:${group.id}:label`, text: group.label, width: 80, height: 18 }]\n : undefined,\n layoutOptions: {\n \"elk.padding\": `[top=${pad.top},left=${pad.left},bottom=${pad.bottom},right=${pad.right}]`,\n \"elk.spacing.nodeNode\": String(Math.round(gap * 0.8)),\n \"elk.layered.spacing.nodeNodeBetweenLayers\": String(Math.round(gap * 0.8)),\n \"elk.layered.nodePlacement.strategy\": nodePlacement,\n \"elk.layered.nodePlacement.favorStraightEdges\": \"true\",\n \"elk.contentAlignment\": \"V_CENTER H_CENTER\",\n },\n };\n };\n\n const children: ElkNode[] = [];\n\n for (const top of groupsByParent.get(undefined) ?? []) {\n children.push(buildGroupNode(top.id));\n }\n\n for (const node of graph.nodes) {\n if (assignedNodes.has(node.id)) continue;\n const m = measureMap.get(node.id);\n if (!m) continue;\n children.push(buildLeaf(node.id, m));\n }\n\n const sourceRef = (edge: GraphEdge): string =>\n portAssignment.edgeSourcePort.get(edge.id) ?? edge.from;\n\n const targetRef = (edge: GraphEdge): string =>\n portAssignment.edgeTargetPort.get(edge.id) ?? edge.to;\n\n const edges = graph.edges.map((e) => ({\n id: e.id,\n sources: [sourceRef(e)],\n targets: [targetRef(e)],\n layoutOptions: elkPriorityOptionsForEdge(e),\n }));\n\n return {\n id: \"root\",\n layoutOptions: rootLayoutOptions,\n children,\n edges,\n };\n}\n","/** Shared elk engine — elkjs today (elk-rs drop-in when published). */\nimport ELK from \"elkjs/lib/elk.bundled.js\";\n\nexport type ElkPoint = { x: number; y: number };\n\nexport type ElkLabel = {\n id?: string;\n text: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n layoutOptions?: Record<string, string>;\n};\n\nexport type ElkEdgeSection = {\n id?: string;\n startPoint: ElkPoint;\n endPoint: ElkPoint;\n bendPoints?: ElkPoint[];\n};\n\nexport type ElkPort = {\n id: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n layoutOptions?: Record<string, string>;\n};\n\nexport type ElkEdge = {\n id: string;\n sources: string[];\n targets: string[];\n sections?: ElkEdgeSection[];\n labels?: ElkLabel[];\n layoutOptions?: Record<string, string>;\n};\n\nexport type ElkNode = {\n id: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n children?: ElkNode[];\n edges?: ElkEdge[];\n ports?: ElkPort[];\n labels?: ElkLabel[];\n layoutOptions?: Record<string, string>;\n};\n\nexport type ElkGraph = ElkNode;\n\ntype ElkConstructor = new (options?: { defaultLayoutOptions?: Record<string, string> }) => {\n layout: (graph: ElkGraph) => Promise<ElkGraph>;\n};\n\nconst ElkCtor = ELK as unknown as ElkConstructor;\n\nlet shared: InstanceType<ElkConstructor> | null = null;\n\nexport function getElk(): InstanceType<ElkConstructor> {\n if (!shared) {\n shared = new ElkCtor({\n defaultLayoutOptions: {\n \"elk.algorithm\": \"layered\",\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n \"elk.hierarchyHandling\": \"INCLUDE_CHILDREN\",\n },\n });\n }\n return shared;\n}\n\nexport const ELK_LAYOUT_ALGORITHM = \"elk-layered-v1\";\nexport const ELK_ROUTER_ALGORITHM = \"elk-orthogonal-v1\";\n","/**\n * Snap ELK edge endpoints onto ShapeGeometry perimeters.\n *\n * ELK routes to FIXED_POS pins (one out-port and one in-port per edge) derived\n * from ShapeGeometry.getPortPosition. This pass is the authoritative visual\n * attach: first/last points move onto the silhouette along an orthogonal stub\n * so corridors stay rectilinear and fan-in/out lateral offsets are preserved.\n *\n * ERD column-qualified edges are left alone — `snapErdEdgeEndpoints` owns those.\n */\n\nimport type { GraphModel, Point, Vec2 } from \"@kekonic/diagrams-core\";\nimport { attachPointOnPerimeter } from \"@kekonic/diagrams-geometry\";\nimport type { LaidOutNode, LayoutEdgePath } from \"./types.ts\";\n\nconst EPS = 0.75;\n\nfunction toward(from: Point, to: Point): Vec2 {\n return { x: to.x - from.x, y: to.y - from.y };\n}\n\nfunction centerOf(bounds: { x: number; y: number; width: number; height: number }): Point {\n return { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 };\n}\n\n/** Prefer the dominant axis so attach rays stay H/V even when ELK left a diagonal stub. */\nfunction orthoDirection(v: Vec2): Vec2 {\n if (Math.abs(v.x) >= Math.abs(v.y)) return { x: Math.sign(v.x) || 1, y: 0 };\n return { x: 0, y: Math.sign(v.y) || 1 };\n}\n\nfunction axisAligned(a: Point, b: Point): boolean {\n return Math.abs(a.x - b.x) < EPS || Math.abs(a.y - b.y) < EPS;\n}\n\nfunction applyOrthoAttach(points: Point[], endIndex: number, hit: Point, direction: Vec2): void {\n const inward = endIndex === 0 ? 1 : endIndex - 1;\n const anchor = points[inward]!;\n if (axisAligned(anchor, hit)) {\n points[endIndex] = hit;\n return;\n }\n // Ray missed the silhouette column/row — bridge with one orthogonal corner.\n const corner =\n Math.abs(direction.y) >= Math.abs(direction.x)\n ? { x: anchor.x, y: hit.y }\n : { x: hit.x, y: anchor.y };\n points[endIndex] = hit;\n if (endIndex === 0) points.splice(1, 0, corner);\n else points.splice(endIndex, 0, corner);\n}\n\n/** Aim at the nearest facing side of the bounds so we do not flip H/V on shallow diagonals. */\nfunction directionOntoBounds(\n origin: Point,\n bounds: { x: number; y: number; width: number; height: number },\n): Vec2 {\n const L = bounds.x;\n const R = bounds.x + bounds.width;\n const T = bounds.y;\n const B = bounds.y + bounds.height;\n const inX = origin.x >= L - EPS && origin.x <= R + EPS;\n const inY = origin.y >= T - EPS && origin.y <= B + EPS;\n if (origin.y < T && inX) return { x: 0, y: 1 };\n if (origin.y > B && inX) return { x: 0, y: -1 };\n if (origin.x < L && inY) return { x: 1, y: 0 };\n if (origin.x > R && inY) return { x: -1, y: 0 };\n return orthoDirection(toward(origin, centerOf(bounds)));\n}\n\n/**\n * Replace path termini with shape-perimeter hits.\n * Attach rays are forced orthogonal; a corner is inserted when needed so the\n * final stub never becomes a diagonal shortcut.\n */\nexport function snapEdgeEndpointsToGeometry(\n graph: GraphModel,\n nodes: LaidOutNode[],\n edgePaths: LayoutEdgePath[],\n): LayoutEdgePath[] {\n const nodeMap = new Map(nodes.map((n) => [n.nodeId, n]));\n const graphNodes = new Map(graph.nodes.map((n) => [n.id, n]));\n\n return edgePaths.map((path) => {\n const edge = graph.edges.find((e) => e.id === path.edgeId);\n if (!edge || path.points.length < 2) return path;\n if (edge.fromColumn || edge.toColumn) return path;\n\n const points = path.points.map((p) => ({ x: p.x, y: p.y }));\n const fromLaid = nodeMap.get(edge.from);\n const toLaid = nodeMap.get(edge.to);\n const fromNode = graphNodes.get(edge.from);\n const toNode = graphNodes.get(edge.to);\n\n if (fromLaid && fromNode) {\n const p1 = points[1]!;\n const direction = directionOntoBounds(p1, fromLaid.bounds);\n const hit = attachPointOnPerimeter({\n shapeId: fromNode.shape,\n bounds: fromLaid.bounds,\n origin: p1,\n direction,\n });\n applyOrthoAttach(points, 0, hit, direction);\n }\n\n if (toLaid && toNode) {\n const prev = points[points.length - 2]!;\n const direction = directionOntoBounds(prev, toLaid.bounds);\n const hit = attachPointOnPerimeter({\n shapeId: toNode.shape,\n bounds: toLaid.bounds,\n origin: prev,\n direction,\n });\n applyOrthoAttach(points, points.length - 1, hit, direction);\n }\n\n return { ...path, points };\n });\n}\n","import type { GraphGroup, RegionAlign, RegionArrange, TrackSpec } from \"@kekonic/diagrams-core\";\nimport type { Rect } from \"@kekonic/diagrams-core\";\nimport { DENSITY_GAP, DEFAULT_GROUP_GAP } from \"./constants.ts\";\n\nexport type RegionCell = {\n groupId: string;\n /** Intrinsic content size before stretch. */\n width: number;\n height: number;\n column?: number | string;\n row?: number | string;\n colSpan?: number;\n rowSpan?: number;\n};\n\nexport type RegionArrangeInput = {\n arrange: RegionArrange;\n align?: RegionAlign;\n gap?: string | number;\n columns?: TrackSpec;\n rows?: TrackSpec;\n cells: RegionCell[];\n /** Origin of the parent content box. */\n origin?: { x: number; y: number };\n};\n\nexport type ArrangedRegion = {\n groupId: string;\n bounds: Rect;\n};\n\nconst GAP_PRESETS: Record<string, number> = {\n compact: DENSITY_GAP.compact,\n normal: DENSITY_GAP.normal,\n spacious: DENSITY_GAP.spacious,\n};\n\nexport function resolveArrangeGap(gap: string | number | undefined): number {\n if (typeof gap === \"number\" && Number.isFinite(gap)) return Math.max(0, gap);\n if (typeof gap === \"string\" && GAP_PRESETS[gap] != null) return GAP_PRESETS[gap]!;\n return DEFAULT_GROUP_GAP;\n}\n\nfunction trackCount(spec: TrackSpec | undefined, fallback: number): number {\n if (typeof spec === \"number\") return Math.max(1, Math.floor(spec));\n if (Array.isArray(spec)) return Math.max(1, spec.length);\n return Math.max(1, fallback);\n}\n\nfunction resolveTrackIndex(\n ref: number | string | undefined,\n spec: TrackSpec | undefined,\n fallbackIndex: number,\n count: number,\n): number {\n if (typeof ref === \"number\" && ref >= 1) {\n return Math.min(count - 1, Math.max(0, Math.floor(ref) - 1));\n }\n if (typeof ref === \"string\" && Array.isArray(spec)) {\n const idx = spec.indexOf(ref);\n if (idx >= 0) return idx;\n }\n return Math.min(count - 1, Math.max(0, fallbackIndex));\n}\n\nfunction alignOffset(align: RegionAlign, free: number): number {\n if (free <= 0) return 0;\n switch (align) {\n case \"end\":\n return free;\n case \"center\":\n return free / 2;\n case \"start\":\n case \"stretch\":\n default:\n return 0;\n }\n}\n\n/**\n * Place sibling region cells into stack / row / grid tracks.\n * Pure geometry — no ELK. Stretch equalizes the cross-axis.\n */\nexport function regionArrange(input: RegionArrangeInput): ArrangedRegion[] {\n const align = input.align ?? \"stretch\";\n const gap = resolveArrangeGap(input.gap);\n const originX = input.origin?.x ?? 0;\n const originY = input.origin?.y ?? 0;\n const cells = input.cells;\n if (cells.length === 0) return [];\n\n if (input.arrange === \"stack\") {\n return arrangeStack(cells, align, gap, originX, originY);\n }\n if (input.arrange === \"row\") {\n return arrangeRow(cells, align, gap, originX, originY);\n }\n return arrangeGrid(input, align, gap, originX, originY);\n}\n\nfunction arrangeStack(\n cells: RegionCell[],\n align: RegionAlign,\n gap: number,\n originX: number,\n originY: number,\n): ArrangedRegion[] {\n const maxW = Math.max(...cells.map((c) => c.width), 0);\n let y = originY;\n const out: ArrangedRegion[] = [];\n for (const cell of cells) {\n const width = align === \"stretch\" ? maxW : cell.width;\n const x = originX + alignOffset(align, maxW - width);\n out.push({\n groupId: cell.groupId,\n bounds: { x, y, width, height: cell.height },\n });\n y += cell.height + gap;\n }\n return out;\n}\n\nfunction arrangeRow(\n cells: RegionCell[],\n align: RegionAlign,\n gap: number,\n originX: number,\n originY: number,\n): ArrangedRegion[] {\n const maxH = Math.max(...cells.map((c) => c.height), 0);\n let x = originX;\n const out: ArrangedRegion[] = [];\n for (const cell of cells) {\n const height = align === \"stretch\" ? maxH : cell.height;\n const y = originY + alignOffset(align, maxH - height);\n out.push({\n groupId: cell.groupId,\n bounds: { x, y, width: cell.width, height },\n });\n x += cell.width + gap;\n }\n return out;\n}\n\nfunction arrangeGrid(\n input: RegionArrangeInput,\n align: RegionAlign,\n gap: number,\n originX: number,\n originY: number,\n): ArrangedRegion[] {\n const cells = input.cells;\n // Auto-flow by source order when column/row omitted.\n let autoCol = 0;\n let autoRow = 0;\n const colCountHint = trackCount(input.columns, 1);\n const placements = cells.map((cell) => {\n const colSpan = Math.max(1, cell.colSpan ?? 1);\n const rowSpan = Math.max(1, cell.rowSpan ?? 1);\n let col = resolveTrackIndex(cell.column, input.columns, autoCol, colCountHint);\n let row = resolveTrackIndex(cell.row, input.rows, autoRow, trackCount(input.rows, 1));\n if (cell.column == null && cell.row == null) {\n col = autoCol;\n row = autoRow;\n autoCol += colSpan;\n if (autoCol >= colCountHint) {\n autoCol = 0;\n autoRow += 1;\n }\n }\n return { cell, col, row, colSpan, rowSpan };\n });\n\n const maxCol = Math.max(colCountHint, ...placements.map((p) => p.col + p.colSpan));\n const maxRow = Math.max(trackCount(input.rows, 1), ...placements.map((p) => p.row + p.rowSpan));\n\n const colWidths = Array.from({ length: maxCol }, () => 0);\n const rowHeights = Array.from({ length: maxRow }, () => 0);\n for (const p of placements) {\n const perCol = p.cell.width / p.colSpan;\n const perRow = p.cell.height / p.rowSpan;\n for (let c = p.col; c < p.col + p.colSpan; c++) {\n colWidths[c] = Math.max(colWidths[c]!, perCol);\n }\n for (let r = p.row; r < p.row + p.rowSpan; r++) {\n rowHeights[r] = Math.max(rowHeights[r]!, perRow);\n }\n }\n\n const colX: number[] = [];\n let x = originX;\n for (let c = 0; c < maxCol; c++) {\n colX.push(x);\n x += colWidths[c]! + (c < maxCol - 1 ? gap : 0);\n }\n const rowY: number[] = [];\n let y = originY;\n for (let r = 0; r < maxRow; r++) {\n rowY.push(y);\n y += rowHeights[r]! + (r < maxRow - 1 ? gap : 0);\n }\n\n return placements.map((p) => {\n let width = 0;\n for (let c = p.col; c < p.col + p.colSpan; c++) {\n width += colWidths[c]!;\n if (c < p.col + p.colSpan - 1) width += gap;\n }\n let height = 0;\n for (let r = p.row; r < p.row + p.rowSpan; r++) {\n height += rowHeights[r]!;\n if (r < p.row + p.rowSpan - 1) height += gap;\n }\n const cellW = align === \"stretch\" ? width : p.cell.width;\n const cellH = align === \"stretch\" ? height : p.cell.height;\n const ox = alignOffset(align, width - cellW);\n const oy = alignOffset(align, height - cellH);\n return {\n groupId: p.cell.groupId,\n bounds: {\n x: colX[p.col]! + ox,\n y: rowY[p.row]! + oy,\n width: cellW,\n height: cellH,\n },\n };\n });\n}\n\n/** True when a group or diagram options request region arrangement. */\nexport function groupHasRegionArrange(group: GraphGroup): boolean {\n return group.arrange === \"stack\" || group.arrange === \"row\" || group.arrange === \"grid\";\n}\n","import type { Point, Rect } from \"@kekonic/diagrams-core\";\n\nconst EPS = 0.5;\n/** Keep corridors off node silhouettes so edges do not run along a face. */\nconst SIDE_STANDOFF = 16;\n\nfunction inflate(b: Rect, pad: number): Rect {\n return {\n x: b.x - pad,\n y: b.y - pad,\n width: b.width + pad * 2,\n height: b.height + pad * 2,\n };\n}\n\nfunction centerOf(b: Rect): Point {\n return { x: b.x + b.width / 2, y: b.y + b.height / 2 };\n}\n\n/** Orthogonal segment vs inflated axis-aligned rect (open interior). */\nexport function segmentHitsRect(a: Point, b: Point, box: Rect): boolean {\n const minX = Math.min(a.x, b.x);\n const maxX = Math.max(a.x, b.x);\n const minY = Math.min(a.y, b.y);\n const maxY = Math.max(a.y, b.y);\n const L = box.x;\n const R = box.x + box.width;\n const T = box.y;\n const B = box.y + box.height;\n\n if (Math.abs(a.x - b.x) < EPS) {\n const x = a.x;\n if (x <= L + EPS || x >= R - EPS) return false;\n return maxY > T + EPS && minY < B - EPS;\n }\n if (Math.abs(a.y - b.y) < EPS) {\n const y = a.y;\n if (y <= T + EPS || y >= B - EPS) return false;\n return maxX > L + EPS && minX < R - EPS;\n }\n return false;\n}\n\nfunction rangesOverlap(a0: number, a1: number, b0: number, b1: number): boolean {\n return Math.min(a0, a1) <= Math.max(b0, b1) && Math.max(a0, a1) >= Math.min(b0, b1);\n}\n\n/**\n * True when an orthogonal segment runs along a box face (parallel hug).\n * Short stubs into an attach face are allowed; long slides along a side are not.\n */\nexport function segmentHugsRect(\n a: Point,\n b: Point,\n box: Rect,\n standoff = SIDE_STANDOFF,\n allowShortStub = false,\n): boolean {\n const minX = Math.min(a.x, b.x);\n const maxX = Math.max(a.x, b.x);\n const minY = Math.min(a.y, b.y);\n const maxY = Math.max(a.y, b.y);\n const L = box.x;\n const R = box.x + box.width;\n const T = box.y;\n const B = box.y + box.height;\n const len = Math.abs(b.x - a.x) + Math.abs(b.y - a.y);\n\n if (Math.abs(a.x - b.x) < EPS) {\n const x = a.x;\n const alongLeft = Math.abs(x - L) <= standoff;\n const alongRight = Math.abs(x - R) <= standoff;\n if (!(alongLeft || alongRight)) return false;\n if (!rangesOverlap(minY, maxY, T, B)) return false;\n if (allowShortStub && len <= standoff * 1.5) return false;\n const overlap = Math.min(maxY, B) - Math.max(minY, T);\n return overlap > standoff * 0.5;\n }\n if (Math.abs(a.y - b.y) < EPS) {\n const y = a.y;\n const alongTop = Math.abs(y - T) <= standoff;\n const alongBottom = Math.abs(y - B) <= standoff;\n if (!(alongTop || alongBottom)) return false;\n if (!rangesOverlap(minX, maxX, L, R)) return false;\n if (allowShortStub && len <= standoff * 1.5) return false;\n const overlap = Math.min(maxX, R) - Math.max(minX, L);\n return overlap > standoff * 0.5;\n }\n return false;\n}\n\nfunction pathLength(points: Point[]): number {\n let len = 0;\n for (let i = 1; i < points.length; i++) {\n const a = points[i - 1]!;\n const b = points[i]!;\n len += Math.abs(b.x - a.x) + Math.abs(b.y - a.y);\n }\n return len;\n}\n\nfunction dedupe(points: Point[]): Point[] {\n const out: Point[] = [];\n for (const p of points) {\n const prev = out[out.length - 1];\n if (prev && Math.abs(prev.x - p.x) < EPS && Math.abs(prev.y - p.y) < EPS) continue;\n out.push(p);\n }\n return out;\n}\n\n/**\n * Collapse colinear bends, but keep the egress/ingress stubs so a later\n * corridor on the same line cannot erase the outward nudge and cut through\n * the source/target box.\n *\n * Final layout polish uses `collapseColinearPoints` in polish-edges.ts (no stub\n * preservation) after endpoints are frozen — different stage, different rule.\n */\nfunction collapseColinear(points: Point[]): Point[] {\n if (points.length < 3) return points;\n const out: Point[] = [points[0]!];\n for (let i = 1; i < points.length - 1; i++) {\n const keepStub = i === 1 || i === points.length - 2;\n if (keepStub) {\n out.push(points[i]!);\n continue;\n }\n const a = out[out.length - 1]!;\n const b = points[i]!;\n const c = points[i + 1]!;\n const vertical = Math.abs(a.x - b.x) < EPS && Math.abs(b.x - c.x) < EPS;\n const horizontal = Math.abs(a.y - b.y) < EPS && Math.abs(b.y - c.y) < EPS;\n if (vertical || horizontal) continue;\n out.push(b);\n }\n out.push(points[points.length - 1]!);\n return dedupe(out);\n}\n\ntype Side = \"N\" | \"S\" | \"E\" | \"W\";\n\nfunction attach(b: Rect, side: Side, t: number): Point {\n const clamped = Math.min(0.85, Math.max(0.15, t));\n switch (side) {\n case \"N\":\n return { x: b.x + b.width * clamped, y: b.y };\n case \"S\":\n return { x: b.x + b.width * clamped, y: b.y + b.height };\n case \"E\":\n return { x: b.x + b.width, y: b.y + b.height * clamped };\n case \"W\":\n return { x: b.x, y: b.y + b.height * clamped };\n }\n}\n\n/** Which face a point sits on (within EPS), if any. */\nfunction sideOfPoint(p: Point, b: Rect): Side | null {\n if (Math.abs(p.y - b.y) < EPS && p.x >= b.x - EPS && p.x <= b.x + b.width + EPS) return \"N\";\n if (Math.abs(p.y - (b.y + b.height)) < EPS && p.x >= b.x - EPS && p.x <= b.x + b.width + EPS) {\n return \"S\";\n }\n if (Math.abs(p.x - (b.x + b.width)) < EPS && p.y >= b.y - EPS && p.y <= b.y + b.height + EPS) {\n return \"E\";\n }\n if (Math.abs(p.x - b.x) < EPS && p.y >= b.y - EPS && p.y <= b.y + b.height + EPS) return \"W\";\n return null;\n}\n\n/**\n * Prefer the geometrically primary faces; heavily punish U-turns that attach on\n * the far side after wrapping under/around the target (common arranged-mode fail).\n */\nfunction facePreferencePenalty(\n from: Rect,\n to: Rect,\n points: Point[],\n preferred: [Side, Side],\n): number {\n const start = sideOfPoint(points[0]!, from);\n const end = sideOfPoint(points[points.length - 1]!, to);\n let penalty = 0;\n if (start && start !== preferred[0]) penalty += 2_400;\n if (end && end !== preferred[1]) penalty += 9_000;\n const [fs, ts] = preferred;\n // Downward flow attaching under the target after a bottom rail looks worst.\n if (fs === \"S\" && ts === \"N\" && end === \"S\") penalty += 18_000;\n if (fs === \"S\" && ts === \"N\" && (end === \"E\" || end === \"W\")) penalty += 12_000;\n if (fs === \"N\" && ts === \"S\" && end === \"N\") penalty += 18_000;\n if (fs === \"E\" && ts === \"W\" && end === \"E\") penalty += 18_000;\n if (fs === \"W\" && ts === \"E\" && end === \"W\") penalty += 18_000;\n return penalty;\n}\n\n/** Point outside the attach face — corridors route through here, not on the silhouette. */\nfunction egress(b: Rect, side: Side, t: number, standoff: number): Point {\n const p = attach(b, side, t);\n switch (side) {\n case \"E\":\n return { x: p.x + standoff, y: p.y };\n case \"W\":\n return { x: p.x - standoff, y: p.y };\n case \"S\":\n return { x: p.x, y: p.y + standoff };\n case \"N\":\n return { x: p.x, y: p.y - standoff };\n }\n}\n\nfunction sidePairs(from: Rect, to: Rect): Array<[Side, Side]> {\n const primary = preferredSidePair(from, to);\n const eastWest = to.x - (from.x + from.width);\n const westEast = from.x - (to.x + to.width);\n const southNorth = to.y - (from.y + from.height);\n const northSouth = from.y - (to.y + to.height);\n const secondary: [Side, Side] =\n primary[0] === \"E\" || primary[0] === \"W\"\n ? southNorth >= northSouth\n ? [\"S\", \"N\"]\n : [\"N\", \"S\"]\n : eastWest >= westEast\n ? [\"E\", \"W\"]\n : [\"W\", \"E\"];\n return [primary, secondary, [\"E\", \"W\"], [\"W\", \"E\"], [\"S\", \"N\"], [\"N\", \"S\"]];\n}\n\n/** Primary attach faces — shared with arranged fan-slot grouping. */\nexport function preferredSidePair(from: Rect, to: Rect): [Side, Side] {\n const eastWest = to.x - (from.x + from.width);\n const westEast = from.x - (to.x + to.width);\n const southNorth = to.y - (from.y + from.height);\n const northSouth = from.y - (to.y + to.height);\n const hClear = Math.max(eastWest, westEast);\n const vClear = Math.max(southNorth, northSouth);\n const separatedH = hClear > 8;\n const separatedV = vClear > 8;\n\n if (separatedH && (!separatedV || hClear >= vClear * 0.35 || hClear > 48)) {\n // Clear lateral gutter (column layouts) — prefer E/W even when |dy| is larger,\n // otherwise routes climb the mid column and escape around the whole platform.\n return eastWest >= westEast ? [\"E\", \"W\"] : [\"W\", \"E\"];\n }\n if (separatedV) {\n return southNorth >= northSouth ? [\"S\", \"N\"] : [\"N\", \"S\"];\n }\n const fc = centerOf(from);\n const tc = centerOf(to);\n const dx = tc.x - fc.x;\n const dy = tc.y - fc.y;\n return Math.abs(dx) >= Math.abs(dy)\n ? dx >= 0\n ? [\"E\", \"W\"]\n : [\"W\", \"E\"]\n : dy >= 0\n ? [\"S\", \"N\"]\n : [\"N\", \"S\"];\n}\n\n/** Clearance between facing sides; null when the pair does not face. */\nfunction facingClearance(from: Rect, to: Rect, fs: Side, ts: Side): number | null {\n if (fs === \"S\" && ts === \"N\") return to.y - (from.y + from.height);\n if (fs === \"N\" && ts === \"S\") return from.y - (to.y + to.height);\n if (fs === \"E\" && ts === \"W\") return to.x - (from.x + from.width);\n if (fs === \"W\" && ts === \"E\") return from.x - (to.x + to.width);\n return null;\n}\n\n/** True when the boxes overlap on the axis orthogonal to the facing sides. */\nfunction facesOverlap(from: Rect, to: Rect, fs: Side): boolean {\n if (fs === \"S\" || fs === \"N\") {\n return rangesOverlap(from.x, from.x + from.width, to.x, to.x + to.width);\n }\n return rangesOverlap(from.y, from.y + from.height, to.y, to.y + to.height);\n}\n\n/**\n * Pack/stack cells leave ~16px gaps, but the default egress turn is ~36px.\n * When neighbors face across a tight clear gap, route in the interstitial\n * channel instead of overshooting into the target and escaping around the hull.\n */\nfunction tryTightNeighborRoute(\n from: Rect,\n to: Rect,\n obstacles: Rect[],\n pad: number,\n tFrom: number,\n tTo: number,\n turn: number,\n): Point[] | null {\n const [fs, ts] = sidePairs(from, to)[0]!;\n const gap = facingClearance(from, to, fs, ts);\n if (gap == null || gap <= 0 || gap >= turn * 2) return null;\n if (!facesOverlap(from, to, fs)) return null;\n\n const aAttach = attach(from, fs, tFrom);\n const bAttach = attach(to, ts, tTo);\n const half = gap / 2;\n let mid: Point[];\n if (fs === \"S\" || fs === \"N\") {\n const y = fs === \"S\" ? from.y + from.height + half : from.y - half;\n mid = [\n { x: aAttach.x, y },\n { x: bAttach.x, y },\n ];\n } else {\n const x = fs === \"E\" ? from.x + from.width + half : from.x - half;\n mid = [\n { x, y: aAttach.y },\n { x, y: bAttach.y },\n ];\n }\n\n const points = collapseColinear(dedupe([aAttach, ...mid, bAttach]));\n // Keep obstacle padding inside the gap so a clear pack channel stays usable.\n const channelPad = Math.min(pad, Math.max(0, gap / 4 - 1));\n const inflated = obstacles.map((b) => inflate(b, channelPad));\n if (countHits(points, inflated, [from, to]) > 0) return null;\n return points;\n}\n\nfunction turnForPair(baseTurn: number, gap: number | null): number {\n if (gap == null || gap <= 0) return baseTurn;\n // Stay inside the facing channel; leave a little slack so stubs do not meet.\n return Math.min(baseTurn, Math.max(2, gap / 2 - 1));\n}\n\nfunction hvPath(a: Point, b: Point): Point[] {\n if (Math.abs(a.y - b.y) < EPS || Math.abs(a.x - b.x) < EPS) return [a, b];\n return [a, { x: b.x, y: a.y }, b];\n}\n\nfunction vhPath(a: Point, b: Point): Point[] {\n if (Math.abs(a.y - b.y) < EPS || Math.abs(a.x - b.x) < EPS) return [a, b];\n return [a, { x: a.x, y: b.y }, b];\n}\n\nfunction unionBounds(rects: Rect[]): Rect | null {\n if (rects.length === 0) return null;\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (const b of rects) {\n minX = Math.min(minX, b.x);\n minY = Math.min(minY, b.y);\n maxX = Math.max(maxX, b.x + b.width);\n maxY = Math.max(maxY, b.y + b.height);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Rectilinear route between two node boxes that prefers corridors clear of\n * other node footprints. Candidate channels only (not a grid/A* router).\n */\nexport function routeOrthogonalAvoiding(\n from: Rect,\n to: Rect,\n obstacles: Rect[],\n pad: number,\n tFrom = 0.5,\n tTo = 0.5,\n): Point[] {\n const pads = [pad, Math.min(pad, 12), 6, 2].filter((p, i, arr) => arr.indexOf(p) === i);\n let fallback: Point[] | null = null;\n for (const tryPad of pads) {\n const result = routeWithPad(from, to, obstacles, tryPad, tFrom, tTo);\n if (result.clear) return result.points;\n fallback ??= result.points;\n }\n return fallback ?? [centerOf(from), centerOf(to)];\n}\n\ntype Cand = { raw: Point[]; rank: number };\n\nfunction routeWithPad(\n from: Rect,\n to: Rect,\n obstacles: Rect[],\n pad: number,\n tFrom: number,\n tTo: number,\n): { points: Point[]; clear: boolean } {\n const standoff = Math.max(SIDE_STANDOFF, pad);\n // Turn farther out than the attach stub so first corridors do not hug the face.\n const turn = Math.max(standoff * 2.25, pad + 14);\n const tight = tryTightNeighborRoute(from, to, obstacles, pad, tFrom, tTo, turn);\n if (tight) return { points: tight, clear: true };\n\n const hugReach = Math.max(SIDE_STANDOFF, turn * 0.75);\n const inflated = obstacles.map((b) => inflate(b, pad));\n const endpointBoxes = [from, to];\n const candidates: Cand[] = [];\n const pairs = sidePairs(from, to);\n const preferred = pairs[0]!;\n\n for (let rank = 0; rank < pairs.length; rank++) {\n const [fs, ts] = pairs[rank]!;\n const pairTurn = turnForPair(turn, facingClearance(from, to, fs, ts));\n const aAttach = attach(from, fs, tFrom);\n const bAttach = attach(to, ts, tTo);\n const a = egress(from, fs, tFrom, pairTurn);\n const b = egress(to, ts, tTo, pairTurn);\n\n for (const mid of [hvPath(a, b), vhPath(a, b)]) {\n candidates.push({ raw: [aAttach, ...mid, bAttach], rank });\n }\n\n const midX = (a.x + b.x) / 2;\n const midY = (a.y + b.y) / 2;\n candidates.push({\n raw: [aAttach, a, { x: midX, y: a.y }, { x: midX, y: b.y }, b, bAttach],\n rank,\n });\n candidates.push({\n raw: [aAttach, a, { x: a.x, y: midY }, { x: b.x, y: midY }, b, bAttach],\n rank,\n });\n }\n\n // When a pack sibling sits in the facing gutter, hull rails tour the whole local\n // AABB. Prefer short lanes just above/below the blockers in that channel.\n pushFacingChannelDetours(candidates, from, to, inflated, pad, tFrom, tTo, preferred);\n\n // Local hull only — wrapping the whole diagram makes \"outside\" rails cut through\n // other arrange bands. Endpoint boxes are included so rails clear both faces.\n const local = localObstacles(from, to, inflated);\n const hull = unionBounds([...local, inflate(from, pad), inflate(to, pad)]);\n if (hull) {\n const clear = Math.max(pad, turn);\n const left = hull.x - clear;\n const right = hull.x + hull.width + clear;\n const top = hull.y - clear;\n const bottom = hull.y + hull.height + clear;\n // Prefer rails that land on the geometrically preferred entry face.\n const entrySides: Side[] = [\n preferred[1],\n ...([\"N\", \"S\", \"E\", \"W\"] as Side[]).filter((s) => s !== preferred[1]),\n ];\n for (const ts of entrySides) {\n const bAttach = attach(to, ts, tTo);\n const railRank = ts === preferred[1] ? 2 : 5;\n pushRailEscapes(\n candidates,\n from,\n tFrom,\n turn,\n pad,\n left,\n right,\n top,\n bottom,\n bAttach,\n railRank,\n );\n }\n }\n\n let bestClear: Point[] | null = null;\n let bestClearScore = Infinity;\n let bestAny: Point[] = candidates[0]?.raw ?? [centerOf(from), centerOf(to)];\n let bestAnyScore = Infinity;\n\n for (const cand of candidates) {\n const points = collapseColinear(dedupe(cand.raw));\n if (points.length < 2) continue;\n const len = pathLength(points);\n const hits = countHits(points, inflated, endpointBoxes);\n // Strong hug reach on endpoints (no self-silhouette slides); lighter on obstacles\n // so narrow interstitial channels between stacked cards stay usable.\n const hugs =\n countHugs(points, endpointBoxes, hugReach) + countHugs(points, obstacles, SIDE_STANDOFF);\n const facePenalty = facePreferencePenalty(from, to, points, preferred);\n // Hits must dominate: in a dense pack every detour lightly hugs something, and a\n // short through-node path used to beat a clear perimeter route on hug+length alone.\n const score = hits * 100_000 + hugs * 140 + cand.rank * 320 + facePenalty + len;\n if (score < bestAnyScore) {\n bestAnyScore = score;\n bestAny = points;\n }\n // Accept clear paths even with light hugs — hugs only rank among hit-free routes.\n if (hits === 0 && score < bestClearScore) {\n bestClearScore = score;\n bestClear = points;\n }\n }\n\n return { points: bestClear ?? bestAny, clear: bestClear != null };\n}\n\n/**\n * Short detours that skim above/below (or beside) blockers in the facing\n * channel — avoids full-hull perimeter tours when only a pack sibling blocks.\n */\nfunction pushFacingChannelDetours(\n candidates: Cand[],\n from: Rect,\n to: Rect,\n inflated: Rect[],\n pad: number,\n tFrom: number,\n tTo: number,\n preferred: [Side, Side],\n): void {\n const [fs, ts] = preferred;\n const clear = Math.max(pad, SIDE_STANDOFF);\n const bAttach = attach(to, ts, tTo);\n const b = egress(to, ts, tTo, clear);\n\n if ((fs === \"E\" && ts === \"W\") || (fs === \"W\" && ts === \"E\")) {\n const x0 = fs === \"E\" ? from.x + from.width : to.x + to.width;\n const x1 = fs === \"E\" ? to.x : from.x;\n if (x1 <= x0 + 1) return;\n // Only same-row (or target-row) siblings in the gutter — not cards that merely\n // sit in the vertical span between offset endpoints (those inflate topLane\n // to the far side of the column and recreate perimeter tours).\n const blockers = inflated.filter(\n (box) =>\n box.x + box.width > x0 - 1 &&\n box.x < x1 - 1 &&\n (rangesOverlap(box.y, box.y + box.height, from.y, from.y + from.height) ||\n rangesOverlap(box.y, box.y + box.height, to.y, to.y + to.height)),\n );\n if (blockers.length === 0) return;\n const topLane = Math.min(...blockers.map((box) => box.y)) - clear;\n const bottomLane = Math.max(...blockers.map((box) => box.y + box.height)) + clear;\n const aN = attach(from, \"N\", tFrom);\n const aS = attach(from, \"S\", tFrom);\n candidates.push({\n raw: [aN, { x: aN.x, y: topLane }, { x: b.x, y: topLane }, b, bAttach],\n rank: 1,\n });\n candidates.push({\n raw: [aS, { x: aS.x, y: bottomLane }, { x: b.x, y: bottomLane }, b, bAttach],\n rank: 1,\n });\n // Preferred-face exit with a jog into the free lane (when the stub is clear).\n const aF = attach(from, fs, tFrom);\n const jogX =\n fs === \"E\" ? Math.min(aF.x + clear, (x0 + x1) / 2) : Math.max(aF.x - clear, (x0 + x1) / 2);\n candidates.push({\n raw: [aF, { x: jogX, y: aF.y }, { x: jogX, y: topLane }, { x: b.x, y: topLane }, b, bAttach],\n rank: 0,\n });\n candidates.push({\n raw: [\n aF,\n { x: jogX, y: aF.y },\n { x: jogX, y: bottomLane },\n { x: b.x, y: bottomLane },\n b,\n bAttach,\n ],\n rank: 0,\n });\n return;\n }\n\n if ((fs === \"S\" && ts === \"N\") || (fs === \"N\" && ts === \"S\")) {\n const y0 = fs === \"S\" ? from.y + from.height : to.y + to.height;\n const y1 = fs === \"S\" ? to.y : from.y;\n if (y1 <= y0 + 1) return;\n const blockers = inflated.filter(\n (box) =>\n box.y + box.height > y0 - 1 &&\n box.y < y1 - 1 &&\n (rangesOverlap(box.x, box.x + box.width, from.x, from.x + from.width) ||\n rangesOverlap(box.x, box.x + box.width, to.x, to.x + to.width)),\n );\n if (blockers.length === 0) return;\n const leftLane = Math.min(...blockers.map((box) => box.x)) - clear;\n const rightLane = Math.max(...blockers.map((box) => box.x + box.width)) + clear;\n const aW = attach(from, \"W\", tFrom);\n const aE = attach(from, \"E\", tFrom);\n candidates.push({\n raw: [aW, { x: leftLane, y: aW.y }, { x: leftLane, y: b.y }, b, bAttach],\n rank: 1,\n });\n candidates.push({\n raw: [aE, { x: rightLane, y: aE.y }, { x: rightLane, y: b.y }, b, bAttach],\n rank: 1,\n });\n }\n}\n\n/**\n * Obstacles near the endpoints — generous AABB so pack siblings beside the\n * straight span still shape the local hull (and its outside rails).\n */\nfunction localObstacles(from: Rect, to: Rect, inflated: Rect[], margin = 160): Rect[] {\n const x0 = Math.min(from.x, to.x) - margin;\n const y0 = Math.min(from.y, to.y) - margin;\n const x1 = Math.max(from.x + from.width, to.x + to.width) + margin;\n const y1 = Math.max(from.y + from.height, to.y + to.height) + margin;\n return inflated.filter(\n (box) => !(box.x + box.width < x0 || box.x > x1 || box.y + box.height < y0 || box.y > y1),\n );\n}\n\n/** Ortho routes that ride the outside of a local hull without mid-pack cuts. */\nfunction pushRailEscapes(\n candidates: Cand[],\n from: Rect,\n tFrom: number,\n turn: number,\n pad: number,\n left: number,\n right: number,\n top: number,\n bottom: number,\n bAttach: Point,\n rank = 3,\n): void {\n const aN = attach(from, \"N\", tFrom);\n const aS = attach(from, \"S\", tFrom);\n const aE = attach(from, \"E\", tFrom);\n const aW = attach(from, \"W\", tFrom);\n const nTurn = Math.min(turn, Math.max(pad, aN.y - top));\n const sTurn = Math.min(turn, Math.max(pad, bottom - aS.y));\n const eTurn = Math.min(turn, Math.max(pad, right - aE.x));\n const wTurn = Math.min(turn, Math.max(pad, aW.x - left));\n const n = egress(from, \"N\", tFrom, nTurn);\n const s = egress(from, \"S\", tFrom, sTurn);\n const e = egress(from, \"E\", tFrom, eTurn);\n const w = egress(from, \"W\", tFrom, wTurn);\n\n // East → right rail → top/bottom → target\n candidates.push({\n raw: [aE, e, { x: right, y: e.y }, { x: right, y: top }, { x: bAttach.x, y: top }, bAttach],\n rank,\n });\n candidates.push({\n raw: [\n aE,\n e,\n { x: right, y: e.y },\n { x: right, y: bottom },\n { x: bAttach.x, y: bottom },\n bAttach,\n ],\n rank: rank + 1,\n });\n // West → left rail → top/bottom → target\n candidates.push({\n raw: [aW, w, { x: left, y: w.y }, { x: left, y: top }, { x: bAttach.x, y: top }, bAttach],\n rank,\n });\n candidates.push({\n raw: [aW, w, { x: left, y: w.y }, { x: left, y: bottom }, { x: bAttach.x, y: bottom }, bAttach],\n rank: rank + 1,\n });\n // North → top rail → left/right corner → target (avoids dropping through the pack)\n candidates.push({\n raw: [aN, n, { x: n.x, y: top }, { x: left, y: top }, { x: left, y: bAttach.y }, bAttach],\n rank,\n });\n candidates.push({\n raw: [aN, n, { x: n.x, y: top }, { x: right, y: top }, { x: right, y: bAttach.y }, bAttach],\n rank,\n });\n candidates.push({\n raw: [aN, n, { x: n.x, y: top }, { x: bAttach.x, y: top }, bAttach],\n rank: rank + 1,\n });\n // South → bottom rail → left/right corner → target\n candidates.push({\n raw: [aS, s, { x: s.x, y: bottom }, { x: left, y: bottom }, { x: left, y: bAttach.y }, bAttach],\n rank,\n });\n candidates.push({\n raw: [\n aS,\n s,\n { x: s.x, y: bottom },\n { x: right, y: bottom },\n { x: right, y: bAttach.y },\n bAttach,\n ],\n rank,\n });\n candidates.push({\n raw: [aS, s, { x: s.x, y: bottom }, { x: bAttach.x, y: bottom }, bAttach],\n rank: rank + 1,\n });\n}\n\nfunction countHits(points: Point[], obstacles: Rect[], endpoints: Rect[]): number {\n let n = 0;\n for (let i = 0; i < points.length - 1; i++) {\n const isStub = i === 0 || i === points.length - 2;\n for (const box of obstacles) {\n if (segmentHitsRect(points[i]!, points[i + 1]!, box)) n += 1;\n }\n // Mid segments must not cut through source/target interiors.\n if (!isStub) {\n for (const box of endpoints) {\n if (segmentHitsRect(points[i]!, points[i + 1]!, box)) n += 1;\n }\n }\n }\n return n;\n}\n\nfunction countHugs(points: Point[], boxes: Rect[], reach: number): number {\n let n = 0;\n for (let i = 0; i < points.length - 1; i++) {\n const isStub = i === 0 || i === points.length - 2;\n for (const box of boxes) {\n if (segmentHugsRect(points[i]!, points[i + 1]!, box, reach, isStub)) n += 1;\n }\n }\n return n;\n}\n","import type {\n GraphGroup,\n GraphModel,\n LayoutOptions,\n Rect,\n RegionArrange,\n} from \"@kekonic/diagrams-core\";\nimport type { MeasuredNode } from \"../../measure/measure.ts\";\nimport { LAYOUT_MARGIN } from \"../constants.ts\";\nimport { measureGroupLabelBox, paddingForGroup } from \"../group-bounds.ts\";\nimport type {\n LaidOutGroup,\n LaidOutNode,\n LayoutEdgeLabel,\n LayoutEdgePath,\n LayoutResult,\n} from \"../types.ts\";\nimport {\n groupHasRegionArrange,\n regionArrange,\n resolveArrangeGap,\n type RegionCell,\n} from \"../region-arrange.ts\";\nimport { preferredSidePair, routeOrthogonalAvoiding } from \"../route-orthogonal-avoid.ts\";\nimport { buildElkGraph } from \"./build-elk-graph.ts\";\nimport { snapEdgeEndpointsToGeometry } from \"../attach-endpoints.ts\";\nimport {\n collapseColinearPoints,\n ensureOrthogonalPoints,\n MIN_EDGE_NODE_CLEARANCE,\n} from \"./polish-edges.ts\";\nimport {\n ELK_LAYOUT_ALGORITHM,\n ELK_ROUTER_ALGORITHM,\n getElk,\n type ElkEdge,\n type ElkGraph,\n type ElkNode,\n} from \"./elk-engine.ts\";\n\n/** Inside a row of columns, pack top→bottom; inside stacked bands, pack left→right. */\nfunction cellFlowDirection(parentArrange: RegionArrange): NonNullable<LayoutOptions[\"direction\"]> {\n if (parentArrange === \"row\") return \"TD\";\n if (parentArrange === \"stack\") return \"LR\";\n return \"TD\";\n}\n\nexport type ArrangedLayoutResult = {\n layout: LayoutResult;\n edges: LayoutEdgePath[];\n routerAlgorithm: string;\n};\n\nconst NODE_CELL_PREFIX = \"__node__:\";\n\n/** Fallback leaf gap when no authored `gap` — roomier than the old hard-coded 16px. */\nfunction defaultLeafGap(density?: LayoutOptions[\"density\"]): number {\n switch (density) {\n case \"compact\":\n return 20;\n case \"spacious\":\n return 40;\n case \"normal\":\n default:\n return 28;\n }\n}\n\nfunction resolveLeafGap(gap: string | number | undefined, options: LayoutOptions): number {\n const scale = options.spacingScale ?? 1;\n const base = gap != null ? resolveArrangeGap(gap) : defaultLeafGap(options.density);\n return Math.max(0, Math.round(base * scale));\n}\n\nfunction resolveTrackGap(gap: string | number | undefined, options: LayoutOptions): number {\n const scale = options.spacingScale ?? 1;\n return Math.max(0, Math.round(resolveArrangeGap(gap) * scale));\n}\n\nfunction nodeCellId(nodeId: string): string {\n return `${NODE_CELL_PREFIX}${nodeId}`;\n}\n\nfunction parseNodeCellId(cellId: string): string | null {\n return cellId.startsWith(NODE_CELL_PREFIX) ? cellId.slice(NODE_CELL_PREFIX.length) : null;\n}\n\n/** Pack wrap width — wider densities keep more siblings on one row. */\nfunction packMaxRowWidth(density?: LayoutOptions[\"density\"]): number {\n switch (density) {\n case \"compact\":\n return 420;\n case \"spacious\":\n return 720;\n case \"normal\":\n default:\n return 560;\n }\n}\n\nexport function needsRegionArrange(graph: GraphModel, options: LayoutOptions): boolean {\n if (options.arrange === \"stack\" || options.arrange === \"row\" || options.arrange === \"grid\") {\n return true;\n }\n return graph.groups.some((g) => groupHasRegionArrange(g));\n}\n\nfunction ranksFromFixed(\n nodes: LaidOutNode[],\n direction: LayoutOptions[\"direction\"],\n): LaidOutNode[] {\n const dir = direction ?? \"LR\";\n const horizontal = dir === \"LR\" || dir === \"RL\";\n const sorted = [...nodes].sort((a, b) => {\n const aPrimary = horizontal ? a.bounds.x : a.bounds.y;\n const bPrimary = horizontal ? b.bounds.x : b.bounds.y;\n if (aPrimary !== bPrimary) return aPrimary - bPrimary;\n return (horizontal ? a.bounds.y : a.bounds.x) - (horizontal ? b.bounds.y : b.bounds.x);\n });\n const rankOf = new Map<string, number>();\n let rank = 0;\n let lastPrimary = Number.NEGATIVE_INFINITY;\n for (const n of sorted) {\n const primary = horizontal ? n.bounds.x : n.bounds.y;\n if (primary - lastPrimary > 8) {\n if (lastPrimary !== Number.NEGATIVE_INFINITY) rank += 1;\n lastPrimary = primary;\n }\n rankOf.set(n.nodeId, rank);\n }\n const orderInRank = new Map<number, number>();\n return sorted.map((n) => {\n const r = rankOf.get(n.nodeId) ?? 0;\n const order = orderInRank.get(r) ?? 0;\n orderInRank.set(r, order + 1);\n return { ...n, rank: r, order };\n });\n}\n\nfunction packNodes(\n nodeIds: string[],\n measureMap: Map<string, MeasuredNode>,\n mode: \"pack\" | \"stack\",\n density?: LayoutOptions[\"density\"],\n gapPx = 28,\n): Map<string, Rect> {\n const out = new Map<string, Rect>();\n let x = 0;\n let y = 0;\n let rowH = 0;\n const maxRowW = packMaxRowWidth(density);\n const gap = Math.max(0, gapPx);\n const rows: string[][] = [];\n let row: string[] = [];\n for (const id of nodeIds) {\n const m = measureMap.get(id);\n if (!m) continue;\n if (mode === \"stack\") {\n // Center narrower nodes on the column axis for a tidier band/column.\n out.set(id, { x: 0, y, width: m.width, height: m.height });\n y += m.height + gap;\n continue;\n }\n if (x > 0 && x + m.width > maxRowW) {\n rows.push(row);\n row = [];\n x = 0;\n y += rowH + gap;\n rowH = 0;\n }\n out.set(id, { x, y, width: m.width, height: m.height });\n row.push(id);\n x += m.width + gap;\n rowH = Math.max(rowH, m.height);\n }\n if (row.length) rows.push(row);\n\n if (mode === \"stack\" && out.size > 1) {\n const maxW = Math.max(...[...out.values()].map((b) => b.width));\n for (const [id, b] of out) {\n out.set(id, { ...b, x: (maxW - b.width) / 2 });\n }\n } else if (mode === \"pack\" && rows.length > 0) {\n // Column-aligned grid: equalize column widths across wrapped rows and\n // top-align within each cell so mixed glyphs (person, hexagon, cloud)\n // share a clean top edge instead of floating mid-row.\n const colCount = Math.max(...rows.map((r) => r.length), 0);\n const colW = Array.from({ length: colCount }, () => 0);\n const rowHeights = Array.from({ length: rows.length }, () => 0);\n for (let r = 0; r < rows.length; r++) {\n const ids = rows[r]!;\n for (let c = 0; c < ids.length; c++) {\n const b = out.get(ids[c]!)!;\n colW[c] = Math.max(colW[c]!, b.width);\n rowHeights[r] = Math.max(rowHeights[r]!, b.height);\n }\n }\n let gy = 0;\n for (let r = 0; r < rows.length; r++) {\n const ids = rows[r]!;\n let gx = 0;\n for (let c = 0; c < ids.length; c++) {\n const id = ids[c]!;\n const b = out.get(id)!;\n out.set(id, { x: gx, y: gy, width: b.width, height: b.height });\n gx += colW[c]! + gap;\n }\n gy += rowHeights[r]! + gap;\n }\n }\n return out;\n}\n\nfunction aabbOf(rects: Iterable<Rect>): Rect | null {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n let any = false;\n for (const b of rects) {\n any = true;\n minX = Math.min(minX, b.x);\n minY = Math.min(minY, b.y);\n maxX = Math.max(maxX, b.x + b.width);\n maxY = Math.max(maxY, b.y + b.height);\n }\n if (!any) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nfunction offsetRects(rects: Map<string, Rect>, dx: number, dy: number): void {\n for (const [id, b] of rects) {\n rects.set(id, { ...b, x: b.x + dx, y: b.y + dy });\n }\n}\n\n/**\n * Local ELK for nodes inside a group (and edges wholly inside it).\n * Returns node bounds relative to (0,0) content origin (no group padding).\n */\nasync function layoutCellFlow(\n graph: GraphModel,\n group: GraphGroup,\n measured: MeasuredNode[],\n options: LayoutOptions,\n flowDirection: NonNullable<LayoutOptions[\"direction\"]>,\n): Promise<Map<string, Rect>> {\n const nodeIds = new Set(collectDescendantNodeIds(graph, group.id));\n if (nodeIds.size === 0) return new Map();\n\n const subGraph: GraphModel = {\n ...graph,\n nodes: graph.nodes.filter((n) => nodeIds.has(n.id)),\n edges: graph.edges.filter((e) => nodeIds.has(e.from) && nodeIds.has(e.to)),\n groups: [],\n };\n const subMeasured = measured.filter((m) => nodeIds.has(m.nodeId));\n if (subMeasured.length === 0) return new Map();\n\n // Disconnected members: ELK often stacks components against the flow axis.\n // Pack along the cell direction instead (row cells → vertical, stack cells → horizontal).\n if (subGraph.edges.length === 0) {\n const ids = subMeasured.map((m) => m.nodeId);\n const measureMap = new Map(measured.map((m) => [m.nodeId, m]));\n const mode = flowDirection === \"TD\" || flowDirection === \"BT\" ? \"stack\" : \"pack\";\n return packNodes(ids, measureMap, mode, options.density, resolveLeafGap(undefined, options));\n }\n\n const elkGraph = buildElkGraph(subGraph, subMeasured, {\n ...options,\n direction: flowDirection,\n groupLayout: \"flat\",\n });\n const laid = await getElk().layout(elkGraph);\n const out = new Map<string, Rect>();\n for (const child of laid.children ?? []) {\n if (!nodeIds.has(child.id)) continue;\n out.set(child.id, {\n x: child.x ?? 0,\n y: child.y ?? 0,\n width: child.width ?? 0,\n height: child.height ?? 0,\n });\n }\n // Normalize to content origin\n const box = aabbOf(out.values());\n if (box && (box.x !== 0 || box.y !== 0)) {\n offsetRects(out, -box.x, -box.y);\n }\n return out;\n}\n\n/** Center (or start/end) content inside a stretched slot's padded inner box. */\nfunction contentOriginInSlot(\n slot: Rect,\n pad: { top: number; right: number; bottom: number; left: number },\n contentBox: Rect,\n align: NonNullable<LayoutOptions[\"align\"]>,\n): { x: number; y: number } {\n const innerW = Math.max(0, slot.width - pad.left - pad.right);\n const innerH = Math.max(0, slot.height - pad.top - pad.bottom);\n const freeX = Math.max(0, innerW - contentBox.width);\n const freeY = Math.max(0, innerH - contentBox.height);\n const ox = align === \"end\" ? freeX : align === \"start\" ? 0 : freeX / 2;\n const oy = align === \"end\" ? freeY : align === \"start\" ? 0 : freeY / 2;\n return { x: slot.x + pad.left + ox, y: slot.y + pad.top + oy };\n}\n\nfunction collectDescendantNodeIds(graph: GraphModel, groupId: string): string[] {\n const group = graph.groups.find((g) => g.id === groupId);\n if (!group) return [];\n const ids = [...group.nodeIds];\n const stack = [...group.childGroupIds];\n while (stack.length) {\n const cid = stack.pop()!;\n const child = graph.groups.find((g) => g.id === cid);\n if (!child) continue;\n ids.push(...child.nodeIds);\n stack.push(...child.childGroupIds);\n }\n return ids;\n}\n\nfunction childGroupsOf(graph: GraphModel, parentId: string | undefined): GraphGroup[] {\n return graph.groups.filter((g) => g.parentId === parentId);\n}\n\n/** Reconstruct declaration order when `members` is missing (older compiled graphs). */\nfunction fallbackTrackMembers(\n graph: GraphModel,\n parent: GraphGroup,\n children: GraphGroup[],\n): Array<{ kind: \"node\"; id: string } | { kind: \"group\"; id: string }> {\n type Item = { kind: \"node\" | \"group\"; id: string; order: number };\n const items: Item[] = [];\n for (const id of parent.nodeIds) {\n const n = graph.nodes.find((node) => node.id === id);\n items.push({\n kind: \"node\",\n id,\n order: n?.sourceRange?.start.offset ?? Number.MAX_SAFE_INTEGER,\n });\n }\n for (const child of children) {\n let order = Number.MAX_SAFE_INTEGER;\n for (const nid of collectDescendantNodeIds(graph, child.id)) {\n const n = graph.nodes.find((node) => node.id === nid);\n const o = n?.sourceRange?.start.offset;\n if (o != null) order = Math.min(order, o);\n }\n items.push({ kind: \"group\", id: child.id, order });\n }\n items.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));\n return items.map(({ kind, id }) =>\n kind === \"node\" ? { kind: \"node\", id } : { kind: \"group\", id },\n );\n}\n\n/** Diagram-level declaration order across ungrouped nodes and top-level regions. */\nfunction topLevelTrackMembers(\n graph: GraphModel,\n children: GraphGroup[],\n): Array<{ kind: \"node\"; id: string } | { kind: \"group\"; id: string }> {\n type Item = { kind: \"node\" | \"group\"; id: string; order: number };\n const items: Item[] = graph.nodes\n .filter((node) => node.groupId == null)\n .map((node) => ({\n kind: \"node\" as const,\n id: node.id,\n order: node.sourceRange?.start.offset ?? Number.MAX_SAFE_INTEGER,\n }));\n\n for (const child of children) {\n let order = Number.MAX_SAFE_INTEGER;\n for (const nodeId of collectDescendantNodeIds(graph, child.id)) {\n const offset = graph.nodes.find((node) => node.id === nodeId)?.sourceRange?.start.offset;\n if (offset != null) order = Math.min(order, offset);\n }\n items.push({ kind: \"group\", id: child.id, order });\n }\n\n items.sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));\n return items.map(({ kind, id }) => ({ kind, id }));\n}\n\ntype ArrangeContext = {\n graph: GraphModel;\n measured: MeasuredNode[];\n measureMap: Map<string, MeasuredNode>;\n options: LayoutOptions;\n nodeBounds: Map<string, Rect>;\n groupBounds: Map<string, Rect>;\n};\n\n/**\n * Layout one arranged parent: size children, pack tracks, write world node/group bounds.\n * Direct member nodes participate as track cells (declaration order via `members`).\n */\nasync function layoutArrangedParent(ctx: ArrangeContext, parent: GraphGroup | null): Promise<void> {\n const arrange = parent?.arrange ?? ctx.options.arrange;\n if (!arrange) return;\n\n const children = childGroupsOf(ctx.graph, parent?.id);\n const members =\n parent?.members && parent.members.length > 0\n ? parent.members\n : parent\n ? fallbackTrackMembers(ctx.graph, parent, children)\n : topLevelTrackMembers(ctx.graph, children);\n const trackMembers = members;\n if (trackMembers.length === 0) return;\n\n const align = parent?.align ?? ctx.options.align ?? \"stretch\";\n const flowDirection = cellFlowDirection(arrange);\n const childById = new Map(children.map((g) => [g.id, g]));\n\n // Depth-first: nested arrange first\n for (const child of children) {\n if (groupHasRegionArrange(child)) {\n await layoutArrangedParent(ctx, child);\n }\n }\n\n const cells: RegionCell[] = [];\n const childContent = new Map<string, Map<string, Rect>>();\n\n for (const member of trackMembers) {\n if (member.kind === \"node\") {\n const m = ctx.measureMap.get(member.id);\n if (!m) continue;\n cells.push({\n groupId: nodeCellId(member.id),\n width: m.width,\n height: m.height,\n });\n continue;\n }\n\n const child = childById.get(member.id);\n if (!child) continue;\n\n let content: Map<string, Rect>;\n if (ctx.groupBounds.has(child.id) && groupHasRegionArrange(child)) {\n // Already laid out as nested arrange — use existing group bounds as cell size.\n const gb = ctx.groupBounds.get(child.id)!;\n cells.push({\n groupId: child.id,\n width: gb.width,\n height: gb.height,\n column: child.column,\n row: child.row,\n colSpan: child.colSpan ?? child.span,\n rowSpan: child.rowSpan,\n });\n continue;\n }\n\n const mode = child.cellArrange ?? \"flow\";\n const leafGap = resolveLeafGap(child.gap, ctx.options);\n if (mode === \"pack\" || mode === \"stack\") {\n content = packNodes(child.nodeIds, ctx.measureMap, mode, ctx.options.density, leafGap);\n } else {\n content = await layoutCellFlow(ctx.graph, child, ctx.measured, ctx.options, flowDirection);\n }\n childContent.set(child.id, content);\n\n const pad = paddingForGroup(child);\n const contentBox = aabbOf(content.values()) ?? { x: 0, y: 0, width: 80, height: 40 };\n const width = contentBox.width + pad.left + pad.right;\n const height = contentBox.height + pad.top + pad.bottom;\n cells.push({\n groupId: child.id,\n width,\n height,\n column: child.column,\n row: child.row,\n colSpan: child.colSpan ?? child.span,\n rowSpan: child.rowSpan,\n });\n }\n\n const placed = regionArrange({\n arrange,\n align,\n gap: resolveTrackGap(parent?.gap ?? ctx.options.gap, ctx.options),\n columns: parent?.columns ?? ctx.options.columns,\n rows: parent?.rows ?? ctx.options.rows,\n cells,\n origin: { x: LAYOUT_MARGIN, y: LAYOUT_MARGIN },\n });\n\n for (const slot of placed) {\n const directNodeId = parseNodeCellId(slot.groupId);\n if (directNodeId) {\n const m = ctx.measureMap.get(directNodeId);\n if (m) {\n const contentBox = { x: 0, y: 0, width: m.width, height: m.height };\n const origin = contentOriginInSlot(\n slot.bounds,\n { top: 0, right: 0, bottom: 0, left: 0 },\n contentBox,\n align,\n );\n ctx.nodeBounds.set(directNodeId, {\n x: origin.x,\n y: origin.y,\n width: m.width,\n height: m.height,\n });\n } else {\n ctx.nodeBounds.set(directNodeId, { ...slot.bounds });\n }\n continue;\n }\n\n const child = childById.get(slot.groupId);\n if (!child) continue;\n const pad = paddingForGroup(child);\n\n const content = childContent.get(child.id);\n if (content) {\n ctx.groupBounds.set(child.id, slot.bounds);\n const contentBox = aabbOf(content.values()) ?? { x: 0, y: 0, width: 0, height: 0 };\n const origin = contentOriginInSlot(slot.bounds, pad, contentBox, align);\n for (const [nodeId, local] of content) {\n ctx.nodeBounds.set(nodeId, {\n x: origin.x + (local.x - contentBox.x),\n y: origin.y + (local.y - contentBox.y),\n width: local.width,\n height: local.height,\n });\n }\n } else if (groupHasRegionArrange(child)) {\n // Nested arranged group: shift its subtree into this slot.\n // Read prev bounds BEFORE overwriting — otherwise dx/dy collapse to 0.\n const prev = ctx.groupBounds.get(child.id);\n if (prev) {\n const dx = slot.bounds.x - prev.x;\n const dy = slot.bounds.y - prev.y;\n ctx.groupBounds.set(child.id, slot.bounds);\n if (dx !== 0 || dy !== 0) {\n for (const nid of collectDescendantNodeIds(ctx.graph, child.id)) {\n const b = ctx.nodeBounds.get(nid);\n if (b) ctx.nodeBounds.set(nid, { ...b, x: b.x + dx, y: b.y + dy });\n }\n const stack = [...child.childGroupIds];\n while (stack.length) {\n const cid = stack.pop()!;\n const gb = ctx.groupBounds.get(cid);\n if (gb) ctx.groupBounds.set(cid, { ...gb, x: gb.x + dx, y: gb.y + dy });\n const g = ctx.graph.groups.find((x) => x.id === cid);\n if (g) stack.push(...g.childGroupIds);\n }\n }\n } else {\n ctx.groupBounds.set(child.id, slot.bounds);\n }\n } else {\n ctx.groupBounds.set(child.id, slot.bounds);\n }\n }\n\n // Parent shell bounds\n if (parent) {\n const box = aabbOf(placed.map((p) => p.bounds));\n if (box) {\n const pad = paddingForGroup(parent);\n ctx.groupBounds.set(parent.id, {\n x: box.x - pad.left,\n y: box.y - pad.top,\n width: box.width + pad.left + pad.right,\n height: box.height + pad.top + pad.bottom,\n });\n }\n }\n}\n\nfunction stubOrthogonalEdge(\n edgeId: string,\n fromId: string,\n toId: string,\n from: Rect,\n to: Rect,\n obstacles: Rect[],\n pad: number,\n tFrom: number,\n tTo: number,\n): ElkEdge {\n const points = routeOrthogonalAvoiding(from, to, obstacles, pad, tFrom, tTo);\n const start = points[0]!;\n const end = points[points.length - 1]!;\n const bendPoints = points.slice(1, -1);\n return {\n id: edgeId,\n sources: [fromId],\n targets: [toId],\n sections: [\n {\n id: `${edgeId}_s0`,\n startPoint: { x: start.x, y: start.y },\n endPoint: { x: end.x, y: end.y },\n bendPoints,\n },\n ],\n };\n}\n\nfunction fanSlot(index: number, count: number): number {\n if (count <= 1) return 0.5;\n // Spread shared-face fans enough to read as distinct corridors (esp. Loose/spacious).\n return 0.28 + (0.44 * index) / (count - 1);\n}\n\ntype OrthoSide = \"N\" | \"S\" | \"E\" | \"W\";\n\nfunction primaryExitSide(from: Rect, to: Rect): OrthoSide {\n return preferredSidePair(from, to)[0];\n}\n\nfunction primaryEntrySide(from: Rect, to: Rect): OrthoSide {\n return preferredSidePair(from, to)[1];\n}\n\n/** Sort key along a face — left→right for N/S, top→bottom for E/W. */\nfunction faceSortKey(node: Rect, other: Rect, side: OrthoSide): number {\n const ox = other.x + other.width / 2;\n const oy = other.y + other.height / 2;\n if (side === \"N\" || side === \"S\") return ox - node.x;\n return oy - node.y;\n}\n\nfunction rectsOverlap(a: Rect, b: Rect): boolean {\n return !(\n a.x + a.width < b.x ||\n b.x + b.width < a.x ||\n a.y + a.height < b.y ||\n b.y + b.height < a.y\n );\n}\n\n/**\n * Channel between facing sides of two boxes (primary axis only).\n * Used to decide which group chrome actually sits *between* the endpoints.\n */\nfunction facingStrip(from: Rect, to: Rect): Rect | null {\n const [fs] = preferredSidePair(from, to);\n if (fs === \"E\" || fs === \"W\") {\n const x0 = fs === \"E\" ? from.x + from.width : to.x + to.width;\n const x1 = fs === \"E\" ? to.x : from.x;\n if (x1 <= x0 + 1) return null;\n const y0 = Math.min(from.y, to.y);\n const y1 = Math.max(from.y + from.height, to.y + to.height);\n return { x: x0, y: y0, width: x1 - x0, height: Math.max(1, y1 - y0) };\n }\n const y0 = fs === \"S\" ? from.y + from.height : to.y + to.height;\n const y1 = fs === \"S\" ? to.y : from.y;\n if (y1 <= y0 + 1) return null;\n const x0 = Math.min(from.x, to.x);\n const x1 = Math.max(from.x + from.width, to.x + to.width);\n return { x: x0, y: y0, width: Math.max(1, x1 - x0), height: y1 - y0 };\n}\n\n/**\n * Fan attach slots only among edges that share the same exit/entry face.\n * A lone edge on a face stays centered (t=0.5).\n */\nfunction sideAwareFanSlots(\n routed: Array<{ id: string; from: string; to: string }>,\n nodeBounds: Map<string, Rect>,\n): { tFrom: Map<string, number>; tTo: Map<string, number> } {\n const tFrom = new Map<string, number>();\n const tTo = new Map<string, number>();\n\n type Member = { edgeId: string; key: number };\n const outGroups = new Map<string, Member[]>();\n const inGroups = new Map<string, Member[]>();\n\n for (const e of routed) {\n const from = nodeBounds.get(e.from)!;\n const to = nodeBounds.get(e.to)!;\n const outSide = primaryExitSide(from, to);\n const inSide = primaryEntrySide(from, to);\n const outKey = `${e.from}:${outSide}`;\n const inKey = `${e.to}:${inSide}`;\n if (!outGroups.has(outKey)) outGroups.set(outKey, []);\n if (!inGroups.has(inKey)) inGroups.set(inKey, []);\n outGroups.get(outKey)!.push({ edgeId: e.id, key: faceSortKey(from, to, outSide) });\n inGroups.get(inKey)!.push({ edgeId: e.id, key: faceSortKey(to, from, inSide) });\n }\n\n for (const members of outGroups.values()) {\n members.sort((a, b) => a.key - b.key);\n members.forEach((m, i) => tFrom.set(m.edgeId, fanSlot(i, members.length)));\n }\n for (const members of inGroups.values()) {\n members.sort((a, b) => a.key - b.key);\n members.forEach((m, i) => tTo.set(m.edgeId, fanSlot(i, members.length)));\n }\n\n return { tFrom, tTo };\n}\n\nfunction buildFixedElkGraph(\n graph: GraphModel,\n nodeBounds: Map<string, Rect>,\n groupBounds: Map<string, Rect>,\n options: LayoutOptions,\n): ElkGraph {\n const children: ElkNode[] = [];\n for (const node of graph.nodes) {\n const b = nodeBounds.get(node.id);\n if (!b) continue;\n children.push({\n id: node.id,\n x: b.x,\n y: b.y,\n width: b.width,\n height: b.height,\n });\n }\n\n const clearance = Math.max(\n MIN_EDGE_NODE_CLEARANCE,\n options.edgeNodeSpacing ?? MIN_EDGE_NODE_CLEARANCE,\n );\n // Footprint avoidance uses a tighter pad so gutters between cards stay usable;\n // ELK spacing still uses full clearance for the fixed pass metadata.\n const avoidPad = Math.min(12, clearance);\n const routed = graph.edges.filter((e) => nodeBounds.has(e.from) && nodeBounds.has(e.to));\n const { tFrom, tTo } = sideAwareFanSlots(routed, nodeBounds);\n\n const memberCache = new Map<string, Set<string>>();\n const membersOf = (groupId: string): Set<string> => {\n let set = memberCache.get(groupId);\n if (!set) {\n set = new Set(collectDescendantNodeIds(graph, groupId));\n memberCache.set(groupId, set);\n }\n return set;\n };\n\n const descendantGroups = (groupId: string): Set<string> => {\n const out = new Set<string>([groupId]);\n const stack = [groupId];\n while (stack.length) {\n const id = stack.pop()!;\n const g = graph.groups.find((x) => x.id === id);\n if (!g) continue;\n for (const child of g.childGroupIds) {\n if (out.has(child)) continue;\n out.add(child);\n stack.push(child);\n }\n }\n return out;\n };\n\n /** Groups that contain `nodeId` but not `otherId`, plus their nested groups. */\n const exclusiveSubtree = (nodeId: string, otherId: string): Set<string> => {\n const skip = new Set<string>();\n for (const g of graph.groups) {\n const members = membersOf(g.id);\n if (!members.has(nodeId) || members.has(otherId)) continue;\n for (const id of descendantGroups(g.id)) skip.add(id);\n }\n return skip;\n };\n\n const edges = routed.map((e) => {\n const from = nodeBounds.get(e.from)!;\n const to = nodeBounds.get(e.to)!;\n const obstacles: Rect[] = [];\n for (const [id, b] of nodeBounds) {\n if (id === e.from || id === e.to) continue;\n obstacles.push(b);\n }\n // Group chrome only when it sits in the facing strip AND isn't part of either\n // endpoint's exclusive nest (avoids mid-column stretch bands blocking column hops,\n // which used to force perimeter tours around the whole platform).\n const strip = facingStrip(from, to);\n if (strip) {\n const skip = new Set<string>([\n ...exclusiveSubtree(e.from, e.to),\n ...exclusiveSubtree(e.to, e.from),\n ]);\n for (const [gid, gb] of groupBounds) {\n if (skip.has(gid)) continue;\n const members = membersOf(gid);\n if (members.has(e.from) || members.has(e.to)) continue;\n if (!rectsOverlap(gb, strip)) continue;\n obstacles.push(gb);\n }\n }\n return stubOrthogonalEdge(\n e.id,\n e.from,\n e.to,\n from,\n to,\n obstacles,\n avoidPad,\n tFrom.get(e.id) ?? 0.5,\n tTo.get(e.id) ?? 0.5,\n );\n });\n\n return {\n id: \"root\",\n layoutOptions: {\n \"elk.algorithm\": \"fixed\",\n \"elk.edgeRouting\": \"ORTHOGONAL\",\n \"elk.direction\":\n options.direction === \"TD\"\n ? \"DOWN\"\n : options.direction === \"BT\"\n ? \"UP\"\n : options.direction === \"RL\"\n ? \"LEFT\"\n : \"RIGHT\",\n \"elk.spacing.nodeNode\": \"40\",\n \"elk.spacing.edgeNode\": String(clearance),\n \"elk.spacing.edgeEdge\": String(options.edgeEdgeSpacing ?? 18),\n \"elk.padding\": `[top=${LAYOUT_MARGIN},left=${LAYOUT_MARGIN},bottom=${LAYOUT_MARGIN},right=${LAYOUT_MARGIN}]`,\n },\n children,\n edges,\n };\n}\n\n/**\n * Region-arrange path: local cell layouts → track packing → fixed-position ELK for edges.\n */\nexport async function layoutAndRouteArranged(\n graph: GraphModel,\n measured: MeasuredNode[],\n options: LayoutOptions,\n): Promise<ArrangedLayoutResult> {\n const t0 = performance.now();\n const direction = options.direction ?? \"LR\";\n const measureMap = new Map(measured.map((m) => [m.nodeId, m]));\n const ctx: ArrangeContext = {\n graph,\n measured,\n measureMap,\n options,\n nodeBounds: new Map(),\n groupBounds: new Map(),\n };\n\n // Arranged parents (deepest first via recursion)\n if (options.arrange) {\n await layoutArrangedParent(ctx, null);\n } else {\n const arrangedParents = graph.groups.filter((g) => groupHasRegionArrange(g));\n const roots = arrangedParents.filter((g) => {\n if (!g.parentId) return true;\n const parent = graph.groups.find((p) => p.id === g.parentId);\n return !parent || !groupHasRegionArrange(parent);\n });\n for (const root of roots) {\n await layoutArrangedParent(ctx, root);\n }\n }\n\n // Residual nodes: park sources on the incoming side and sinks on the outgoing\n // side so client→system→external edges do not cut through the arranged core.\n const placedIds = new Set(ctx.nodeBounds.keys());\n const residualIds = graph.nodes.filter((n) => !placedIds.has(n.id)).map((n) => n.id);\n if (residualIds.length) {\n const residualSet = new Set(residualIds);\n const sources: string[] = [];\n const sinks: string[] = [];\n const other: string[] = [];\n for (const id of residualIds) {\n const feedsIn = graph.edges.some((e) => e.from === id && !residualSet.has(e.to));\n const fedFrom = graph.edges.some((e) => e.to === id && !residualSet.has(e.from));\n if (feedsIn && !fedFrom) sources.push(id);\n else if (fedFrom && !feedsIn) sinks.push(id);\n else other.push(id);\n }\n\n const placePack = (ids: string[], side: \"before\" | \"after\"): void => {\n if (ids.length === 0) return;\n const packMode =\n direction === \"TD\" || direction === \"BT\" ? (\"pack\" as const) : (\"stack\" as const);\n const packed = packNodes(\n ids,\n measureMap,\n packMode,\n options.density,\n resolveLeafGap(undefined, options),\n );\n const packedBox = aabbOf(packed.values()) ?? { x: 0, y: 0, width: 80, height: 40 };\n const arrangedBox = aabbOf(ctx.nodeBounds.values());\n let originX = LAYOUT_MARGIN;\n let originY = LAYOUT_MARGIN;\n if (arrangedBox) {\n if (direction === \"TD\" || direction === \"BT\") {\n originX = arrangedBox.x;\n originY =\n side === \"before\"\n ? arrangedBox.y - packedBox.height - DEFAULT_RESIDUAL_GAP\n : arrangedBox.y + arrangedBox.height + DEFAULT_RESIDUAL_GAP;\n } else {\n originY = arrangedBox.y;\n originX =\n side === \"before\"\n ? arrangedBox.x - packedBox.width - DEFAULT_RESIDUAL_GAP\n : arrangedBox.x + arrangedBox.width + DEFAULT_RESIDUAL_GAP;\n }\n }\n for (const [id, b] of packed) {\n ctx.nodeBounds.set(id, {\n ...b,\n x: b.x - packedBox.x + originX,\n y: b.y - packedBox.y + originY,\n });\n }\n };\n\n placePack(sources, \"before\");\n placePack([...sinks, ...other], \"after\");\n\n const allBox = aabbOf(ctx.nodeBounds.values());\n if (allBox && (allBox.x < LAYOUT_MARGIN || allBox.y < LAYOUT_MARGIN)) {\n const dx = Math.max(0, LAYOUT_MARGIN - allBox.x);\n const dy = Math.max(0, LAYOUT_MARGIN - allBox.y);\n if (dx || dy) {\n for (const [id, b] of ctx.nodeBounds) {\n ctx.nodeBounds.set(id, { ...b, x: b.x + dx, y: b.y + dy });\n }\n for (const [id, b] of ctx.groupBounds) {\n ctx.groupBounds.set(id, { ...b, x: b.x + dx, y: b.y + dy });\n }\n }\n }\n }\n\n // Edge routing with fixed node positions\n const elkGraph = buildFixedElkGraph(graph, ctx.nodeBounds, ctx.groupBounds, {\n ...options,\n direction,\n });\n const laid = await getElk().layout(elkGraph);\n\n // Keep our node positions (fixed alg should preserve; still prefer ours)\n const laidOutNodes: LaidOutNode[] = ranksFromFixed(\n [...ctx.nodeBounds.entries()].map(([nodeId, bounds]) => ({\n nodeId,\n bounds,\n rank: 0,\n order: 0,\n })),\n direction,\n );\n\n const groups: LaidOutGroup[] = [];\n for (const g of graph.groups) {\n const bounds = ctx.groupBounds.get(g.id);\n if (!bounds) continue;\n const padding = paddingForGroup(g);\n groups.push({\n groupId: g.id,\n bounds,\n labelBox: measureGroupLabelBox(\n g.label,\n bounds,\n Boolean(g.icon && g.icon !== \"none\" && g.chrome !== false),\n ),\n padding,\n });\n }\n\n // Collect edges from fixed layout\n const rawPaths: LayoutEdgePath[] = [];\n for (const edge of laid.edges ?? []) {\n const points: { x: number; y: number }[] = [];\n for (const section of edge.sections ?? []) {\n points.push({ ...section.startPoint });\n for (const bend of section.bendPoints ?? []) points.push({ ...bend });\n points.push({ ...section.endPoint });\n }\n if (points.length >= 2) rawPaths.push({ edgeId: edge.id, points });\n }\n // Also walk children edges if any\n const walkEdges = (node: ElkNode) => {\n for (const edge of node.edges ?? []) {\n if (rawPaths.some((p) => p.edgeId === edge.id)) continue;\n const points: { x: number; y: number }[] = [];\n for (const section of edge.sections ?? []) {\n points.push({\n x: (section.startPoint.x ?? 0) + (node.x ?? 0),\n y: (section.startPoint.y ?? 0) + (node.y ?? 0),\n });\n for (const bend of section.bendPoints ?? []) {\n points.push({ x: bend.x + (node.x ?? 0), y: bend.y + (node.y ?? 0) });\n }\n points.push({\n x: (section.endPoint.x ?? 0) + (node.x ?? 0),\n y: (section.endPoint.y ?? 0) + (node.y ?? 0),\n });\n }\n if (points.length >= 2) rawPaths.push({ edgeId: edge.id, points });\n }\n for (const c of node.children ?? []) walkEdges(c);\n };\n walkEdges(laid);\n\n const attachedPaths = snapEdgeEndpointsToGeometry(graph, laidOutNodes, rawPaths);\n // Fixed stubs are already corridor-aware; skip clearOrthogonalCorridors (it\n // creates loops when fan-out edges share a waypoint).\n const edgePaths = attachedPaths.map((path) => ({\n ...path,\n points: ensureOrthogonalPoints(collapseColinearPoints(path.points)),\n }));\n const edgeLabels: LayoutEdgeLabel[] = [];\n\n let maxX = 0;\n let maxY = 0;\n for (const n of laidOutNodes) {\n maxX = Math.max(maxX, n.bounds.x + n.bounds.width);\n maxY = Math.max(maxY, n.bounds.y + n.bounds.height);\n }\n for (const g of groups) {\n maxX = Math.max(maxX, g.bounds.x + g.bounds.width);\n maxY = Math.max(maxY, g.bounds.y + g.bounds.height);\n }\n for (const path of edgePaths) {\n for (const p of path.points) {\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n }\n }\n\n return {\n layout: {\n nodes: laidOutNodes,\n groups,\n edgePaths,\n edgeLabels,\n direction,\n algorithmVersion: ELK_LAYOUT_ALGORITHM,\n layoutMs: performance.now() - t0,\n width: maxX + 8,\n height: maxY + 8,\n },\n edges: edgePaths,\n routerAlgorithm: ELK_ROUTER_ALGORITHM,\n };\n}\n\nconst DEFAULT_RESIDUAL_GAP = 48;\n","import type {\n GraphModel,\n LayoutOptions,\n Point,\n Rect,\n SequenceFragment,\n SequenceIR,\n} from \"@kekonic/diagrams-core\";\nimport { sequenceFragmentDisplayName } from \"@kekonic/diagrams-core\";\nimport type { MeasuredNode } from \"../../measure/measure.ts\";\nimport type { LaidOutNode, LayoutEdgePath, LayoutResult } from \"../types.ts\";\n\nexport type SequenceLayoutRouteResult = {\n layout: LayoutResult;\n edges: LayoutEdgePath[];\n routerAlgorithm: string;\n};\n\nexport const SEQUENCE_LAYOUT_ALGORITHM = \"sequence-v1\";\nexport const SEQUENCE_ROUTER_ALGORITHM = \"sequence-direct-v1\";\n\nexport type SequenceLifelineLayout = {\n participantId: string;\n /** Vertical line from below header to diagram bottom. */\n x: number;\n y0: number;\n y1: number;\n};\n\nexport type SequenceActivationLayout = {\n id: string;\n participantId: string;\n startOrder: number;\n endOrder: number;\n bounds: Rect;\n};\n\nexport type SequenceFragmentLayout = {\n id: string;\n operator: SequenceFragment[\"operator\"];\n label?: string;\n styleRefs: string[];\n unresolvedVars: Record<string, string>;\n bounds: Rect;\n startOrder: number;\n endOrder: number;\n /** Horizontal separators between operands (alternate/else, parallel/and). */\n separators: number[];\n operandLabels: Array<{ text: string; x: number; y: number }>;\n /** Per-operand tint bands (success vs danger, etc.). */\n operandBands: Array<{\n startOrder: number;\n endOrder: number;\n styleRefs: string[];\n bounds: Rect;\n }>;\n};\n\nexport type SequenceNoteLayout = {\n id: string;\n bounds: Rect;\n text: string;\n};\n\nexport type SequenceDividerLayout = {\n id: string;\n y: number;\n x0: number;\n x1: number;\n label?: string;\n};\n\nexport type SequenceMessageLayout = {\n messageId: string;\n kind: NonNullable<SequenceIR[\"messages\"][number][\"kind\"]>;\n points: Point[];\n label?: string;\n labelCenter?: Point;\n number?: number;\n};\n\nexport type SequenceLayoutArtifacts = {\n lifelines: SequenceLifelineLayout[];\n activations: SequenceActivationLayout[];\n fragments: SequenceFragmentLayout[];\n notes: SequenceNoteLayout[];\n dividers: SequenceDividerLayout[];\n messages: SequenceMessageLayout[];\n};\n\nconst HEADER_GAP = 32;\nconst PARTICIPANT_GAP = 48;\n/** Vertical pitch per message/note/divider order — room for label above the path. */\nconst SLOT_H = 52;\nconst LABEL_GAP = 14;\nconst FRAGMENT_PAD_X = 14;\nconst FRAGMENT_PAD_Y = 14;\nconst FRAGMENT_HEADER = 22;\n/** Extra gap inserted before a fragment starts / after it ends. */\nconst FRAGMENT_EDGE_GAP = 10;\nconst ACTIVATION_W = 10;\nconst SELF_LOOP_W = 44;\nconst SELF_LOOP_EXTRA = 22;\nconst MARGIN = 24;\nconst NOTE_PAD = 10;\nconst NOTE_LINE = 15;\nconst NOTE_BAND_GAP = 12;\nconst DIVIDER_BAND = 36;\n\nfunction densityScale(density: LayoutOptions[\"density\"]): number {\n if (density === \"compact\") return 0.88;\n if (density === \"spacious\") return 1.22;\n return 1;\n}\n\n/**\n * Build cumulative Y baselines for each order index.\n * Notes, dividers, self-messages, and fragment edges reserve extra vertical band\n * so labels/boxes don't collide with neighboring message paths.\n */\nfunction buildOrderBaselines(\n seq: SequenceIR,\n contentTop: number,\n slotH: number,\n): {\n yAt: (order: number) => number;\n bandTop: (order: number) => number;\n bandBottom: (order: number) => number;\n bottomY: number;\n} {\n const maxOrder = Math.max(\n 0,\n ...seq.messages.map((m) => m.order),\n ...seq.notes.map((n) => n.order),\n ...seq.dividers.map((d) => d.order),\n ...seq.activations.map((a) => a.endOrder),\n );\n\n const noteAt = new Map(seq.notes.map((n) => [n.order, n]));\n const dividerAt = new Map(seq.dividers.map((d) => [d.order, d]));\n const selfAt = new Set(\n seq.messages.filter((m) => m.from && m.to && m.from === m.to).map((m) => m.order),\n );\n\n const fragStart = new Set<number>();\n const fragEnd = new Set<number>();\n const operandSepBefore = new Set<number>();\n\n const walkFrags = (fragments: SequenceFragment[]) => {\n for (const frag of fragments) {\n fragStart.add(frag.startOrder);\n fragEnd.add(frag.endOrder);\n for (let i = 1; i < frag.operands.length; i++) {\n operandSepBefore.add(frag.operands[i]!.startOrder);\n }\n for (const op of frag.operands) walkFrags(op.children);\n }\n };\n walkFrags(seq.fragments);\n\n const yBaselines = new Map<number, number>();\n const tops = new Map<number, number>();\n const bottoms = new Map<number, number>();\n let cursor = contentTop;\n\n for (let order = 0; order <= maxOrder; order++) {\n let topPad = 0;\n let band = slotH;\n let bottomPad = 0;\n\n if (fragStart.has(order)) {\n topPad += FRAGMENT_HEADER + FRAGMENT_PAD_Y + FRAGMENT_EDGE_GAP;\n }\n if (operandSepBefore.has(order)) {\n topPad += 18;\n }\n\n const note = noteAt.get(order);\n if (note) {\n band = Math.max(band, measureNoteHeight(note.text) + NOTE_BAND_GAP);\n }\n if (dividerAt.has(order)) {\n band = Math.max(band, DIVIDER_BAND);\n }\n if (selfAt.has(order)) {\n band = Math.max(band, slotH + SELF_LOOP_EXTRA);\n }\n if (fragEnd.has(order)) {\n bottomPad += FRAGMENT_PAD_Y + FRAGMENT_EDGE_GAP;\n }\n\n const top = cursor;\n const center = cursor + topPad + band / 2;\n const bottom = cursor + topPad + band + bottomPad;\n tops.set(order, top);\n yBaselines.set(order, center);\n bottoms.set(order, bottom);\n cursor = bottom;\n }\n\n const fallback = (order: number) => contentTop + order * slotH;\n return {\n yAt: (order: number) => yBaselines.get(order) ?? fallback(order) + slotH / 2,\n bandTop: (order: number) => tops.get(order) ?? fallback(order),\n bandBottom: (order: number) => bottoms.get(order) ?? fallback(order) + slotH,\n bottomY: cursor + MARGIN,\n };\n}\n\nfunction measureNoteHeight(text: string): number {\n const lines = Math.max(1, Math.ceil(text.length / 32));\n return lines * NOTE_LINE + NOTE_PAD * 2;\n}\n\n/**\n * Time-axis sequence layout: participants on X, messages ordered on Y.\n */\nexport function layoutSequence(\n graph: GraphModel,\n measured: MeasuredNode[],\n options: LayoutOptions = {},\n): SequenceLayoutRouteResult {\n const t0 = performance.now();\n const seq = graph.sequence;\n if (!seq) {\n return emptySequenceResult(t0);\n }\n\n const scale = densityScale(options.density);\n const slotH = SLOT_H * scale;\n const participantGap = PARTICIPANT_GAP * scale;\n const measuredById = new Map(measured.map((m) => [m.nodeId, m]));\n\n // Participant headers along X.\n const nodes: LaidOutNode[] = [];\n const centers = new Map<string, number>();\n let x = MARGIN;\n let headerH = 40;\n\n for (const [i, id] of seq.participantOrder.entries()) {\n const m = measuredById.get(id);\n const w = m?.width ?? 120;\n const h = m?.height ?? 40;\n headerH = Math.max(headerH, h);\n const bounds: Rect = { x, y: MARGIN, width: w, height: h };\n nodes.push({ nodeId: id, bounds, rank: 0, order: i });\n centers.set(id, x + w / 2);\n x += w + participantGap;\n }\n\n const contentTop = MARGIN + headerH + HEADER_GAP * scale;\n const { yAt, bandTop, bandBottom, bottomY } = buildOrderBaselines(seq, contentTop, slotH);\n\n const messages: SequenceMessageLayout[] = [];\n const edgePaths: LayoutEdgePath[] = [];\n const edgeLabels: LayoutResult[\"edgeLabels\"] = [];\n let msgNumber = 0;\n\n for (const msg of seq.messages) {\n // Create counts as a real hop; destroy is just the X glyph (no number).\n if (seq.autonumber && msg.kind !== \"destroy\") msgNumber += 1;\n const y = yAt(msg.order);\n const fromX =\n msg.from && centers.has(msg.from)\n ? centers.get(msg.from)!\n : msg.kind === \"found\"\n ? (centers.get(msg.to!) ?? MARGIN) - 40\n : MARGIN;\n const toX =\n msg.to && centers.has(msg.to)\n ? centers.get(msg.to)!\n : msg.kind === \"lost\"\n ? (centers.get(msg.from!) ?? MARGIN) + 40\n : fromX;\n\n let points: Point[];\n if (msg.kind === \"destroy\") {\n const cx = centers.get(msg.from!) ?? fromX;\n points = [\n { x: cx - 8, y: y - 8 },\n { x: cx + 8, y: y + 8 },\n { x: cx + 8, y: y - 8 },\n { x: cx - 8, y: y + 8 },\n ];\n } else if (msg.from && msg.to && msg.from === msg.to) {\n const cx = centers.get(msg.from)!;\n const loopDepth = Math.max(18, SELF_LOOP_EXTRA * scale);\n points = [\n { x: cx, y: y - loopDepth * 0.15 },\n { x: cx + SELF_LOOP_W, y: y - loopDepth * 0.15 },\n { x: cx + SELF_LOOP_W, y: y + loopDepth * 0.85 },\n { x: cx, y: y + loopDepth * 0.85 },\n ];\n } else {\n points = [\n { x: fromX, y },\n { x: toX, y },\n ];\n }\n\n const labelCenter =\n points.length >= 2\n ? {\n x: (points[0]!.x + points[points.length - 1]!.x) / 2,\n y: Math.min(points[0]!.y, points[points.length - 1]!.y) - LABEL_GAP,\n }\n : undefined;\n\n messages.push({\n messageId: msg.id,\n kind: msg.kind,\n points,\n label: msg.label,\n labelCenter,\n number: seq.autonumber && msg.kind !== \"destroy\" ? msgNumber : undefined,\n });\n\n if (msg.from && msg.to && msg.from !== \"*\" && msg.to !== \"*\") {\n edgePaths.push({ edgeId: msg.id, points });\n // Message labels are painted by the sequence overlay (not flowchart edgeLabels).\n }\n }\n\n const lifelines: SequenceLifelineLayout[] = [];\n for (const id of seq.participantOrder) {\n const cx = centers.get(id)!;\n const node = nodes.find((n) => n.nodeId === id)!;\n lifelines.push({\n participantId: id,\n x: cx,\n y0: node.bounds.y + node.bounds.height,\n y1: bottomY,\n });\n }\n\n const activations: SequenceActivationLayout[] = seq.activations.map((a) => {\n const cx = centers.get(a.participantId) ?? MARGIN;\n const y0 = yAt(a.startOrder) - 6;\n const y1 = yAt(a.endOrder) + 6;\n return {\n id: a.id,\n participantId: a.participantId,\n startOrder: a.startOrder,\n endOrder: a.endOrder,\n bounds: {\n x: cx - ACTIVATION_W / 2,\n y: Math.min(y0, y1),\n width: ACTIVATION_W,\n height: Math.max(8, Math.abs(y1 - y0)),\n },\n };\n });\n\n const fragments: SequenceFragmentLayout[] = [];\n const layoutFrag = (frag: SequenceFragment, depth: number): void => {\n const xs = seq.participantOrder.map((id) => centers.get(id)!);\n const minX = Math.min(...xs) - FRAGMENT_PAD_X - depth * 6;\n const maxX = Math.max(...xs) + FRAGMENT_PAD_X + depth * 6;\n // Stay inside reserved bands — don't bleed into the prior note/message.\n const y0 = bandTop(frag.startOrder) + 2;\n const y1 = bandBottom(frag.endOrder) - 2;\n const separators: number[] = [];\n const operandLabels: Array<{ text: string; x: number; y: number }> = [];\n const operandBands: SequenceFragmentLayout[\"operandBands\"] = [];\n\n for (let i = 0; i < frag.operands.length; i++) {\n const op = frag.operands[i]!;\n const opTop = i === 0 ? y0 : bandTop(op.startOrder);\n const opBottom =\n i === frag.operands.length - 1 ? y1 : bandTop(frag.operands[i + 1]!.startOrder);\n operandBands.push({\n startOrder: op.startOrder,\n endOrder: op.endOrder,\n styleRefs: op.styleRefs,\n bounds: {\n x: minX,\n y: opTop,\n width: maxX - minX,\n height: Math.max(8, opBottom - opTop),\n },\n });\n if (i > 0) {\n separators.push(opTop);\n if (op.label) {\n operandLabels.push({ text: op.label, x: minX + 8, y: opTop + 4 });\n }\n }\n }\n if (frag.label) {\n operandLabels.unshift({\n text: `${sequenceFragmentDisplayName(frag.operator)} [${frag.label}]`,\n x: minX + 8,\n y: y0 + 6,\n });\n } else {\n operandLabels.unshift({\n text: sequenceFragmentDisplayName(frag.operator),\n x: minX + 8,\n y: y0 + 6,\n });\n }\n\n fragments.push({\n id: frag.id,\n operator: frag.operator,\n label: frag.label,\n styleRefs: frag.styleRefs,\n unresolvedVars: frag.unresolvedVars,\n bounds: { x: minX, y: y0, width: maxX - minX, height: Math.max(24, y1 - y0) },\n startOrder: frag.startOrder,\n endOrder: frag.endOrder,\n separators,\n operandLabels,\n operandBands,\n });\n\n for (const op of frag.operands) {\n for (const child of op.children) layoutFrag(child, depth + 1);\n }\n };\n for (const frag of seq.fragments) layoutFrag(frag, 0);\n\n const notes: SequenceNoteLayout[] = seq.notes.map((n) => {\n const y = yAt(n.order);\n const h = measureNoteHeight(n.text);\n const ids = n.participantIds.filter((id) => centers.has(id));\n let x0: number;\n let x1: number;\n if (n.placement === \"over\" && ids.length) {\n const xs = ids.map((id) => centers.get(id)!);\n x0 = Math.min(...xs) - 24;\n x1 = Math.max(...xs) + 24;\n } else if (n.placement === \"left\" && ids[0]) {\n const cx = centers.get(ids[0])!;\n x0 = cx - 150;\n x1 = cx - 24;\n } else if (ids[0]) {\n const cx = centers.get(ids[0])!;\n x0 = cx + 24;\n x1 = cx + 150;\n } else {\n x0 = MARGIN;\n x1 = MARGIN + 120;\n }\n const w = Math.max(80, x1 - x0);\n return {\n id: n.id,\n text: n.text,\n bounds: { x: x0, y: y - h / 2, width: w, height: h },\n };\n });\n\n const firstX = Math.min(...centers.values(), MARGIN);\n const lastX = Math.max(...centers.values(), MARGIN);\n const dividers: SequenceDividerLayout[] = seq.dividers.map((d) => ({\n id: d.id,\n // Line at baseline; label sits clearly above so it doesn't collide with prior message.\n y: yAt(d.order) + 4,\n x0: firstX - 20,\n x1: lastX + 20,\n label: d.label,\n }));\n\n const sequence: SequenceLayoutArtifacts = {\n lifelines,\n activations,\n fragments,\n notes,\n dividers,\n messages,\n };\n\n let maxX = x;\n let maxY = bottomY;\n for (const f of fragments) {\n maxX = Math.max(maxX, f.bounds.x + f.bounds.width);\n maxY = Math.max(maxY, f.bounds.y + f.bounds.height);\n }\n for (const n of notes) {\n maxX = Math.max(maxX, n.bounds.x + n.bounds.width);\n maxY = Math.max(maxY, n.bounds.y + n.bounds.height);\n }\n for (const path of edgePaths) {\n for (const p of path.points) {\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n }\n }\n\n const layout: LayoutResult = {\n nodes,\n groups: [],\n edgePaths,\n edgeLabels,\n direction: \"TD\",\n algorithmVersion: SEQUENCE_LAYOUT_ALGORITHM,\n layoutMs: performance.now() - t0,\n width: maxX + MARGIN,\n height: maxY + MARGIN,\n sequence,\n };\n\n return {\n layout,\n edges: edgePaths,\n routerAlgorithm: SEQUENCE_ROUTER_ALGORITHM,\n };\n}\n\nfunction emptySequenceResult(t0: number): SequenceLayoutRouteResult {\n return {\n layout: {\n nodes: [],\n groups: [],\n edgePaths: [],\n edgeLabels: [],\n direction: \"TD\",\n algorithmVersion: SEQUENCE_LAYOUT_ALGORITHM,\n layoutMs: performance.now() - t0,\n width: 0,\n height: 0,\n },\n edges: [],\n routerAlgorithm: SEQUENCE_ROUTER_ALGORITHM,\n };\n}\n\nexport function isSequenceGraph(graph: GraphModel): boolean {\n return graph.diagramKind === \"sequence\" || graph.sequence != null;\n}\n","import type { GraphModel, LayoutOptions, Point, Rect } from \"@kekonic/diagrams-core\";\nimport type { MeasuredNode } from \"../../measure/measure.ts\";\nimport { computeGroupBounds, measureGroupLabelBox, paddingForGroup } from \"../group-bounds.ts\";\nimport type {\n LaidOutGroup,\n LaidOutNode,\n LayoutEdgeLabel,\n LayoutEdgePath,\n LayoutResult,\n} from \"../types.ts\";\nimport { buildElkGraph, endpointNodeId } from \"./build-elk-graph.ts\";\nimport {\n ELK_LAYOUT_ALGORITHM,\n ELK_ROUTER_ALGORITHM,\n getElk,\n type ElkEdge,\n type ElkGraph,\n type ElkNode,\n} from \"./elk-engine.ts\";\nimport { snapEdgeEndpointsToGeometry } from \"../attach-endpoints.ts\";\nimport { polishEdgePaths, MIN_EDGE_NODE_CLEARANCE } from \"./polish-edges.ts\";\nimport { layoutAndRouteArranged, needsRegionArrange } from \"./layout-arranged.ts\";\nimport { isSequenceGraph, layoutSequence } from \"../sequence/layout-sequence.ts\";\n\nexport type { LayoutEdgePath };\n\nexport type ElkLayoutAndRouteResult = {\n layout: LayoutResult;\n /** Same as `layout.edgePaths`. */\n edges: LayoutEdgePath[];\n routerAlgorithm: string;\n};\n\ntype ElkNodeIndex = {\n bounds: Rect;\n parentId: string | null;\n};\n\nfunction collectAbsoluteNodes(\n node: ElkNode,\n offsetX: number,\n offsetY: number,\n parentId: string | null,\n boundsOut: Map<string, Rect>,\n index: Map<string, ElkNodeIndex>,\n): void {\n const x = offsetX + (node.x ?? 0);\n const y = offsetY + (node.y ?? 0);\n const bounds = {\n x,\n y,\n width: node.width ?? 0,\n height: node.height ?? 0,\n };\n index.set(node.id, { bounds, parentId });\n if (node.id !== \"root\") {\n boundsOut.set(node.id, bounds);\n }\n for (const child of node.children ?? []) {\n collectAbsoluteNodes(child, x, y, node.id, boundsOut, index);\n }\n}\n\n/**\n * With INCLUDE_CHILDREN, ELK may list edges on the root while section/label\n * coordinates stay relative to the LCA of the endpoints (often a compound group).\n * Offset by that LCA's absolute origin — not the edges-array owner.\n */\nfunction edgeCoordinateOrigin(\n index: Map<string, ElkNodeIndex>,\n sourceId: string | undefined,\n targetId: string | undefined,\n): Point {\n if (!sourceId || !targetId) return { x: 0, y: 0 };\n\n const sourceNode = endpointNodeId(sourceId);\n const targetNode = endpointNodeId(targetId);\n\n const ancestors = new Set<string>();\n let cur: string | null = sourceNode;\n while (cur) {\n ancestors.add(cur);\n cur = index.get(cur)?.parentId ?? null;\n }\n\n cur = targetNode;\n while (cur) {\n if (ancestors.has(cur)) {\n const hit = index.get(cur);\n return hit ? { x: hit.bounds.x, y: hit.bounds.y } : { x: 0, y: 0 };\n }\n cur = index.get(cur)?.parentId ?? null;\n }\n\n return { x: 0, y: 0 };\n}\n\nfunction collectAbsoluteEdges(\n node: ElkNode,\n index: Map<string, ElkNodeIndex>,\n paths: LayoutEdgePath[],\n labels: LayoutEdgeLabel[],\n seen: Set<string>,\n): void {\n for (const edge of node.edges ?? []) {\n if (seen.has(edge.id)) continue;\n seen.add(edge.id);\n\n const origin = edgeCoordinateOrigin(index, edge.sources?.[0], edge.targets?.[0]);\n const points = edgePoints(edge, origin.x, origin.y);\n if (points.length >= 2) paths.push({ edgeId: edge.id, points });\n\n for (const label of edge.labels ?? []) {\n if (label.x == null || label.y == null || !label.width || !label.height) continue;\n const bounds = {\n x: origin.x + label.x,\n y: origin.y + label.y,\n width: label.width,\n height: label.height,\n };\n labels.push({\n edgeId: edge.id,\n text: label.text,\n bounds,\n anchor: { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 },\n });\n }\n }\n for (const child of node.children ?? []) {\n collectAbsoluteEdges(child, index, paths, labels, seen);\n }\n}\n\nfunction edgePoints(edge: ElkEdge, offsetX: number, offsetY: number): Point[] {\n const points: Point[] = [];\n for (const section of edge.sections ?? []) {\n points.push({ x: section.startPoint.x + offsetX, y: section.startPoint.y + offsetY });\n for (const bend of section.bendPoints ?? []) {\n points.push({ x: bend.x + offsetX, y: bend.y + offsetY });\n }\n points.push({ x: section.endPoint.x + offsetX, y: section.endPoint.y + offsetY });\n }\n return dedupePoints(points);\n}\n\nfunction dedupePoints(points: Point[]): Point[] {\n const out: Point[] = [];\n for (const p of points) {\n const prev = out[out.length - 1];\n if (prev && Math.abs(prev.x - p.x) < 0.5 && Math.abs(prev.y - p.y) < 0.5) continue;\n out.push(p);\n }\n return out;\n}\n\nfunction ranksFromBounds(\n nodes: Array<{ nodeId: string; bounds: Rect }>,\n direction: LayoutOptions[\"direction\"],\n): LaidOutNode[] {\n const dir = direction ?? \"LR\";\n const horizontal = dir === \"LR\" || dir === \"RL\";\n const sorted = [...nodes].sort((a, b) => {\n const aPrimary = horizontal ? a.bounds.x : a.bounds.y;\n const bPrimary = horizontal ? b.bounds.x : b.bounds.y;\n if (aPrimary !== bPrimary) return aPrimary - bPrimary;\n const aSecondary = horizontal ? a.bounds.y : a.bounds.x;\n const bSecondary = horizontal ? b.bounds.y : b.bounds.x;\n return aSecondary - bSecondary;\n });\n\n const rankOf = new Map<string, number>();\n let rank = 0;\n let lastPrimary = Number.NEGATIVE_INFINITY;\n for (const n of sorted) {\n const primary = horizontal ? n.bounds.x : n.bounds.y;\n if (primary - lastPrimary > 8) {\n if (lastPrimary !== Number.NEGATIVE_INFINITY) rank += 1;\n lastPrimary = primary;\n }\n rankOf.set(n.nodeId, rank);\n }\n\n const orderInRank = new Map<number, number>();\n return sorted.map((n) => {\n const r = rankOf.get(n.nodeId) ?? 0;\n const order = orderInRank.get(r) ?? 0;\n orderInRank.set(r, order + 1);\n return {\n nodeId: n.nodeId,\n bounds: n.bounds,\n rank: r,\n order,\n };\n });\n}\n\nfunction groupsFromElk(\n graph: GraphModel,\n absolute: Map<string, Rect>,\n laidOutNodes: LaidOutNode[],\n): LaidOutGroup[] {\n const fallback = computeGroupBounds(graph, laidOutNodes);\n const byId = new Map(fallback.map((g) => [g.groupId, g]));\n\n for (const group of graph.groups) {\n const elkBounds = absolute.get(`group:${group.id}`);\n if (!elkBounds || elkBounds.width <= 0 || elkBounds.height <= 0) continue;\n const padding = paddingForGroup(group);\n byId.set(group.id, {\n groupId: group.id,\n bounds: elkBounds,\n labelBox: measureGroupLabelBox(\n group.label,\n elkBounds,\n Boolean(group.icon && group.icon !== \"none\" && group.chrome !== false),\n ),\n padding,\n });\n }\n\n return [...byId.values()];\n}\n\n/**\n * Layout + orthogonal edge routes via ELK (elkjs API; elk-rs drop-in when published).\n */\nexport async function layoutAndRouteWithElk(\n graph: GraphModel,\n measured: MeasuredNode[],\n options: LayoutOptions = {},\n): Promise<ElkLayoutAndRouteResult> {\n if (isSequenceGraph(graph)) {\n return layoutSequence(graph, measured, options);\n }\n if (needsRegionArrange(graph, options)) {\n return layoutAndRouteArranged(graph, measured, options);\n }\n\n const t0 = performance.now();\n const direction = options.direction ?? \"LR\";\n const elkGraph = buildElkGraph(graph, measured, { ...options, direction });\n const laid: ElkGraph = await getElk().layout(elkGraph);\n\n const absolute = new Map<string, Rect>();\n const index = new Map<string, ElkNodeIndex>();\n collectAbsoluteNodes(laid, 0, 0, null, absolute, index);\n\n const nodeEntries = graph.nodes\n .map((n) => {\n const b = absolute.get(n.id);\n if (!b) return null;\n return { nodeId: n.id, bounds: b };\n })\n .filter((n): n is NonNullable<typeof n> => n != null);\n\n const laidOutNodes = ranksFromBounds(nodeEntries, direction);\n const groups = groupsFromElk(graph, absolute, laidOutNodes);\n\n const rawPaths: LayoutEdgePath[] = [];\n const rawLabels: LayoutEdgeLabel[] = [];\n collectAbsoluteEdges(laid, index, rawPaths, rawLabels, new Set());\n // Authoritative visual attach: snap termini onto ShapeGeometry perimeters, then\n // polish corridors with those endpoints frozen (ERD column snap runs later).\n const attachedPaths = snapEdgeEndpointsToGeometry(graph, laidOutNodes, rawPaths);\n const edgePaths = polishEdgePaths(\n attachedPaths,\n laidOutNodes.map((n) => n.bounds),\n Math.max(MIN_EDGE_NODE_CLEARANCE, options.edgeNodeSpacing ?? MIN_EDGE_NODE_CLEARANCE),\n );\n const edgeLabels = rawLabels;\n\n let maxX = 0;\n let maxY = 0;\n for (const n of laidOutNodes) {\n maxX = Math.max(maxX, n.bounds.x + n.bounds.width);\n maxY = Math.max(maxY, n.bounds.y + n.bounds.height);\n }\n for (const g of groups) {\n maxX = Math.max(maxX, g.bounds.x + g.bounds.width);\n maxY = Math.max(maxY, g.bounds.y + g.bounds.height);\n }\n for (const path of edgePaths) {\n for (const p of path.points) {\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n }\n }\n for (const label of edgeLabels) {\n maxX = Math.max(maxX, label.bounds.x + label.bounds.width);\n maxY = Math.max(maxY, label.bounds.y + label.bounds.height);\n }\n\n const layout: LayoutResult = {\n nodes: laidOutNodes,\n groups,\n edgePaths,\n edgeLabels,\n direction,\n algorithmVersion: ELK_LAYOUT_ALGORITHM,\n layoutMs: performance.now() - t0,\n width: Math.max(maxX, laid.width ?? 0) + 8,\n height: Math.max(maxY, laid.height ?? 0) + 8,\n };\n\n return {\n layout,\n edges: edgePaths,\n routerAlgorithm: ELK_ROUTER_ALGORITHM,\n };\n}\n","import type { GraphModel, LayoutOptions } from \"@kekonic/diagrams-core\";\nimport { mergeOptions } from \"@kekonic/diagrams-core\";\nimport { measureGraph } from \"./measure/measure.ts\";\nimport { layoutAndRouteWithElk } from \"./layout/elk/layout-with-elk.ts\";\nimport type { LayoutResult } from \"./layout/types.ts\";\n\nconst DEFAULT_LAYOUT: LayoutOptions = {\n direction: \"LR\",\n density: \"normal\",\n spacingScale: 1.1,\n algorithmVersion: \"elk-layered-v1\",\n groupLayout: \"compound\",\n nodePlacement: \"balanced\",\n};\n\nexport async function layoutFromGraph(\n graph: GraphModel,\n layoutOpts: LayoutOptions = {},\n): Promise<LayoutResult> {\n const opts = mergeOptions(DEFAULT_LAYOUT, layoutOpts);\n const measured = measureGraph(graph);\n const result = await layoutAndRouteWithElk(graph, measured.nodes, opts);\n return result.layout;\n}\n\nexport type { LayoutResult };\n","/** Load bundled Inter via FontFace so canvas metrics match CLI opentype measurer. */\n\nlet fontLoadPromise: Promise<void> | null = null;\nlet fontsReady = false;\n\nexport function browserFontsReady(): boolean {\n return fontsReady;\n}\n\nexport function ensureBrowserFonts(fontUrl: string): Promise<void> {\n if (typeof document === \"undefined\") return Promise.resolve();\n if (fontsReady) return Promise.resolve();\n if (fontLoadPromise) return fontLoadPromise;\n\n fontLoadPromise = (async () => {\n const face = new FontFace(\"Inter\", `url(${fontUrl})`, {\n weight: \"500\",\n style: \"normal\",\n });\n await face.load();\n document.fonts.add(face);\n await document.fonts.load('500 14px \"Inter\"');\n fontsReady = true;\n })();\n\n return fontLoadPromise;\n}\n","import type { GraphModel, Point, Rect } from \"@kekonic/diagrams-core\";\nimport { findColumnIndex } from \"@kekonic/diagrams-core\";\nimport type { LayoutResult, LayoutEdgePath } from \"../layout/types.ts\";\nimport { columnAnchorY, isErdTableNode } from \"../measure/table-measure.ts\";\n\ntype Side = \"left\" | \"right\";\n\nconst OUTER_CLEARANCE = 18;\n\n/**\n * Snap ERD edge endpoints to column midlines while preserving orthogonal routes.\n * Runs after ELK; before crossing treatment / trim.\n */\nexport function snapErdEdgeEndpoints(\n graph: GraphModel,\n layout: LayoutResult,\n edgePaths: LayoutEdgePath[],\n): LayoutEdgePath[] {\n const nodeMap = new Map(layout.nodes.map((n) => [n.nodeId, n]));\n const graphNodes = new Map(graph.nodes.map((n) => [n.id, n]));\n const obstacles = layout.nodes.map((n) => ({ nodeId: n.nodeId, rect: n.bounds }));\n\n return edgePaths.map((path) => {\n const edge = graph.edges.find((e) => e.id === path.edgeId);\n if (!edge || (!edge.fromColumn && !edge.toColumn)) return path;\n if (path.points.length < 2) return path;\n\n const fromNode = graphNodes.get(edge.from);\n const toNode = graphNodes.get(edge.to);\n const fromLaid = nodeMap.get(edge.from);\n const toLaid = nodeMap.get(edge.to);\n if (!fromNode || !toNode || !fromLaid || !toLaid) return path;\n\n let fromY: number | undefined;\n let toY: number | undefined;\n\n if (edge.fromColumn && isErdTableNode(fromNode)) {\n const row = findColumnIndex(fromNode.columns, edge.fromColumn);\n if (row >= 0) fromY = columnAnchorY(fromLaid.bounds.y, row, fromNode.scale ?? 1);\n }\n if (edge.toColumn && isErdTableNode(toNode)) {\n const row = findColumnIndex(toNode.columns, edge.toColumn);\n if (row >= 0) toY = columnAnchorY(toLaid.bounds.y, row, toNode.scale ?? 1);\n }\n if (fromY == null && toY == null) return path;\n\n const sides = pickAttachmentSides(fromLaid.bounds, toLaid.bounds, path.points);\n const start = pointOnSide(fromLaid.bounds, sides.fromSide, fromY ?? path.points[0]!.y);\n const end = pointOnSide(\n toLaid.bounds,\n sides.toSide,\n toY ?? path.points[path.points.length - 1]!.y,\n );\n\n let points = rebuildOrthogonal(start, end, path.points, sides);\n // If the preferred outer side still clips an unrelated table, try the opposite outer side.\n if (\n sides.fromSide === sides.toSide &&\n pathCrossesObstacles(points, obstacles, edge.from, edge.to)\n ) {\n const flipped: Side = sides.fromSide === \"left\" ? \"right\" : \"left\";\n const altSides = { fromSide: flipped, toSide: flipped };\n const altStart = pointOnSide(fromLaid.bounds, flipped, start.y);\n const altEnd = pointOnSide(toLaid.bounds, flipped, end.y);\n const alt = rebuildOrthogonal(altStart, altEnd, path.points, altSides);\n if (!pathCrossesObstacles(alt, obstacles, edge.from, edge.to)) {\n points = alt;\n }\n }\n\n return { ...path, points };\n });\n}\n\n/** Choose left/right faces. Facing sides when horizontally separated; shared outer side when stacked. */\nexport function pickAttachmentSides(\n fromBounds: Rect,\n toBounds: Rect,\n original: Point[],\n): { fromSide: Side; toSide: Side } {\n const fromRight = fromBounds.x + fromBounds.width;\n const toRight = toBounds.x + toBounds.width;\n const gapToRight = toBounds.x - fromRight;\n const gapToLeft = fromBounds.x - toRight;\n\n if (gapToRight > 0) return { fromSide: \"right\", toSide: \"left\" };\n if (gapToLeft > 0) return { fromSide: \"left\", toSide: \"right\" };\n\n // Overlapping X ranges (typical TD stacks): exit/enter on the same outer side so the\n // vertical run stays outside both cards instead of cutting through them.\n const fromMid = fromBounds.x + fromBounds.width / 2;\n const hint = original[0];\n const preferLeft = hint ? hint.x <= fromMid : true;\n const side: Side = preferLeft ? \"left\" : \"right\";\n return { fromSide: side, toSide: side };\n}\n\nfunction pointOnSide(bounds: Rect, side: Side, y: number): Point {\n return {\n x: side === \"left\" ? bounds.x : bounds.x + bounds.width,\n y,\n };\n}\n\nfunction rebuildOrthogonal(\n start: Point,\n end: Point,\n original: Point[],\n sides: { fromSide: Side; toSide: Side },\n): Point[] {\n if (Math.abs(start.y - end.y) < 0.5) {\n return [start, end];\n }\n if (Math.abs(start.x - end.x) < 0.5) {\n return [start, end];\n }\n\n // Same-side attachments: route around the outside, not between the faces.\n if (sides.fromSide === sides.toSide) {\n const midX =\n sides.fromSide === \"left\"\n ? Math.min(start.x, end.x) - OUTER_CLEARANCE\n : Math.max(start.x, end.x) + OUTER_CLEARANCE;\n return [start, { x: midX, y: start.y }, { x: midX, y: end.y }, end];\n }\n\n // Facing sides: two-bend route through the clear horizontal gap.\n const lo = Math.min(start.x, end.x);\n const hi = Math.max(start.x, end.x);\n let midX = (start.x + end.x) / 2;\n const interior = original.slice(1, -1);\n if (interior.length) {\n const xs = interior.map((p) => p.x).sort((a, b) => a - b);\n const candidate = xs[Math.floor(xs.length / 2)]!;\n if (candidate >= lo && candidate <= hi) midX = candidate;\n }\n\n return [start, { x: midX, y: start.y }, { x: midX, y: end.y }, end];\n}\n\nfunction pathCrossesObstacles(\n points: Point[],\n obstacles: Array<{ nodeId: string; rect: Rect }>,\n fromId: string,\n toId: string,\n): boolean {\n const exclude = new Set([fromId, toId]);\n for (let i = 0; i < points.length - 1; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n for (const { nodeId, rect } of obstacles) {\n if (exclude.has(nodeId)) continue;\n if (segmentHitsRectInterior(a, b, rect)) return true;\n }\n }\n return false;\n}\n\n/** True when an orthogonal segment enters the open interior of a rect (not just grazing a face). */\nfunction segmentHitsRectInterior(from: Point, to: Point, rect: Rect): boolean {\n const left = rect.x;\n const right = rect.x + rect.width;\n const top = rect.y;\n const bottom = rect.y + rect.height;\n const eps = 0.75;\n\n if (Math.abs(from.y - to.y) < eps) {\n const y = from.y;\n if (y <= top + eps || y >= bottom - eps) return false;\n const x0 = Math.min(from.x, to.x);\n const x1 = Math.max(from.x, to.x);\n return x0 < right - eps && x1 > left + eps;\n }\n\n if (Math.abs(from.x - to.x) < eps) {\n const x = from.x;\n if (x <= left + eps || x >= right - eps) return false;\n const y0 = Math.min(from.y, to.y);\n const y1 = Math.max(from.y, to.y);\n return y0 < bottom - eps && y1 > top + eps;\n }\n\n return false;\n}\n\nexport function erdRelationshipLabel(edge: {\n fromColumn?: string;\n toColumn?: string;\n label?: string;\n}): string | undefined {\n if (edge.fromColumn && edge.toColumn) {\n return `${edge.toColumn} → ${edge.fromColumn}`;\n }\n if (edge.toColumn) return edge.toColumn;\n if (edge.fromColumn) return edge.fromColumn;\n return edge.label;\n}\n\n// Re-export geometry helpers used by finalize / render.\nexport { columnAnchorY };\n"],"mappings":";;;;;;AAaA,MAAM,iBAAiB;AAEvB,MAAM,WACJ,OAAO,eAAe,UAAU,aAC3B,iBACA,eAAe;AAEtB,IAAI;AAEJ,SAAS,kBAAwC;CAC/C,IAAI,OAAO,aAAa,aAAa,OAAO;CAC5C,IAAI,eAAe,KAAA,GAAW,OAAO;CACrC,IAAI;EAIF,MAAM,iBACJ,WAGA;EACF,MAAM,gBAAgB,gBAAgB,mBAAmB,QAAQ;EAGjE,MAAM,YAAY,gBAAgB,mBAAmB,IAAI;EAGzD,IAAI,CAAC,iBAAiB,CAAC,WAAW,OAAO;EAEzC,MAAM,EAAE,kBAAkB;EAC1B,MAAM,EAAE,iBAAiB;EAGzB,MAAM,SAAS,aAFK,cAAc,OAAO,KAAK,GACnB,CAAC,CAAC,QAAQ,qDACF,CAAC;EACpC,aAAa,SAAS,MAAM,MAAM;EAClC,OAAO;CACT,QAAQ;EACN,aAAa;EACb,OAAO;CACT;AACF;AAEA,SAAgB,yBAA8C;CAC5D,MAAM,OAAO,gBAAgB;CAC7B,IAAI,CAAC,MAAM,OAAO;CAElB,OAAO;EACL,YAAY,MAAc,OAA+B;GACvD,MAAM,QAAQ,MAAM,WAAW,KAAK;GACpC,IAAI,QAAQ;GACZ,KAAK,MAAM,MAAM,MAAM;IACrB,MAAM,QAAQ,KAAK,YAAY,EAAE;IACjC,UAAU,MAAM,gBAAgB,KAAK;GACvC;GACA,MAAM,UAAU,KAAK,YAAY,KAAK,aAAa,MAAO;GAC1D,MAAM,UAAU,KAAK,IAAI,KAAK,aAAa,KAAK,aAAa,EAAG,IAAI;GACpE,OAAO;IAAE;IAAO,QAAQ,SAAS;IAAS;IAAQ;GAAQ;EAC5D;EAEA,SAAS,MAAc,SAAmC;GACxD,MAAM,QAAQ,KAAK,MAAM,KAAK;GAC9B,MAAM,QAAkB,CAAC;GACzB,IAAI,UAAU;GACd,IAAI,OAAO;GACX,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,OAAO,UAAU,GAAG,QAAQ,GAAG,SAAS;IAE9C,IADU,KAAK,YAAY,MAAM,QAAQ,KAAK,CAAC,CAAC,QACxC,QAAQ,YAAY,SAAS;KACnC,MAAM,KAAK,OAAO;KAClB,OAAO,KAAK,IAAI,MAAM,KAAK,YAAY,SAAS,QAAQ,KAAK,CAAC,CAAC,KAAK;KACpE,UAAU;IACZ,OACE,UAAU;GAEd;GACA,IAAI,SAAS;IACX,MAAM,KAAK,OAAO;IAClB,OAAO,KAAK,IAAI,MAAM,KAAK,YAAY,SAAS,QAAQ,KAAK,CAAC,CAAC,KAAK;GACtE;GACA,MAAM,QAAQ,QAAQ,MAAM,WAAW;GACvC,OAAO;IACL,OAAO,MAAM,SAAS,QAAQ,CAAC,IAAI;IACnC,OAAO;IACP,SAAS,MAAM,UAAU,KAAK;GAChC;EACF;CACF;AACF;;;;ACnEA,MAAa,sBAAsB;AAGnC,MAAa,cAAc;AAC3B,MAAM,mBAAmB;AAEzB,IAAI,uBAAuB;AAE3B,SAAgB,oCAA6C;CAC3D,OAAO;AACT;AAEA,SAAS,wBAAsC;CAC7C,IAAI,OAAO,aAAa,aACtB,OAAO,qBAAqB;CAE9B,MAAM,eAAe,uBAAuB;CAC5C,IAAI,cAAc,OAAO;CACzB,uBAAuB;CACvB,OAAO,0BAA0B;AACnC;AAEA,SAAS,4BAA0C;CACjD,OAAO;EACL,YAAY,MAAc,OAA+B;GAEvD,OAAO;IACL,OAFY,KAAK,SAAS,MAAM,WAAW;IAG3C,QAAQ,MAAM,WAAW;IACzB,QAAQ,MAAM,WAAW;IACzB,SAAS,MAAM,WAAW;GAC5B;EACF;EACA,SAAS,MAAc,SAAmC;GACxD,MAAM,QAAQ,KAAK,MAAM,KAAK;GAC9B,MAAM,QAAkB,CAAC;GACzB,IAAI,UAAU;GACd,IAAI,OAAO;GACX,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,OAAO,UAAU,GAAG,QAAQ,GAAG,SAAS;IAE9C,IADU,KAAK,SAAS,QAAQ,MAAM,WAAW,mBACzC,QAAQ,YAAY,SAAS;KACnC,MAAM,KAAK,OAAO;KAClB,OAAO,KAAK,IAAI,MAAM,QAAQ,SAAS,QAAQ,MAAM,WAAW,gBAAgB;KAChF,UAAU;IACZ,OACE,UAAU;GAEd;GACA,IAAI,SAAS;IACX,MAAM,KAAK,OAAO;IAClB,OAAO,KAAK,IAAI,MAAM,QAAQ,SAAS,QAAQ,MAAM,WAAW,gBAAgB;GAClF;GACA,MAAM,QAAQ,QAAQ,MAAM,WAAW;GACvC,OAAO;IACL,OAAO,MAAM,SAAS,QAAQ,CAAC,IAAI;IACnC,OAAO;IACP,SAAS,MAAM,UAAU,KAAK;GAChC;EACF;CACF;AACF;AAEA,SAAgB,qBAAqB,QAA0C;CAE7E,MAAM,OADI,WAAW,OAAO,aAAa,cAAc,SAAS,cAAc,QAAQ,IAAI,MAAA,EAC3E,WAAW,IAAI,KAAK;CAEnC,OAAO;EACL,YAAY,MAAc,OAA+B;GACvD,IAAI,KAAK;IACP,IAAI,OAAO,GAAG,MAAM,cAAc,MAAM,GAAG,MAAM,SAAS,KAAK,MAAM;IACrE,MAAM,IAAI,IAAI,YAAY,IAAI;IAC9B,MAAM,SAAS,EAAE,2BAA2B,MAAM,WAAW;IAC7D,MAAM,UAAU,EAAE,4BAA4B,MAAM,WAAW;IAC/D,OAAO;KAAE,OAAO,EAAE;KAAO,QAAQ,SAAS;KAAS;KAAQ;IAAQ;GACrE;GAEA,OAAO;IACL,OAFY,KAAK,SAAS,MAAM,WAAW;IAG3C,QAAQ,MAAM,WAAW;IACzB,QAAQ,MAAM,WAAW;IACzB,SAAS,MAAM,WAAW;GAC5B;EACF;EAEA,SAAS,MAAc,SAAmC;GACxD,MAAM,QAAQ,KAAK,MAAM,KAAK;GAC9B,MAAM,QAAkB,CAAC;GACzB,IAAI,UAAU;GACd,IAAI,OAAO;GACX,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,OAAO,UAAU,GAAG,QAAQ,GAAG,SAAS;IAE9C,IADU,KAAK,YAAY,MAAM,QAAQ,KAAK,CAAC,CAAC,QACxC,QAAQ,YAAY,SAAS;KACnC,MAAM,KAAK,OAAO;KAClB,OAAO,KAAK,IAAI,MAAM,KAAK,YAAY,SAAS,QAAQ,KAAK,CAAC,CAAC,KAAK;KACpE,UAAU;IACZ,OACE,UAAU;GAEd;GACA,IAAI,SAAS;IACX,MAAM,KAAK,OAAO;IAClB,OAAO,KAAK,IAAI,MAAM,KAAK,YAAY,SAAS,QAAQ,KAAK,CAAC,CAAC,KAAK;GACtE;GACA,MAAM,QAAQ,QAAQ,MAAM,WAAW;GACvC,OAAO;IACL,OAAO,MAAM,SAAS,QAAQ,CAAC,IAAI;IACnC,OAAO;IACP,SAAS,MAAM,UAAU,KAAK;GAChC;EACF;CACF;AACF;AAEA,IAAI;AAEJ,SAAgB,uBAA6B;CAC3C,mBAAmB,KAAA;CACnB,uBAAuB;AACzB;AAEA,SAAS,sBAAoC;CAC3C,IAAI,CAAC,kBAAkB,mBAAmB,sBAAsB;CAChE,OAAO;AACT;AAEA,MAAa,kBAAgC;CAC3C,YAAY,MAAM,OAAO;EACvB,OAAO,oBAAoB,CAAC,CAAC,YAAY,MAAM,KAAK;CACtD;CACA,SAAS,MAAM,SAAS;EACtB,OAAO,oBAAoB,CAAC,CAAC,SAAS,MAAM,OAAO;CACrD;AACF;;;;ACnKA,MAAa,cAAc;AAC3B,MAAa,iBAAiB;AAC9B,MAAa,cAAc;;AAE3B,MAAa,gBAAgB;AAC7B,MAAa,kBAAkB;;;;;AAK/B,MAAa,gBAAgB;AAG7B,MAAa,WAAW;;AAExB,MAAa,iBAAiB;AAU9B,SAAgB,eAAe,MAA0B;CACvD,OAAO,KAAK,UAAU,WAAW,QAAQ,KAAK,WAAW,KAAK,QAAQ,SAAS,CAAC;AAClF;AAEA,SAAgB,cAAc,UAAkB,UAAkB,QAAQ,GAAW;CACnF,MAAM,UAAA,KAA2B;CACjC,MAAM,OAAA,KAAqB;CAC3B,OAAO,WAAW,UAAU,WAAW,OAAO,OAAO;AACvD;;AAGA,SAAgB,gBAAgB,KAA0B;CACxD,OAAO,IAAI,MAAM,KAAK,KAAK;AAC7B;;AAGA,SAAgB,gBAAgB,KAA0B;CACxD,OAAO,IAAI,MAAM,KAAK,KAAK;AAC7B;;;;AAKA,SAAgB,iBACd,MACA,UACA,OACA,eACA,gBACc;CACd,MAAM,OAAA,KAAqB;CAC3B,MAAM,UAAA,KAA2B;CACjC,MAAM,OAAA,KAAqB;CAC3B,MAAM,SAAA,KAAyB;CAC/B,MAAM,UAAA,KAA2B;CACjC,MAAM,UAAA,IAA2B;CACjC,MAAM,YAAY,KAAK;CACvB,MAAM,cAAc,KAAK;CACzB,MAAM,cAAc,KAAK;CACzB,MAAM,cAAc,MAAM;CAE1B,MAAM,eAAe,SAAS,YAAY,KAAK,OAAO;EACpD,UAAU;EACV,YAAY;EACZ,YAAY;CACd,CAAC;CAED,IAAI,gBAAgB;CACpB,MAAM,UAAU,KAAK,WAAW,CAAC;CACjC,KAAK,MAAM,OAAO,SAAS;EACzB,MAAM,QAAQ,SAAS,YAAY,IAAI,MAAM;GAC3C,UAAU;GACV,YAAY;GACZ,YAAY;EACd,CAAC,CAAC,CAAC;EACH,MAAM,YAAY,gBAAgB,GAAG;EACrC,MAAM,YAAY,gBAAgB,GAAG;EACrC,MAAM,QAAQ,YACV,SAAS,YAAY,WAAW;GAC9B,UAAU;GACV,YAAY;GACZ,YAAY;EACd,CAAC,CAAC,CAAC,QACH;EACJ,MAAM,QAAQ,YACV,SAAS,YAAY,WAAW;GAC9B,UAAU;GACV,YAAY;GACZ,YAAY;EACd,CAAC,CAAC,CAAC,QACH;EASJ,MAAM,QAAQ;GAAC;GAPH,IAAI,UACZ,SAAS,YAAY,MAAM;IACzB,UAAU;IACV,YAAY;IACZ,YAAY;GACd,CAAC,CAAC,CAAC,QACH;GACuB;EAAK,CAAC,CAAC,QAAQ,MAAM,IAAI,CAAC;EACrD,MAAM,SAAS,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI;EAEtF,gBAAgB,KAAK,IAAI,eAAe,SAAS,SAAS,SAAS,UAAU,SAAS,EAAE;CAC1F;CAEA,MAAM,WAAW,KAAK,IAAI,aAAa,QAAQ,IAAI,OAAO,aAAa,IAAI,OAAO;CAMlF,OAAO;EACL,OAJY,KAAK,IAAI,eAAA,MAA6B,OAAO,QAIrD;EACJ,QAJa,UAAU,KAAK,IAAI,GAAG,QAAQ,MAAM,IAAI;EAKrD,cAAc;EACd,WAAW;EACX,YAAY,CAAC,KAAK,KAAK;CACzB;AACF;;AAGA,SAAgB,eAAe,KAA4B;CACzD,MAAM,SAAmB,CAAC;CAC1B,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,OAAO,KAAK,IAAI;CAC7C,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,OAAO,KAAK,IAAI;CAC7C,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,OAAO,KAAK,IAAI;CAC7C,OAAO;AACT;;;AChGA,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,iBAAiB;AACvB,MAAM,aAAa;AACnB,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;AAC1B,MAAM,0BAA0B;AAChC,MAAM,cAAc;AACpB,MAAM,cAAc;AACpB,MAAM,eAAe;AACrB,MAAM,mBAAmB;;AAEzB,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AACvB,MAAM,oBAAoB;AAC1B,MAAM,cAAwD;CAC5D,SAAS;EAAE,GAAG;EAAI,GAAG;CAAG;CACxB,UAAU;EAAE,GAAG;EAAI,GAAG;CAAG;CACzB,SAAS;EAAE,GAAG;EAAI,GAAG;CAAG;CACxB,QAAQ;EAAE,GAAG;EAAI,GAAG;CAAE;CACtB,OAAO;EAAE,GAAG;EAAI,GAAG;CAAG;CACtB,eAAe;EAAE,GAAG;EAAI,GAAG;CAAE;CAC7B,WAAW;EAAE,GAAG;EAAI,GAAG;CAAE;CACzB,UAAU;EAAE,GAAG;EAAI,GAAG;CAAG;CACzB,UAAU;EAAE,GAAG;EAAG,GAAG;CAAG;CACxB,mBAAmB;EAAE,GAAG;EAAG,GAAG;CAAG;CACjC,OAAO;EAAE,GAAG;EAAI,GAAG;CAAG;CACtB,QAAQ;EAAE,GAAG;EAAI,GAAG;CAAG;CACvB,SAAS;EAAE,GAAG;EAAI,GAAG;CAAG;CACxB,UAAU;EAAE,GAAG;EAAG,GAAG;CAAE;AACzB;;AAGA,SAAgB,oBAAoB,QAAgB,QAAQ,GAAW;CACrE,MAAM,SAAS,mBAAmB;CAElC,MAAM,EAAE,UAAU,gBADD,YAAY,MACY,KAAK;EAAE,OAAO;EAAG,QAAQ;CAAE,GAAG,MAAM;CAC7E,OAAO,KAAK,IAAI,eAAe,OAAO,KAAK;AAC7C;AAEA,SAAgB,aACd,OACA,WAAyB,iBACzB,UAA0B,CAAC,GACZ;CACf,MAAM,QAAQ,YAAY,IAAI;CAC9B,MAAM,QAAwB,CAAC;CAE/B,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,MAAM,QAAQ,iBAAiB,KAAK,SAAS,SAAS;EACtD,MAAM,WAAW,qBAAqB,KAAK;EAC3C,MAAM,YAAY,UAAU,aAAa,UAAU,eAAe,UAAU;EAC5E,MAAM,UAAU,QAAQ,KAAK,QAAQ,KAAK,SAAS,MAAM;EACzD,MAAM,EAAE,UAAU,iBAAiB,gBAAgB,KAAK,IAAI;EAC5D,MAAM,WACJ,kBAAkB,KAAK,MAAM,WAAW,KAAK,aAAa,aAAa,SAAS,WAAW;EAC7F,MAAM,QAAQ,KAAK,SAAS,KAAK,QAAQ,IAAI,KAAK,QAAQ;EAC1D,MAAM,WAAA,KAA+B;EACrC,MAAM,OAAO,YAAY;EAIzB,MAAM,QAHc,QACjB,KAAK,cAAc,KAAK,WAAW,KAAK,KAAO,KAAK,eAAe,KAAK,YAAY,KAAK,CAEpE,IAAI,iBAAiB,aAAa;EAC1D,MAAM,UAAU,KAAK;EACrB,MAAM,iBACH,KAAK,YAAY,aAAa,oBAAoB,KAAK,WAAW,IAAI;EACzE,MAAM,iBACH,KAAK,YAAY,aAAa,oBAAoB,KAAK,WAAW,IAAI;EAEzE,IAAI,UAAU;GACZ,MAAM,UAAU,KAAK,gBACjB,SAAS,SAAS,KAAK,OAAO;IAC5B,UAAU,gBAAgB;IAC1B,OAAO;KACL,UAAU,WAAW;KACrB,YAAY;KACZ,YAAY;IACd;GACF,CAAC,IACD;IAAE,OAAO,CAAC;IAAe,OAAO;IAAG,QAAQ;GAAE;GACjD,MAAM,OAAO,KAAK,IAChB,eACA,KAAK,IACH,eACA,iBAAiB,SAAS,QAAQ,SAAS,IAAI,oBAAoB,QAAQ,EAC7E,CACF;GACA,MAAM,SAAS,KAAK,IAAI,MAAM,iBAAiB,QAAQ,QAAQ,MAAM;GACrE,MAAM,KAAK;IACT,QAAQ,KAAK;IACb,OAAO;IACP;IACA,YAAY,mBAAmB,UAAU,MAAM,MAAM;IACrD,YAAY,QAAQ;GACtB,CAAC;GACD;EACF;EAEA,IAAI,UAAU,WAAW,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;GAChE,MAAM,QAAQ,iBAAiB,MAAM,UAAU,OAAO,eAAe,aAAa;GAClF,MAAM,KAAK;IACT,QAAQ,KAAK;IACb,OAAO,MAAM;IACb,QAAQ,MAAM;IACd,YAAY,mBAAmB,UAAU,MAAM,OAAO,MAAM,MAAM;IAClE,YAAY,MAAM;GACpB,CAAC;GACD;EACF;EAEA,IAAI,UAAU,WAAW;GACvB,MAAM,aAAa,gBAAgB,OAAO,KAAK;GAC/C,MAAM,UAAU,SAAS,SAAS,KAAK,OAAO;IAC5C,UAAU;IACV,OAAO;KAAE;KAAU,YAAY;KAAqB,YAAY;IAAM;GACxE,CAAC;GAYD,MAAM,cAAc;IAClB,OAZkB,KAAK,IACvB,GAAG,QAAQ,MAAM,KACd,SACC,SAAS,YAAY,MAAM;KACzB;KACA,YAAY;KACZ,YAAY;IACd,CAAC,CAAC,CAAC,KACP,GACA,QAAQ,KAGS,IAAI,OAAO;IAC5B,QAAQ,QAAQ,SAAS,OAAO;GAClC;GACA,MAAM,QAAQ,uBAAuB,UAAU,aAAa;IAC1D,OAAO,KAAK,IAAI,eAAe,YAAY,QAAQ,GAAG;IACtD,QAAQ,KAAK,IAAI,KAAK,OAAO,YAAY,SAAS,GAAG;GACvD,CAAC;GAED,MAAM,QAAQ,KAAK,IAAI,eAAe,MAAM,KAAK;GACjD,MAAM,SAAS,KAAK,IAAI,KAAK,OAAO,MAAM,MAAM;GAChD,MAAM,KAAK;IACT,QAAQ,KAAK;IACb;IACA;IACA,YAAY,mBAAmB,UAAU,OAAO,MAAM;IACtD,YAAY,QAAQ;GACtB,CAAC;GACD;EACF;EAEA,MAAM,UAAU,aAAa,WAAW,KAAK,OAAO,oBAAoB,KAAK,MAAM,KAAK,IAAI;EAC5F,MAAM,UAAU,SAAS,SAAS,KAAK,OAAO;GAC5C,UAAU,gBAAgB,OAAO,IAAI;GACrC,OAAO;IAAE;IAAU,YAAY;IAAqB,YAAY;GAAM;EACxE,CAAC;EACD,MAAM,QAAQ,YAAY,UAAU;GAAE,GAAG;GAAG,GAAG;EAAE;EACjD,MAAM,QAAQ,aAAa,UAAU,UAAU,gBAAgB,QAAQ,UAAU,IAAI,QAAQ;EAC7F,MAAM,QAAQ,WAAW,CAAC,YAAY,aAAa,QAAQ;EAC3D,MAAM,mBAAmB,KAAK,UAAU,KAAK,IAAI,KAAK,SAAS,KAAK,IAAI,KAAA;EACxE,MAAM,gBACJ,QAAQ,gBAAgB,KAAK,KAAK,iBAAiB,QAAQ,QAAQ;EAErE,MAAM,YAAY,gBAAgB,kBAAkB,QAAQ;EAC5D,IAAI,YAAY;EAChB,IAAI,eAAe;GACjB,MAAM,eAAe,YAAY,OAAA;GACjC,MAAM,gBAAgB,oBAAoB,aAAa,KAAK,IAAI,EAAA,CAAG,YAAY;GAO/E,YANiB,SAAS,YAAY,cAAc;IAClD,UAAU;IACV,YAAY;IACZ,YAAY;GACd,CAAC,CAAC,CAAC,QACc,KAAK,IAAI,GAAG,aAAa,SAAS,CAAC,IAAI,eAAe;EAEzE;EACA,MAAM,QAAQ,KAAK,OAAO,cAAc,QAAQ;EAChD,IAAI,QAAQ;EACZ,IAAI,KAAK,MACP,QAAQ,SAAS,YAAY,KAAK,MAAM;GACtC,UAAU,YAAY,IAAA;GACtB,YAAY;GACZ,YAAY;EACd,CAAC,CAAC,CAAC;EAEL,MAAM,aAAa,KAAK,YAAY,KAAK,IAAI,KAAK,WAAW,KAAK,IAAI,KAAA;EACtE,MAAM,cAAc,KAAK,aAAa,KAAK,IAAI,KAAK,YAAY,KAAK,IAAI,KAAA;EACzE,MAAM,WAAW,gBAAgB,OAAO,IAAI;EAC5C,MAAM,aAAa,cAAc;EAEjC,IAAI;EACJ,IAAI,cAAc;EAClB,IAAI,cAAc;EAClB,IAAI,YAAY;GACd,MAAM,WAAW,YAAY,KAAA;GAC7B,MAAM,WAAW,SAAS,SAAS,YAAY;IAC7C,UAAU;IACV,OAAO;KAAE,UAAU;KAAU,YAAY;KAAqB,YAAY;IAAM;GAClF,CAAC;GACD,kBAAkB,SAAS;GAC3B,cAAc,SAAS;GACvB,cAAc,gBAAgB,SAAS,oBAAoB;EAC7D;EAEA,IAAI;EACJ,IAAI,eAAe;EACnB,IAAI,eAAe;EACnB,IAAI,aAAa;GACf,MAAM,WAAW,YAAY,KAAA;GAC7B,MAAM,WAAW,SAAS,SAAS,aAAa;IAC9C,UAAU;IACV,OAAO;KAAE,UAAU;KAAU,YAAY;KAAqB,YAAY;IAAM;GAClF,CAAC;GACD,mBAAmB,SAAS;GAC5B,eAAe,SAAS;GACxB,eAAe,iBAAiB,SAAS,0BAA0B;EACrE;EAEA,MAAM,mBAAmB,mBAAmB,mBAAmB,aAAa;EAC5E,MAAM,eAAe,mBAAmB,mBAAmB,aAAa;EAGxE,MAAM,cACJ,UAAU,YAAY,UAAU,aAAa,QAAQ,UAAU,WAAW,IAAI;EAChF,MAAM,aACJ,QAAQ,SACR,YACA,mBACA,cACA,eACA,eACA;EACF,MAAM,WACJ,KAAK,IAAI,QAAQ,OAAO,WAAW,aAAa,cAAc,KAAK,IACnE,OAAO,IACP,MAAM,IAAI,QACV;EACF,MAAM,WAAW,aAAa,OAAO,IAAI,MAAM,IAAI,QAAQ;EAE3D,IAAI,QAAQ,KAAK,IAAI,eAAe,QAAQ;EAE5C,MAAM,UAAU,WAAW,KAAK,QAAQ,WAAW,KAAK,IAAI,QAAQ,UAAU,IAAI,IAAI;EACtF,IAAI,SAAS,KAAK,IAAI,SAAS,WAAW,OAAO;EAEjD,IAAI,UAAU,aAAa,UAAU,SACnC,SAAS,KAAK,IAAI,QAAQ,QAAQ,GAAI;EAGxC,IAAI,UAAU,YACZ,SAAS,KAAK,IAAI,QAAQ,KAAK,IAAI,QAAQ,KAAM,KAAK,KAAK,CAAC;EAG9D,IAAI,WAAW;GAKb,MAAM,QAAQ,uBAAuB,UAAU;IAH7C,OAAO,KAAK,IAAI,QAAQ,OAAO,WAAW,aAAa,cAAc,KAAK,IAAI;IAC9E,QAAQ;GAEyC,GAAG;IAAE;IAAO;GAAO,CAAC;GACvE,QAAQ,KAAK,IAAI,OAAO,MAAM,KAAK;GACnC,SAAS,KAAK,IAAI,QAAQ,MAAM,MAAM;EACxC;EAGA,IAAI,UAAU,SAEZ,QAAQ,KAAK,IAAI,OAAO,SAAS,GAAW;EAG9C,IAAI,UAAU,UAAU;GACtB,MAAM,QAAQ,KAAK,IAAI,eAAe,QAAQ;GAC9C,MAAM,QAAQ,KAAK,IAAI,KAAK,OAAO,aAAa,OAAO,IAAI,WAAW;GAEtE,MAAM,YAAY,KAAK,IAAI,IAAI,QAAQ,IAAI,CAAC;GAC5C,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,YAAY,GAAI,CAAC;GACzD,MAAM,YAAY,QAAQ,IAAI,KAAK,IAAI,GAAG,QAAQ,GAAI,IAAI;GAC1D,QAAQ;GACR,SAAS,YAAY;EACvB;EACA,IAAI,UAAU,UAAU;GACtB,MAAM,OAAO,KAAK,IAAI,OAAO,MAAM;GACnC,QAAQ;GACR,SAAS;EACX;EAEA,MAAM,KAAK;GACT,QAAQ,KAAK;GACb;GACA;GACA,YAAY,mBAAmB,UAAU,OAAO,MAAM;GACtD,YAAY,QAAQ;GACpB;GACA;EACF,CAAC;CACH;CAEA,OAAO;EAAE;EAAO,WAAW,YAAY,IAAI,IAAI;CAAM;AACvD;;;AC3UA,MAAa,cAAuC;CAClD,SAAS;CACT,QAAQ;CACR,UAAU;AACZ;AAEA,MAAa,wBAAoC;CAC/C,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;AACR;;AAGA,MAAa,4BAAwC;CACnD,KAAK;CACL,OAAO;CACP,QAAQ;CACR,MAAM;AACR;AAEA,MAAa,gBAA4C;CACvD,SAAS;EAAE,KAAK;EAAI,OAAO;EAAI,QAAQ;EAAI,MAAM;CAAG;CACpD,QAAQ;EAAE,KAAK;EAAI,OAAO;EAAI,QAAQ;EAAI,MAAM;CAAG;CACnD,UAAU;EAAE,KAAK;EAAI,OAAO;EAAI,QAAQ;EAAI,MAAM;CAAG;;CAErD,OAAO;EAAE,KAAK;EAAK,OAAO;EAAI,QAAQ;EAAI,MAAM;CAAG;AACrD;;;ACzBA,MAAM,wBAAwB;AAE9B,MAAM,wBAAwB;AAC9B,MAAM,wBAAwB;AAC9B,MAAa,kBAAkB;AAC/B,MAAa,iBAAiB;AAE9B,SAAgB,gBAAgB,OAA4C;CAC1E,MAAM,aAAa,MAAM,WAAW;CACpC,IAAI,MAAM,eAAe,cAAc,MAAM,cAAc;EACzD,MAAM,IAAI,cAAc,MAAM;EAE9B,IAAI,YAAY,OAAO;GAAE,KAAK,EAAE;GAAM,OAAO,EAAE;GAAO,QAAQ,EAAE;GAAQ,MAAM,EAAE;EAAK;EACrF,OAAO;CACT;CAEA,IAAI,MAAM,eAAe,MAAM;EAC7B,MAAM,IAAI,OAAO,MAAM,WAAW;EAClC,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,GAAG;GAChC,MAAM,MAAM;IAAE,KAAK;IAAG,OAAO;IAAG,QAAQ;IAAG,MAAM;GAAE;GACnD,IAAI,YAAY,OAAO;IAAE,KAAK;IAAG,OAAO;IAAG,QAAQ;IAAG,MAAM;GAAE;GAC9D,OAAO;EACT;CACF;CACA,IAAI,YAAY,OAAO;CACvB,OAAO;AACT;AAEA,SAAgB,qBACd,OACA,SACA,SACmB;CACnB,MAAM,UAAU,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CACzD,MAAM,yBAAS,IAAI,IAAkB;CAErC,KAAK,MAAM,SAAS,MAAM,QAAQ;EAChC,MAAM,eAAe,MAAM,QACxB,KAAK,OAAO,QAAQ,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CACpC,QAAQ,MAAiB,CAAC,CAAC,CAAC;EAC/B,IAAI,CAAC,aAAa,QAAQ;EAE1B,IAAI,OAAO,UACT,OAAO,UACP,OAAO,WACP,OAAO;EACT,KAAK,MAAM,KAAK,cAAc;GAC5B,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;GACzB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;GACzB,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,KAAK;GACnC,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM;EACtC;EAEA,OAAO,IAAI,MAAM,IAAI;GACnB,GAAG,OAAO,QAAQ;GAClB,GAAG,OAAO,QAAQ;GAClB,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ;GAC5C,QAAQ,OAAO,OAAO,QAAQ,MAAM,QAAQ;EAC9C,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAgB,qBAAqB,OAAe,QAAc,UAAU,OAAa;CACvF,MAAM,OAAO,MAAM,YAAY;CAC/B,MAAM,YAAY,wBAAyB;CAC3C,MAAM,YAAY,UAAU,KAAmC;CAC/D,MAAM,QAAQ,KAAK,IACjB,KAAK,IAAI,KAAK,SAAS,YAAY,IAAI,WAAW,EAAE,GACpD,KAAK,IAAI,OAAO,QAAQ,GAAG,EAAE,CAC/B;CAEA,OAAO;EACL,GAAG,OAAO,IAAI;EACd,GAAG,OAAO,IAAI;EACd;EACA,QAAA;CACF;AACF;AAEA,SAAgB,mBAAmB,OAAmB,SAAwC;CAC5F,MAAM,SAAyB,CAAC;CAEhC,KAAK,MAAM,SAAS,MAAM,QAAQ;EAChC,MAAM,UAAU,gBAAgB,KAAK;EAErC,MAAM,SADY,qBAAqB,OAAO,SAAS,OAChC,CAAC,CAAC,IAAI,MAAM,EAAE;EACrC,IAAI,CAAC,QAAQ;EACb,MAAM,UAAU,QAAQ,MAAM,QAAQ,MAAM,SAAS,UAAU,MAAM,WAAW,KAAK;EACrF,OAAO,KAAK;GACV,SAAS,MAAM;GACf;GACA,UAAU,qBAAqB,MAAM,OAAO,QAAQ,OAAO;GAC3D;EACF,CAAC;CACH;CACA,OAAO;AACT;;;;AC9FA,SAAgB,aAAa,WAA+B;CAC1D,OAAO,cAAc,QAAQ,cAAc;AAC7C;;AAGA,SAAgB,WAAW,WAA+B;CACxD,OAAO,cAAc,QAAQ,cAAc;AAC7C;;;ACAA,SAAS,gBAAgB,OAGvB;CACA,MAAM,2BAAW,IAAI,IAAoB;CACzC,MAAM,2BAAW,IAAI,IAAoB;CAEzC,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,SAAS,IAAI,KAAK,IAAI,CAAC;EACvB,SAAS,IAAI,KAAK,IAAI,CAAC;CACzB;CAEA,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,SAAS,IAAI,KAAK,OAAO,SAAS,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC;EAC1D,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,EAAE,KAAK,KAAK,CAAC;CACxD;CAEA,OAAO;EAAE;EAAU;CAAS;AAC9B;AAEA,SAAgB,uBAAuB,OAAmB,WAAuC;CAC/F,MAAM,EAAE,UAAU,aAAa,gBAAgB,KAAK;CAEpD,MAAM,cAAwB,CAAC;CAC/B,MAAM,iCAAiB,IAAI,IAAY;CACvC,KAAK,MAAM,QAAQ,MAAM,OACvB,IAAI,KAAK,SAAS,aAAa,SAAS,IAAI,KAAK,EAAE,KAAK,MAAM,GAAG;EAC/D,YAAY,KAAK,KAAK,EAAE;EACxB,eAAe,IAAI,KAAK,EAAE;CAC5B;CAGF,MAAM,aAAuB,CAAC;CAC9B,MAAM,cAAwB,CAAC;CAC/B,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,KAAK,SAAS,IAAI,KAAK,EAAE,KAAK,MAAM,GAAG,WAAW,KAAK,KAAK,EAAE;EAC9D,KAAK,SAAS,IAAI,KAAK,EAAE,KAAK,MAAM,GAAG,YAAY,KAAK,KAAK,EAAE;CACjE;CAIA,OAAO;EACL;EACA,cAJmB,WAAW,SAAS,KAAK,YAAY,SAAS;EAKjE;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAgB,cAAc,UAA2B,QAAwB;CAC/E,OAAO,SAAS,SAAS,IAAI,MAAM,KAAK;AAC1C;AAEA,SAAgB,cAAc,UAA2B,QAAwB;CAC/E,OAAO,SAAS,SAAS,IAAI,MAAM,KAAK;AAC1C;AAEA,SAAgB,eAAe,UAA2B,QAAyB;CACjF,OAAO,SAAS,eAAe,IAAI,MAAM;AAC3C;;;ACzEA,SAAgB,gBAAgB,MAA4D;CAC1F,OAAO,KAAK,UAAU,eAAe,KAAK,KAAK;AACjD;;;;;AAMA,SAAgB,0BAA0B,MAAyC;CACjF,MAAM,MAAM,gBAAgB,IAAI;CAChC,IAAI,eAAe;CACnB,IAAI,YAAY;CAEhB,IAAI,KAAK,SAAS,aAAa,QAAQ,MAAM;EAC3C,eAAe;EACf,YAAY;CACd,OAAO,IAAI,QAAQ,OAAO;EACxB,eAAe;EACf,YAAY;CACd,OAAO,IAAI,CAAC,KAAK,OAAO;EAEtB,eAAe;EACf,YAAY;CACd;CAEA,IAAI,KAAK,aAAa,QAAQ;EAC5B,gBAAgB;EAChB,aAAa;CACf,OAAO,IAAI,KAAK,aAAa,OAAO;EAClC,eAAe,KAAK,IAAI,GAAG,eAAe,CAAC;EAC3C,IAAI,QAAQ,QAAQ,KAAK,SAAS,WAChC,YAAY,KAAK,IAAI,GAAG,YAAY,CAAC;CAEzC;CAEA,OAAO;EACL,qCAAqC,OAAO,YAAY;EACxD,kCAAkC,OAAO,SAAS;CACpD;AACF;;;ACAA,SAAgB,aAAa,WAAmC;CAC9D,QAAQ,WAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAgB,cAAc,WAAmC;CAC/D,QAAQ,WAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,kBAAkB,MAAqC;CAC9D,QAAQ,MAAR;EACE,KAAK,SACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,QACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAgB,UAAU,QAAgB,QAAwB;CAChE,OAAO,GAAG,OAAO,OAAO;AAC1B;AAEA,SAAgB,SAAS,QAAgB,QAAwB;CAC/D,OAAO,GAAG,OAAO,MAAM;AACzB;;AAGA,SAAgB,iBACd,IACA,MACA,OACA,OACA,SACA,OACA,QACS;CACT,MAAM,WAAW,qBAAqB,iBAAiB,OAAO,CAAC;CAC/D,MAAM,QAAQ;EAAE,GAAG;EAAG,GAAG;EAAG;EAAO;CAAO;CAC1C,MAAM,MAAM,SAAS,gBACnB;EAAE,MAAM;EAAQ,MAAM,kBAAkB,IAAI;EAAG;EAAO;CAAM,GAC5D,KACF;CACA,OAAO;EACL;EACA,GAAG,IAAI,IAAI;EACX,GAAG,IAAI,IAAI;EACX,OAAO;EACP,QAAQ;EACR,eAAe;GACb,iBAAiB;GACjB,kBAAkB,OAAO,KAAK;EAChC;CACF;AACF;AAEA,SAAS,QAAQ,MAAyB;CACxC,MAAM,MAAM,gBAAgB,IAAI;CAChC,IAAI,QAAQ,OAAO,OAAO;CAC1B,IAAI,QAAQ,MAAM,OAAO;CACzB,OAAO;AACT;;;;;AAMA,SAAgB,cAAc,OAAgC;CAC5D,MAAM,sBAAM,IAAI,IAAY;CAC5B,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,IAAI,KAAK,SAAS,KAAK,IAAI;EAI3B,IAHmB,MAAM,MAAM,MAC5B,MAAM,EAAE,OAAO,KAAK,MAAM,EAAE,SAAS,KAAK,MAAM,EAAE,OAAO,KAAK,IAEpD,GAAG,IAAI,IAAI,KAAK,EAAE;CACjC;CACA,OAAO;AACT;AAEA,SAAS,qBACP,OACA,SACA,OACA,QACW;CACX,MAAM,yBAAS,IAAI,IAA6B;CAChD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC;EACvC,KAAK,KAAK,IAAI;EACd,OAAO,IAAI,KAAK,MAAM,IAAI;CAC5B;CACA,MAAM,QAAmB,CAAC;CAC1B,KAAK,MAAM,CAAC,MAAM,SAAS,QAAQ;EACjC,KAAK,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,cAAc,EAAE,MAAM,CAAC;EACvE,MAAM,QAAQ,KAAK;EACnB,KAAK,SAAS,MAAM,UAAU;GAC5B,MAAM,KAAK,iBAAiB,KAAK,IAAI,MAAM,OAAO,OAAO,SAAS,OAAO,MAAM,CAAC;EAClF,CAAC;CACH;CACA,OAAO;AACT;;;;;AAMA,SAAgB,gBACd,OACA,UACA,WACoB;CACpB,MAAM,aAAa,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC7D,MAAM,cAAc,IAAI,IAAI,MAAM,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;CACnE,MAAM,OAAO,aAAa,SAAS;CACnC,MAAM,QAAQ,cAAc,SAAS;CACrC,MAAM,SAAS,cAAc,KAAK;CAElC,MAAM,iCAAiB,IAAI,IAAwB;CACnD,MAAM,gCAAgB,IAAI,IAAwB;CAClD,MAAM,iCAAiB,IAAI,IAAoB;CAC/C,MAAM,iCAAiB,IAAI,IAAoB;CAE/C,MAAM,QAAQ,KAA8B,QAAgB,SAAmB;EAC7E,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK,CAAC;EACjC,KAAK,KAAK,IAAI;EACd,IAAI,IAAI,QAAQ,IAAI;CACtB;CAEA,KAAK,MAAM,QAAQ,MAAM,OAAO;EAE9B,IAAI,OAAO,IAAI,KAAK,EAAE,GAAG;EAEzB,MAAM,WAAW,UAAU,KAAK,MAAM,KAAK,EAAE;EAC7C,MAAM,WAAW,SAAS,KAAK,IAAI,KAAK,EAAE;EAC1C,eAAe,IAAI,KAAK,IAAI,QAAQ;EACpC,eAAe,IAAI,KAAK,IAAI,QAAQ;EAEpC,KAAK,gBAAgB,KAAK,MAAM;GAC9B,IAAI;GACJ,QAAQ,KAAK;GACb,MAAM;GACN,MAAM,QAAQ,IAAI;EACpB,CAAC;EACD,KAAK,eAAe,KAAK,IAAI;GAC3B,IAAI;GACJ,QAAQ,KAAK;GACb,MAAM;GACN,MAAM;EACR,CAAC;CACH;CAEA,MAAM,8BAAc,IAAI,IAAuB;CAC/C,MAAM,8BAAc,IAAI,IAAY;CAEpC,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,MAAM,IAAI,WAAW,IAAI,KAAK,EAAE;EAChC,IAAI,CAAC,GAAG;EACR,MAAM,OAAO,eAAe,IAAI,KAAK,EAAE,KAAK,CAAC;EAC7C,MAAM,OAAO,cAAc,IAAI,KAAK,EAAE,KAAK,CAAC;EAC5C,IAAI,CAAC,KAAK,UAAU,CAAC,KAAK,QAAQ;EAClC,YAAY,IAAI,KAAK,EAAE;EACvB,MAAM,UAAU,YAAY,IAAI,KAAK,EAAE;EACvC,YAAY,IAAI,KAAK,IAAI,CACvB,GAAG,qBAAqB,MAAM,SAAS,EAAE,OAAO,EAAE,MAAM,GACxD,GAAG,qBAAqB,MAAM,SAAS,EAAE,OAAO,EAAE,MAAM,CAC1D,CAAC;CACH;CAEA,OAAO;EAAE;EAAa;EAAgB;EAAgB;CAAY;AACpE;;;ACzOA,MAAM,eAAe;;;;;AASrB,SAAgB,uBAAuB,QAAiB,MAAM,cAAuB;CACnF,IAAI,OAAO,SAAS,GAAG,OAAO;CAC9B,MAAM,MAAe,CAAC,OAAO,EAAG;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;EAC1C,MAAM,IAAI,IAAI,IAAI,SAAS;EAC3B,MAAM,IAAI,OAAO;EACjB,MAAM,IAAI,OAAO,IAAI;EACrB,MAAM,WAAW,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;EACpE,MAAM,aAAa,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;EACtE,IAAI,YAAY,YAAY;EAC5B,IAAI,KAAK,CAAC;CACZ;CACA,IAAI,KAAK,OAAO,OAAO,SAAS,EAAG;CACnC,OAAO;AACT;AAEA,SAASA,gBAAc,IAAY,IAAY,IAAY,IAAqB;CAC9E,OAAO,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE;AACpF;;AAGA,SAAS,gBAAgB,KAAc,UAAkB,MAAiB,OAAqB;CAC7F,MAAM,IAAI;CACV,MAAM,OAAO,IAAI,SAAS;CAC1B,IAAI,IAAI,GAAG,IAAI,EAAE,CAAE,QAAQ;CAC3B,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,EAAE,CAAE,QAAQ;AACxC;;;;;;AAOA,SAAgB,yBAAyB,QAAiB,OAAe,KAAsB;CAC7F,IAAI,OAAO,SAAS,KAAK,MAAM,WAAW,KAAK,OAAO,GAAG,OAAO;CAChE,MAAM,MAAM,OAAO,KAAK,OAAO;EAAE,GAAG,EAAE;EAAG,GAAG,EAAE;CAAE,EAAE;CAGlD,KAAK,IAAI,OAAO,GAAG,OAAO,GAAG,QAAQ;EACnC,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,SAAS,GAAG,KAAK;GAEvC,IAAI,MAAM,KAAK,MAAM,IAAI,SAAS,GAAG;GACrC,MAAM,IAAI,IAAI;GACd,MAAM,IAAI,IAAI,IAAI;GAClB,MAAM,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;GACnC,MAAM,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;GACnC,IAAI,CAAC,QAAQ,CAAC,MAAM;GAEpB,KAAK,MAAM,OAAO,OAAO;IACvB,MAAM,IAAI,IAAI;IACd,MAAM,IAAI,IAAI,IAAI,IAAI;IACtB,MAAM,IAAI,IAAI;IACd,MAAM,IAAI,IAAI,IAAI,IAAI;IAEtB,IAAI,MAAM;KACR,MAAM,KAAK,EAAE,IAAI,EAAE,KAAK;KACxB,IAAI,CAACA,gBAAc,EAAE,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI,GAAG,GAAG;KAChD,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG;MACxB,gBAAgB,KAAK,GAAG,KAAK,IAAI,GAAG;MACpC,QAAQ;KACV,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK;MAC/B,gBAAgB,KAAK,GAAG,KAAK,IAAI,GAAG;MACpC,QAAQ;KACV;IACF,OAAO;KACL,MAAM,KAAK,EAAE,IAAI,EAAE,KAAK;KACxB,IAAI,CAACA,gBAAc,EAAE,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI,GAAG,GAAG;KAChD,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG;MACxB,gBAAgB,KAAK,GAAG,KAAK,IAAI,GAAG;MACpC,QAAQ;KACV,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK;MAC/B,gBAAgB,KAAK,GAAG,KAAK,IAAI,GAAG;MACpC,QAAQ;KACV;IACF;GACF;EACF;EACA,IAAI,CAAC,OAAO;CACd;CAEA,OAAO;AACT;;;;;AAMA,SAAgB,uBAAuB,QAAiB,MAAM,cAAuB;CACnF,IAAI,OAAO,SAAS,GAAG,OAAO;CAC9B,MAAM,MAAe,CAAC,EAAE,GAAG,OAAO,GAAI,CAAC;CACvC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,OAAO,IAAI,IAAI,SAAS;EAC9B,MAAM,OAAO,OAAO;EACpB,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC;EACnC,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC;EACnC,IAAI,KAAK,OAAO,KAAK,KAAK;GAExB,MAAM,SAAS,IAAI,UAAU,IAAI,IAAI,IAAI,SAAS,KAAM;GACxD,MAAM,iBAAiB,UAAU,OAAO,KAAK,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,MAAM,MAAM;GAClF,IAAI,KAAK,iBAAiB;IAAE,GAAG,KAAK;IAAG,GAAG,KAAK;GAAE,IAAI;IAAE,GAAG,KAAK;IAAG,GAAG,KAAK;GAAE,CAAC;EAC/E;EACA,IAAI,KAAK,EAAE,GAAG,KAAK,CAAC;CACtB;CACA,OAAO,uBAAuB,KAAK,GAAG;AACxC;;AAGA,SAAgB,gBACd,OACA,QAAgB,CAAC,GACjB,oBAAA,IACkB;CAClB,MAAM,MAAM,KAAK,IAAA,IAA6B,iBAAiB;CAC/D,OAAO,MAAM,KAAK,UAAU;EAC1B,GAAG;EACH,QAAQ,uBACN,uBAAuB,yBAAyB,KAAK,QAAQ,OAAO,GAAG,CAAC,CAC1E;CACF,EAAE;AACJ;;;;ACzHA,MAAM,yBAAyB;AAE/B,MAAM,qBAGF;CACF,UAAU;CACV,UAAU;CACV,OAAO;AACT;AACA,MAAM,uBAAuB;AAE7B,SAAS,aAAa,WAA8B;CAClD,QAAQ,WAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,MACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,QAAQ,SAAgC;CAC/C,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,QAAQ,QAAQ,gBAAgB;CACtC,MAAM,MAAM,YAAY,YAAY,YAAY;CAChD,OAAO,KAAK,MAAM,MAAM,KAAK;AAC/B;AAEA,SAAS,eAAe,WAA8B;CACpD,OAAO,cAAc,QAAQ,cAAc,OAAO,SAAS;AAC7D;;AAGA,SAAgB,eAAe,KAAqB;CAClD,MAAM,QAAQ,IAAI,QAAQ,GAAG;CAC7B,IAAI,SAAS,GAAG,OAAO;CACvB,OAAO,IAAI,MAAM,GAAG,KAAK;AAC3B;;;;;;;;;AAUA,SAAgB,cACd,OACA,UACA,SACU;CACV,MAAM,aAAa,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC7D,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,WAAW,QAAQ,YAAA;CACzB,MAAM,YAAY,QAAQ,aAAa;CAEvC,MAAM,WAAW,KAAK,IAAA,IAEpB,QAAQ,mBAAmB,KAAK,MAAM,MAAM,EAAG,CACjD;CACA,MAAM,WAAW,KAAK,IAAI,IAAI,QAAQ,mBAAmB,KAAK,IAAI,IAAI,KAAK,MAAM,MAAM,GAAI,CAAC,CAAC;CAG7F,MAAM,WAAW,QAAQ,YAAY,OAAO,WAAW;CACvD,MAAM,WAAW,QAAQ,YAAY,OAAO,KAAK,MAAM,WAAW,EAAG,IAAI;CACzE,MAAM,gBACJ,mBAAmB,QAAQ,iBAAiB,2BAC5C,mBAAmB;CAErB,MAAM,WAAW,uBAAuB,OAAO,SAAS;CACxD,MAAM,iBAAiB,gBAAgB,OAAO,UAAU,SAAS;CAEjE,MAAM,eAAe,MAAM,OAAO,QAAQ,MAAM,EAAE,SAAS,cAAc,EAAE,YAAY,IAAI;CAC3F,MAAM,gBAAgB,QAAQ,gBAAgB,cAAc,aAAa,SAAS;CAGlF,MAAM,iBACJ,QAAQ,gBAAgB,UAAW,iBAAiB,QAAQ,gBAAgB;CAC9E,MAAM,YAAY,iBAAiB,sBAAsB;CAEzD,MAAM,oCAAoB,IAAI,IAAoB;CAClD,aAAa,SAAS,GAAG,MAAM;EAC7B,KAAK,MAAM,UAAU,EAAE,SAAS,kBAAkB,IAAI,QAAQ,CAAC;EAC/D,MAAM,QAAQ,CAAC,GAAG,EAAE,aAAa;EACjC,OAAO,MAAM,QAAQ;GACnB,MAAM,MAAM,MAAM,IAAI;GACtB,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG;GACnD,IAAI,CAAC,OAAO;GACZ,KAAK,MAAM,UAAU,MAAM,SAAS,kBAAkB,IAAI,QAAQ,CAAC;GACnE,MAAM,KAAK,GAAG,MAAM,aAAa;EACnC;CACF,CAAC;CACD,MAAM,mBAAmB,aAAa;CAEtC,MAAM,WAAW,SAAS;CAC1B,MAAM,WAAW,SAAS;CAE1B,MAAM,oBAA4C;EAChD,iBAAiB;EACjB,iBAAiB,aAAa,SAAS;EACvC,mBAAmB;EACnB,yBAAyB;EACzB,mBAAmB,eAAe,SAAS;EAC3C,4BAA4B,OAAO,oBAAoB;EACvD,6CAA6C;EAC7C,sCAAsC;EACtC,kDAAkD;EAClD,gDAAgD;EAChD,kDAAkD;EAElD,qCAAqC;EAGrC,6BAA6B;EAC7B,2CACE,QAAQ,uBAAuB,QAAQ,SAAS;EAGlD,eAAe;EACf,wBAAwB,OAAO,QAAQ;EACvC,6CAA6C,OAAO,QAAQ;EAC5D,wBAAwB,OAAO,QAAQ;EACvC,6CAA6C,OAAO,QAAQ;EAC5D,wBAAwB,OAAO,QAAQ;EACvC,6CAA6C,OAAO,QAAQ;EAC5D,kCAAkC,OAAO,QAAQ;CACnD;CAEA,IAAI,eACF,kBAAkB,+BAA+B;CAQnD,IALwB,MAAM,MAAM,MAAM,MAAM;EAG9C,OAFU,MAAM,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,YAC1C,MAAM,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE;CAEpD,CACkB,KAAK,CAAC,gBACtB,kBAAkB,qCAAqC;CAGzD,MAAM,iCAAiB,IAAI,IAA6C;CACxE,KAAK,MAAM,KAAK,MAAM,QAAQ;EAE5B,IAAI,gBAAgB;EACpB,MAAM,MAAM,EAAE;EACd,MAAM,OAAO,eAAe,IAAI,GAAG,KAAK,CAAC;EACzC,KAAK,KAAK,CAAC;EACX,eAAe,IAAI,KAAK,IAAI;CAC9B;CAEA,MAAM,gCAAgB,IAAI,IAAY;CAEtC,MAAM,qBAAqB,WAA2C;EACpE,MAAM,OAA+B,CAAC;EACtC,MAAM,MAAM,SAAS,IAAI,MAAM,KAAK;EACpC,MAAM,MAAM,SAAS,IAAI,MAAM,KAAK;EACpC,IAAI,QAAQ,KAAK,MAAM,GAAG,KAAK,0CAA0C;EACzE,IAAI,QAAQ,KAAK,MAAM,GAAG,KAAK,0CAA0C;EACzE,IAAI,eAAe,YAAY,IAAI,MAAM,GAAG,KAAK,yBAAyB;EAC1E,IAAI,eACF,KAAK,gCAAgC,OACnC,kBAAkB,IAAI,MAAM,KAAK,gBACnC;EAEF,OAAO;CACT;CAEA,MAAM,aAAa,QAAgB,MAA6B;EAC9D,MAAM,gBAAgB,kBAAkB,MAAM;EAC9C,MAAM,QAAQ,eAAe,YAAY,IAAI,MAAM;EACnD,OAAO;GACL,IAAI;GACJ,OAAO,EAAE;GACT,QAAQ,EAAE;GACV,GAAI,OAAO,KAAK,aAAa,CAAC,CAAC,SAAS,EAAE,cAAc,IAAI,CAAC;GAC7D,GAAI,OAAO,SAAS,EAAE,MAAM,IAAI,CAAC;EACnC;CACF;CAEA,MAAM,kBAAkB,YAA6B;EACnD,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,OAAO;EACvD,MAAM,MAAM,gBAAgB,KAAK;EACjC,MAAM,WAAsB,CAAC;EAE7B,KAAK,MAAM,UAAU,MAAM,SAAS;GAClC,MAAM,IAAI,WAAW,IAAI,MAAM;GAC/B,IAAI,CAAC,GAAG;GACR,cAAc,IAAI,MAAM;GACxB,SAAS,KAAK,UAAU,QAAQ,CAAC,CAAC;EACpC;EAEA,KAAK,MAAM,SAAS,eAAe,IAAI,OAAO,KAAK,CAAC,GAClD,SAAS,KAAK,eAAe,MAAM,EAAE,CAAC;EAGxC,OAAO;GACL,IAAI,SAAS,MAAM;GACnB;GACA,QAAQ,MAAM,QACV,CAAC;IAAE,IAAI,SAAS,MAAM,GAAG;IAAS,MAAM,MAAM;IAAO,OAAO;IAAI,QAAQ;GAAG,CAAC,IAC5E,KAAA;GACJ,eAAe;IACb,eAAe,QAAQ,IAAI,IAAI,QAAQ,IAAI,KAAK,UAAU,IAAI,OAAO,SAAS,IAAI,MAAM;IACxF,wBAAwB,OAAO,KAAK,MAAM,MAAM,EAAG,CAAC;IACpD,6CAA6C,OAAO,KAAK,MAAM,MAAM,EAAG,CAAC;IACzE,sCAAsC;IACtC,gDAAgD;IAChD,wBAAwB;GAC1B;EACF;CACF;CAEA,MAAM,WAAsB,CAAC;CAE7B,KAAK,MAAM,OAAO,eAAe,IAAI,KAAA,CAAS,KAAK,CAAC,GAClD,SAAS,KAAK,eAAe,IAAI,EAAE,CAAC;CAGtC,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,IAAI,cAAc,IAAI,KAAK,EAAE,GAAG;EAChC,MAAM,IAAI,WAAW,IAAI,KAAK,EAAE;EAChC,IAAI,CAAC,GAAG;EACR,SAAS,KAAK,UAAU,KAAK,IAAI,CAAC,CAAC;CACrC;CAEA,MAAM,aAAa,SACjB,eAAe,eAAe,IAAI,KAAK,EAAE,KAAK,KAAK;CAErD,MAAM,aAAa,SACjB,eAAe,eAAe,IAAI,KAAK,EAAE,KAAK,KAAK;CASrD,OAAO;EACL,IAAI;EACJ,eAAe;EACf;EACA,OAXY,MAAM,MAAM,KAAK,OAAO;GACpC,IAAI,EAAE;GACN,SAAS,CAAC,UAAU,CAAC,CAAC;GACtB,SAAS,CAAC,UAAU,CAAC,CAAC;GACtB,eAAe,0BAA0B,CAAC;EAC5C,EAMM;CACN;AACF;;;;AC3MA,MAAM,UAAU;AAEhB,IAAI,SAA8C;AAElD,SAAgB,SAAuC;CACrD,IAAI,CAAC,QACH,SAAS,IAAI,QAAQ,EACnB,sBAAsB;EACpB,iBAAiB;EACjB,mBAAmB;EACnB,yBAAyB;CAC3B,EACF,CAAC;CAEH,OAAO;AACT;AAEA,MAAa,uBAAuB;AACpC,MAAa,uBAAuB;;;AC9DpC,MAAMC,QAAM;AAEZ,SAAS,OAAO,MAAa,IAAiB;CAC5C,OAAO;EAAE,GAAG,GAAG,IAAI,KAAK;EAAG,GAAG,GAAG,IAAI,KAAK;CAAE;AAC9C;AAEA,SAASC,WAAS,QAAwE;CACxF,OAAO;EAAE,GAAG,OAAO,IAAI,OAAO,QAAQ;EAAG,GAAG,OAAO,IAAI,OAAO,SAAS;CAAE;AAC3E;;AAGA,SAAS,eAAe,GAAe;CACrC,IAAI,KAAK,IAAI,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,OAAO;EAAE,GAAG,KAAK,KAAK,EAAE,CAAC,KAAK;EAAG,GAAG;CAAE;CAC1E,OAAO;EAAE,GAAG;EAAG,GAAG,KAAK,KAAK,EAAE,CAAC,KAAK;CAAE;AACxC;AAEA,SAAS,YAAY,GAAU,GAAmB;CAChD,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAID,SAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAIA;AAC5D;AAEA,SAAS,iBAAiB,QAAiB,UAAkB,KAAY,WAAuB;CAE9F,MAAM,SAAS,OADA,aAAa,IAAI,IAAI,WAAW;CAE/C,IAAI,YAAY,QAAQ,GAAG,GAAG;EAC5B,OAAO,YAAY;EACnB;CACF;CAEA,MAAM,SACJ,KAAK,IAAI,UAAU,CAAC,KAAK,KAAK,IAAI,UAAU,CAAC,IACzC;EAAE,GAAG,OAAO;EAAG,GAAG,IAAI;CAAE,IACxB;EAAE,GAAG,IAAI;EAAG,GAAG,OAAO;CAAE;CAC9B,OAAO,YAAY;CACnB,IAAI,aAAa,GAAG,OAAO,OAAO,GAAG,GAAG,MAAM;MACzC,OAAO,OAAO,UAAU,GAAG,MAAM;AACxC;;AAGA,SAAS,oBACP,QACA,QACM;CACN,MAAM,IAAI,OAAO;CACjB,MAAM,IAAI,OAAO,IAAI,OAAO;CAC5B,MAAM,IAAI,OAAO;CACjB,MAAM,IAAI,OAAO,IAAI,OAAO;CAC5B,MAAM,MAAM,OAAO,KAAK,IAAIA,SAAO,OAAO,KAAK,IAAIA;CACnD,MAAM,MAAM,OAAO,KAAK,IAAIA,SAAO,OAAO,KAAK,IAAIA;CACnD,IAAI,OAAO,IAAI,KAAK,KAAK,OAAO;EAAE,GAAG;EAAG,GAAG;CAAE;CAC7C,IAAI,OAAO,IAAI,KAAK,KAAK,OAAO;EAAE,GAAG;EAAG,GAAG;CAAG;CAC9C,IAAI,OAAO,IAAI,KAAK,KAAK,OAAO;EAAE,GAAG;EAAG,GAAG;CAAE;CAC7C,IAAI,OAAO,IAAI,KAAK,KAAK,OAAO;EAAE,GAAG;EAAI,GAAG;CAAE;CAC9C,OAAO,eAAe,OAAO,QAAQC,WAAS,MAAM,CAAC,CAAC;AACxD;;;;;;AAOA,SAAgB,4BACd,OACA,OACA,WACkB;CAClB,MAAM,UAAU,IAAI,IAAI,MAAM,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CACvD,MAAM,aAAa,IAAI,IAAI,MAAM,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;CAE5D,OAAO,UAAU,KAAK,SAAS;EAC7B,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM,EAAE,OAAO,KAAK,MAAM;EACzD,IAAI,CAAC,QAAQ,KAAK,OAAO,SAAS,GAAG,OAAO;EAC5C,IAAI,KAAK,cAAc,KAAK,UAAU,OAAO;EAE7C,MAAM,SAAS,KAAK,OAAO,KAAK,OAAO;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE,EAAE;EAC1D,MAAM,WAAW,QAAQ,IAAI,KAAK,IAAI;EACtC,MAAM,SAAS,QAAQ,IAAI,KAAK,EAAE;EAClC,MAAM,WAAW,WAAW,IAAI,KAAK,IAAI;EACzC,MAAM,SAAS,WAAW,IAAI,KAAK,EAAE;EAErC,IAAI,YAAY,UAAU;GACxB,MAAM,KAAK,OAAO;GAClB,MAAM,YAAY,oBAAoB,IAAI,SAAS,MAAM;GAOzD,iBAAiB,QAAQ,GANb,uBAAuB;IACjC,SAAS,SAAS;IAClB,QAAQ,SAAS;IACjB,QAAQ;IACR;GACF,CAC8B,GAAG,SAAS;EAC5C;EAEA,IAAI,UAAU,QAAQ;GACpB,MAAM,OAAO,OAAO,OAAO,SAAS;GACpC,MAAM,YAAY,oBAAoB,MAAM,OAAO,MAAM;GACzD,MAAM,MAAM,uBAAuB;IACjC,SAAS,OAAO;IAChB,QAAQ,OAAO;IACf,QAAQ;IACR;GACF,CAAC;GACD,iBAAiB,QAAQ,OAAO,SAAS,GAAG,KAAK,SAAS;EAC5D;EAEA,OAAO;GAAE,GAAG;GAAM;EAAO;CAC3B,CAAC;AACH;;;ACzFA,MAAM,cAAsC;CAC1C,SAAS,YAAY;CACrB,QAAQ,YAAY;CACpB,UAAU,YAAY;AACxB;AAEA,SAAgB,kBAAkB,KAA0C;CAC1E,IAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG,GAAG,OAAO,KAAK,IAAI,GAAG,GAAG;CAC3E,IAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,MAAM,OAAO,YAAY;CAC5E,OAAA;AACF;AAEA,SAAS,WAAW,MAA6B,UAA0B;CACzE,IAAI,OAAO,SAAS,UAAU,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC;CACjE,IAAI,MAAM,QAAQ,IAAI,GAAG,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM;CACvD,OAAO,KAAK,IAAI,GAAG,QAAQ;AAC7B;AAEA,SAAS,kBACP,KACA,MACA,eACA,OACQ;CACR,IAAI,OAAO,QAAQ,YAAY,OAAO,GACpC,OAAO,KAAK,IAAI,QAAQ,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC;CAE7D,IAAI,OAAO,QAAQ,YAAY,MAAM,QAAQ,IAAI,GAAG;EAClD,MAAM,MAAM,KAAK,QAAQ,GAAG;EAC5B,IAAI,OAAO,GAAG,OAAO;CACvB;CACA,OAAO,KAAK,IAAI,QAAQ,GAAG,KAAK,IAAI,GAAG,aAAa,CAAC;AACvD;AAEA,SAAS,YAAY,OAAoB,MAAsB;CAC7D,IAAI,QAAQ,GAAG,OAAO;CACtB,QAAQ,OAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,UACH,OAAO,OAAO;EAGhB,SACE,OAAO;CACX;AACF;;;;;AAMA,SAAgB,cAAc,OAA6C;CACzE,MAAM,QAAQ,MAAM,SAAS;CAC7B,MAAM,MAAM,kBAAkB,MAAM,GAAG;CACvC,MAAM,UAAU,MAAM,QAAQ,KAAK;CACnC,MAAM,UAAU,MAAM,QAAQ,KAAK;CACnC,MAAM,QAAQ,MAAM;CACpB,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC;CAEhC,IAAI,MAAM,YAAY,SACpB,OAAO,aAAa,OAAO,OAAO,KAAK,SAAS,OAAO;CAEzD,IAAI,MAAM,YAAY,OACpB,OAAO,WAAW,OAAO,OAAO,KAAK,SAAS,OAAO;CAEvD,OAAO,YAAY,OAAO,OAAO,KAAK,SAAS,OAAO;AACxD;AAEA,SAAS,aACP,OACA,OACA,KACA,SACA,SACkB;CAClB,MAAM,OAAO,KAAK,IAAI,GAAG,MAAM,KAAK,MAAM,EAAE,KAAK,GAAG,CAAC;CACrD,IAAI,IAAI;CACR,MAAM,MAAwB,CAAC;CAC/B,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,UAAU,YAAY,OAAO,KAAK;EAChD,MAAM,IAAI,UAAU,YAAY,OAAO,OAAO,KAAK;EACnD,IAAI,KAAK;GACP,SAAS,KAAK;GACd,QAAQ;IAAE;IAAG;IAAG;IAAO,QAAQ,KAAK;GAAO;EAC7C,CAAC;EACD,KAAK,KAAK,SAAS;CACrB;CACA,OAAO;AACT;AAEA,SAAS,WACP,OACA,OACA,KACA,SACA,SACkB;CAClB,MAAM,OAAO,KAAK,IAAI,GAAG,MAAM,KAAK,MAAM,EAAE,MAAM,GAAG,CAAC;CACtD,IAAI,IAAI;CACR,MAAM,MAAwB,CAAC;CAC/B,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,SAAS,UAAU,YAAY,OAAO,KAAK;EACjD,MAAM,IAAI,UAAU,YAAY,OAAO,OAAO,MAAM;EACpD,IAAI,KAAK;GACP,SAAS,KAAK;GACd,QAAQ;IAAE;IAAG;IAAG,OAAO,KAAK;IAAO;GAAO;EAC5C,CAAC;EACD,KAAK,KAAK,QAAQ;CACpB;CACA,OAAO;AACT;AAEA,SAAS,YACP,OACA,OACA,KACA,SACA,SACkB;CAClB,MAAM,QAAQ,MAAM;CAEpB,IAAI,UAAU;CACd,IAAI,UAAU;CACd,MAAM,eAAe,WAAW,MAAM,SAAS,CAAC;CAChD,MAAM,aAAa,MAAM,KAAK,SAAS;EACrC,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,WAAW,CAAC;EAC7C,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,WAAW,CAAC;EAC7C,IAAI,MAAM,kBAAkB,KAAK,QAAQ,MAAM,SAAS,SAAS,YAAY;EAC7E,IAAI,MAAM,kBAAkB,KAAK,KAAK,MAAM,MAAM,SAAS,WAAW,MAAM,MAAM,CAAC,CAAC;EACpF,IAAI,KAAK,UAAU,QAAQ,KAAK,OAAO,MAAM;GAC3C,MAAM;GACN,MAAM;GACN,WAAW;GACX,IAAI,WAAW,cAAc;IAC3B,UAAU;IACV,WAAW;GACb;EACF;EACA,OAAO;GAAE;GAAM;GAAK;GAAK;GAAS;EAAQ;CAC5C,CAAC;CAED,MAAM,SAAS,KAAK,IAAI,cAAc,GAAG,WAAW,KAAK,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC;CACjF,MAAM,SAAS,KAAK,IAAI,WAAW,MAAM,MAAM,CAAC,GAAG,GAAG,WAAW,KAAK,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC;CAE9F,MAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,OAAO,SAAS,CAAC;CACxD,MAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,OAAO,SAAS,CAAC;CACzD,KAAK,MAAM,KAAK,YAAY;EAC1B,MAAM,SAAS,EAAE,KAAK,QAAQ,EAAE;EAChC,MAAM,SAAS,EAAE,KAAK,SAAS,EAAE;EACjC,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE,SAAS,KACzC,UAAU,KAAK,KAAK,IAAI,UAAU,IAAK,MAAM;EAE/C,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE,SAAS,KACzC,WAAW,KAAK,KAAK,IAAI,WAAW,IAAK,MAAM;CAEnD;CAEA,MAAM,OAAiB,CAAC;CACxB,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;EAC/B,KAAK,KAAK,CAAC;EACX,KAAK,UAAU,MAAO,IAAI,SAAS,IAAI,MAAM;CAC/C;CACA,MAAM,OAAiB,CAAC;CACxB,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;EAC/B,KAAK,KAAK,CAAC;EACX,KAAK,WAAW,MAAO,IAAI,SAAS,IAAI,MAAM;CAChD;CAEA,OAAO,WAAW,KAAK,MAAM;EAC3B,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE,SAAS,KAAK;GAC9C,SAAS,UAAU;GACnB,IAAI,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS;EAC1C;EACA,IAAI,SAAS;EACb,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE,SAAS,KAAK;GAC9C,UAAU,WAAW;GACrB,IAAI,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU;EAC3C;EACA,MAAM,QAAQ,UAAU,YAAY,QAAQ,EAAE,KAAK;EACnD,MAAM,QAAQ,UAAU,YAAY,SAAS,EAAE,KAAK;EACpD,MAAM,KAAK,YAAY,OAAO,QAAQ,KAAK;EAC3C,MAAM,KAAK,YAAY,OAAO,SAAS,KAAK;EAC5C,OAAO;GACL,SAAS,EAAE,KAAK;GAChB,QAAQ;IACN,GAAG,KAAK,EAAE,OAAQ;IAClB,GAAG,KAAK,EAAE,OAAQ;IAClB,OAAO;IACP,QAAQ;GACV;EACF;CACF,CAAC;AACH;;AAGA,SAAgB,sBAAsB,OAA4B;CAChE,OAAO,MAAM,YAAY,WAAW,MAAM,YAAY,SAAS,MAAM,YAAY;AACnF;;;ACtOA,MAAM,MAAM;;AAEZ,MAAM,gBAAgB;AAEtB,SAAS,QAAQ,GAAS,KAAmB;CAC3C,OAAO;EACL,GAAG,EAAE,IAAI;EACT,GAAG,EAAE,IAAI;EACT,OAAO,EAAE,QAAQ,MAAM;EACvB,QAAQ,EAAE,SAAS,MAAM;CAC3B;AACF;AAEA,SAAS,SAAS,GAAgB;CAChC,OAAO;EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ;EAAG,GAAG,EAAE,IAAI,EAAE,SAAS;CAAE;AACvD;;AAGA,SAAgB,gBAAgB,GAAU,GAAU,KAAoB;CACtE,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,IAAI,IAAI;CACd,MAAM,IAAI,IAAI,IAAI,IAAI;CACtB,MAAM,IAAI,IAAI;CACd,MAAM,IAAI,IAAI,IAAI,IAAI;CAEtB,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK;EAC7B,MAAM,IAAI,EAAE;EACZ,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,OAAO;EACzC,OAAO,OAAO,IAAI,OAAO,OAAO,IAAI;CACtC;CACA,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK;EAC7B,MAAM,IAAI,EAAE;EACZ,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,OAAO;EACzC,OAAO,OAAO,IAAI,OAAO,OAAO,IAAI;CACtC;CACA,OAAO;AACT;AAEA,SAAS,cAAc,IAAY,IAAY,IAAY,IAAqB;CAC9E,OAAO,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,EAAE;AACpF;;;;;AAMA,SAAgB,gBACd,GACA,GACA,KACA,WAAW,eACX,iBAAiB,OACR;CACT,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;CAC9B,MAAM,IAAI,IAAI;CACd,MAAM,IAAI,IAAI,IAAI,IAAI;CACtB,MAAM,IAAI,IAAI;CACd,MAAM,IAAI,IAAI,IAAI,IAAI;CACtB,MAAM,MAAM,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC;CAEpD,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK;EAC7B,MAAM,IAAI,EAAE;EACZ,MAAM,YAAY,KAAK,IAAI,IAAI,CAAC,KAAK;EACrC,MAAM,aAAa,KAAK,IAAI,IAAI,CAAC,KAAK;EACtC,IAAI,EAAE,aAAa,aAAa,OAAO;EACvC,IAAI,CAAC,cAAc,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO;EAC7C,IAAI,kBAAkB,OAAO,WAAW,KAAK,OAAO;EAEpD,OADgB,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,IACnC,WAAW;CAC9B;CACA,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK;EAC7B,MAAM,IAAI,EAAE;EACZ,MAAM,WAAW,KAAK,IAAI,IAAI,CAAC,KAAK;EACpC,MAAM,cAAc,KAAK,IAAI,IAAI,CAAC,KAAK;EACvC,IAAI,EAAE,YAAY,cAAc,OAAO;EACvC,IAAI,CAAC,cAAc,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO;EAC7C,IAAI,kBAAkB,OAAO,WAAW,KAAK,OAAO;EAEpD,OADgB,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,MAAM,CAAC,IACnC,WAAW;CAC9B;CACA,OAAO;AACT;AAEA,SAAS,WAAW,QAAyB;CAC3C,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,IAAI,OAAO,IAAI;EACrB,MAAM,IAAI,OAAO;EACjB,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC;CACjD;CACA,OAAO;AACT;AAEA,SAAS,OAAO,QAA0B;CACxC,MAAM,MAAe,CAAC;CACtB,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,OAAO,IAAI,IAAI,SAAS;EAC9B,IAAI,QAAQ,KAAK,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK;EAC1E,IAAI,KAAK,CAAC;CACZ;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAS,iBAAiB,QAA0B;CAClD,IAAI,OAAO,SAAS,GAAG,OAAO;CAC9B,MAAM,MAAe,CAAC,OAAO,EAAG;CAChC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;EAE1C,IADiB,MAAM,KAAK,MAAM,OAAO,SAAS,GACpC;GACZ,IAAI,KAAK,OAAO,EAAG;GACnB;EACF;EACA,MAAM,IAAI,IAAI,IAAI,SAAS;EAC3B,MAAM,IAAI,OAAO;EACjB,MAAM,IAAI,OAAO,IAAI;EACrB,MAAM,WAAW,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;EACpE,MAAM,aAAa,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;EACtE,IAAI,YAAY,YAAY;EAC5B,IAAI,KAAK,CAAC;CACZ;CACA,IAAI,KAAK,OAAO,OAAO,SAAS,EAAG;CACnC,OAAO,OAAO,GAAG;AACnB;AAIA,SAAS,OAAO,GAAS,MAAY,GAAkB;CACrD,MAAM,UAAU,KAAK,IAAI,KAAM,KAAK,IAAI,KAAM,CAAC,CAAC;CAChD,QAAQ,MAAR;EACE,KAAK,KACH,OAAO;GAAE,GAAG,EAAE,IAAI,EAAE,QAAQ;GAAS,GAAG,EAAE;EAAE;EAC9C,KAAK,KACH,OAAO;GAAE,GAAG,EAAE,IAAI,EAAE,QAAQ;GAAS,GAAG,EAAE,IAAI,EAAE;EAAO;EACzD,KAAK,KACH,OAAO;GAAE,GAAG,EAAE,IAAI,EAAE;GAAO,GAAG,EAAE,IAAI,EAAE,SAAS;EAAQ;EACzD,KAAK,KACH,OAAO;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE,IAAI,EAAE,SAAS;EAAQ;CACjD;AACF;;AAGA,SAAS,YAAY,GAAU,GAAsB;CACnD,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,KAAK,OAAO;CACxF,IAAI,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,KACvF,OAAO;CAET,IAAI,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KACvF,OAAO;CAET,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KAAK,OAAO;CACzF,OAAO;AACT;;;;;AAMA,SAAS,sBACP,MACA,IACA,QACA,WACQ;CACR,MAAM,QAAQ,YAAY,OAAO,IAAK,IAAI;CAC1C,MAAM,MAAM,YAAY,OAAO,OAAO,SAAS,IAAK,EAAE;CACtD,IAAI,UAAU;CACd,IAAI,SAAS,UAAU,UAAU,IAAI,WAAW;CAChD,IAAI,OAAO,QAAQ,UAAU,IAAI,WAAW;CAC5C,MAAM,CAAC,IAAI,MAAM;CAEjB,IAAI,OAAO,OAAO,OAAO,OAAO,QAAQ,KAAK,WAAW;CACxD,IAAI,OAAO,OAAO,OAAO,QAAQ,QAAQ,OAAO,QAAQ,MAAM,WAAW;CACzE,IAAI,OAAO,OAAO,OAAO,OAAO,QAAQ,KAAK,WAAW;CACxD,IAAI,OAAO,OAAO,OAAO,OAAO,QAAQ,KAAK,WAAW;CACxD,IAAI,OAAO,OAAO,OAAO,OAAO,QAAQ,KAAK,WAAW;CACxD,OAAO;AACT;;AAGA,SAAS,OAAO,GAAS,MAAY,GAAW,UAAyB;CACvE,MAAM,IAAI,OAAO,GAAG,MAAM,CAAC;CAC3B,QAAQ,MAAR;EACE,KAAK,KACH,OAAO;GAAE,GAAG,EAAE,IAAI;GAAU,GAAG,EAAE;EAAE;EACrC,KAAK,KACH,OAAO;GAAE,GAAG,EAAE,IAAI;GAAU,GAAG,EAAE;EAAE;EACrC,KAAK,KACH,OAAO;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE,IAAI;EAAS;EACrC,KAAK,KACH,OAAO;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE,IAAI;EAAS;CACvC;AACF;AAEA,SAAS,UAAU,MAAY,IAA+B;CAC5D,MAAM,UAAU,kBAAkB,MAAM,EAAE;CAC1C,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,KAAK;CACvC,MAAM,WAAW,KAAK,KAAK,GAAG,IAAI,GAAG;CACrC,MAAM,aAAa,GAAG,KAAK,KAAK,IAAI,KAAK;CACzC,MAAM,aAAa,KAAK,KAAK,GAAG,IAAI,GAAG;CASvC,OAAO;EAAC;EAPN,QAAQ,OAAO,OAAO,QAAQ,OAAO,MACjC,cAAc,aACZ,CAAC,KAAK,GAAG,IACT,CAAC,KAAK,GAAG,IACX,YAAY,WACV,CAAC,KAAK,GAAG,IACT,CAAC,KAAK,GAAG;EACW,CAAC,KAAK,GAAG;EAAG,CAAC,KAAK,GAAG;EAAG,CAAC,KAAK,GAAG;EAAG,CAAC,KAAK,GAAG;CAAC;AAC5E;;AAGA,SAAgB,kBAAkB,MAAY,IAAwB;CACpE,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,KAAK;CACvC,MAAM,WAAW,KAAK,KAAK,GAAG,IAAI,GAAG;CACrC,MAAM,aAAa,GAAG,KAAK,KAAK,IAAI,KAAK;CACzC,MAAM,aAAa,KAAK,KAAK,GAAG,IAAI,GAAG;CACvC,MAAM,SAAS,KAAK,IAAI,UAAU,QAAQ;CAC1C,MAAM,SAAS,KAAK,IAAI,YAAY,UAAU;CAC9C,MAAM,aAAa,SAAS;CAC5B,MAAM,aAAa,SAAS;CAE5B,IAAI,eAAe,CAAC,cAAc,UAAU,SAAS,OAAQ,SAAS,KAGpE,OAAO,YAAY,WAAW,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;CAEtD,IAAI,YACF,OAAO,cAAc,aAAa,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;CAE1D,MAAM,KAAK,SAAS,IAAI;CACxB,MAAM,KAAK,SAAS,EAAE;CACtB,MAAM,KAAK,GAAG,IAAI,GAAG;CACrB,MAAM,KAAK,GAAG,IAAI,GAAG;CACrB,OAAO,KAAK,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,IAC9B,MAAM,IACJ,CAAC,KAAK,GAAG,IACT,CAAC,KAAK,GAAG,IACX,MAAM,IACJ,CAAC,KAAK,GAAG,IACT,CAAC,KAAK,GAAG;AACjB;;AAGA,SAAS,gBAAgB,MAAY,IAAU,IAAU,IAAyB;CAChF,IAAI,OAAO,OAAO,OAAO,KAAK,OAAO,GAAG,KAAK,KAAK,IAAI,KAAK;CAC3D,IAAI,OAAO,OAAO,OAAO,KAAK,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG;CACzD,IAAI,OAAO,OAAO,OAAO,KAAK,OAAO,GAAG,KAAK,KAAK,IAAI,KAAK;CAC3D,IAAI,OAAO,OAAO,OAAO,KAAK,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG;CACzD,OAAO;AACT;;AAGA,SAAS,aAAa,MAAY,IAAU,IAAmB;CAC7D,IAAI,OAAO,OAAO,OAAO,KACvB,OAAO,cAAc,KAAK,GAAG,KAAK,IAAI,KAAK,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK;CAEzE,OAAO,cAAc,KAAK,GAAG,KAAK,IAAI,KAAK,QAAQ,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM;AAC3E;;;;;;AAOA,SAAS,sBACP,MACA,IACA,WACA,KACA,OACA,KACA,MACgB;CAChB,MAAM,CAAC,IAAI,MAAM,UAAU,MAAM,EAAE,CAAC,CAAC;CACrC,MAAM,MAAM,gBAAgB,MAAM,IAAI,IAAI,EAAE;CAC5C,IAAI,OAAO,QAAQ,OAAO,KAAK,OAAO,OAAO,GAAG,OAAO;CACvD,IAAI,CAAC,aAAa,MAAM,IAAI,EAAE,GAAG,OAAO;CAExC,MAAM,UAAU,OAAO,MAAM,IAAI,KAAK;CACtC,MAAM,UAAU,OAAO,IAAI,IAAI,GAAG;CAClC,MAAM,OAAO,MAAM;CACnB,IAAI;CACJ,IAAI,OAAO,OAAO,OAAO,KAAK;EAC5B,MAAM,IAAI,OAAO,MAAM,KAAK,IAAI,KAAK,SAAS,OAAO,KAAK,IAAI;EAC9D,MAAM,CACJ;GAAE,GAAG,QAAQ;GAAG;EAAE,GAClB;GAAE,GAAG,QAAQ;GAAG;EAAE,CACpB;CACF,OAAO;EACL,MAAM,IAAI,OAAO,MAAM,KAAK,IAAI,KAAK,QAAQ,OAAO,KAAK,IAAI;EAC7D,MAAM,CACJ;GAAE;GAAG,GAAG,QAAQ;EAAE,GAClB;GAAE;GAAG,GAAG,QAAQ;EAAE,CACpB;CACF;CAEA,MAAM,SAAS,iBAAiB,OAAO;EAAC;EAAS,GAAG;EAAK;CAAO,CAAC,CAAC;CAElE,MAAM,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,CAAC;CAEzD,IAAI,UAAU,QADG,UAAU,KAAK,MAAM,QAAQ,GAAG,UAAU,CAC9B,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,OAAO;CACxD,OAAO;AACT;AAEA,SAAS,YAAY,UAAkB,KAA4B;CACjE,IAAI,OAAO,QAAQ,OAAO,GAAG,OAAO;CAEpC,OAAO,KAAK,IAAI,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,CAAC;AACpD;AAEA,SAAS,OAAO,GAAU,GAAmB;CAC3C,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC;CACxE,OAAO;EAAC;EAAG;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE;EAAG;CAAC;AAClC;AAEA,SAAS,OAAO,GAAU,GAAmB;CAC3C,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC;CACxE,OAAO;EAAC;EAAG;GAAE,GAAG,EAAE;GAAG,GAAG,EAAE;EAAE;EAAG;CAAC;AAClC;AAEA,SAAS,YAAY,OAA4B;CAC/C,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,IAAI,OAAO,UACT,OAAO,UACP,OAAO,WACP,OAAO;CACT,KAAK,MAAM,KAAK,OAAO;EACrB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,KAAK;EACnC,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM;CACtC;CACA,OAAO;EAAE,GAAG;EAAM,GAAG;EAAM,OAAO,OAAO;EAAM,QAAQ,OAAO;CAAK;AACrE;;;;;AAMA,SAAgB,wBACd,MACA,IACA,WACA,KACA,QAAQ,IACR,MAAM,IACG;CACT,MAAM,OAAO;EAAC;EAAK,KAAK,IAAI,KAAK,EAAE;EAAG;EAAG;CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC;CACtF,IAAI,WAA2B;CAC/B,KAAK,MAAM,UAAU,MAAM;EACzB,MAAM,SAAS,aAAa,MAAM,IAAI,WAAW,QAAQ,OAAO,GAAG;EACnE,IAAI,OAAO,OAAO,OAAO,OAAO;EAChC,aAAa,OAAO;CACtB;CACA,OAAO,YAAY,CAAC,SAAS,IAAI,GAAG,SAAS,EAAE,CAAC;AAClD;AAIA,SAAS,aACP,MACA,IACA,WACA,KACA,OACA,KACqC;CAGrC,MAAM,OAAO,KAAK,IAFD,KAAK,IAAI,eAAe,GAEZ,IAAI,MAAM,MAAM,EAAE;CAC/C,MAAM,QAAQ,sBAAsB,MAAM,IAAI,WAAW,KAAK,OAAO,KAAK,IAAI;CAC9E,IAAI,OAAO,OAAO;EAAE,QAAQ;EAAO,OAAO;CAAK;CAE/C,MAAM,WAAW,KAAK,IAAI,eAAe,OAAO,GAAI;CACpD,MAAM,WAAW,UAAU,KAAK,MAAM,QAAQ,GAAG,GAAG,CAAC;CACrD,MAAM,gBAAgB,CAAC,MAAM,EAAE;CAC/B,MAAM,aAAqB,CAAC;CAC5B,MAAM,QAAQ,UAAU,MAAM,EAAE;CAChC,MAAM,YAAY,MAAM;CAExB,KAAK,IAAI,OAAO,GAAG,OAAO,MAAM,QAAQ,QAAQ;EAC9C,MAAM,CAAC,IAAI,MAAM,MAAM;EACvB,MAAM,WAAW,YAAY,MAAM,gBAAgB,MAAM,IAAI,IAAI,EAAE,CAAC;EACpE,MAAM,UAAU,OAAO,MAAM,IAAI,KAAK;EACtC,MAAM,UAAU,OAAO,IAAI,IAAI,GAAG;EAClC,MAAM,IAAI,OAAO,MAAM,IAAI,OAAO,QAAQ;EAC1C,MAAM,IAAI,OAAO,IAAI,IAAI,KAAK,QAAQ;EAEtC,KAAK,MAAM,OAAO,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,GAC3C,WAAW,KAAK;GAAE,KAAK;IAAC;IAAS,GAAG;IAAK;GAAO;GAAG;EAAK,CAAC;EAG3D,MAAM,QAAQ,EAAE,IAAI,EAAE,KAAK;EAC3B,MAAM,QAAQ,EAAE,IAAI,EAAE,KAAK;EAC3B,WAAW,KAAK;GACd,KAAK;IAAC;IAAS;IAAG;KAAE,GAAG;KAAM,GAAG,EAAE;IAAE;IAAG;KAAE,GAAG;KAAM,GAAG,EAAE;IAAE;IAAG;IAAG;GAAO;GACtE;EACF,CAAC;EACD,WAAW,KAAK;GACd,KAAK;IAAC;IAAS;IAAG;KAAE,GAAG,EAAE;KAAG,GAAG;IAAK;IAAG;KAAE,GAAG,EAAE;KAAG,GAAG;IAAK;IAAG;IAAG;GAAO;GACtE;EACF,CAAC;CACH;CAIA,yBAAyB,YAAY,MAAM,IAAI,UAAU,KAAK,OAAO,KAAK,SAAS;CAKnF,MAAM,OAAO,YAAY;EAAC,GADZ,eAAe,MAAM,IAAI,QACN;EAAG,QAAQ,MAAM,GAAG;EAAG,QAAQ,IAAI,GAAG;CAAC,CAAC;CACzE,IAAI,MAAM;EACR,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI;EAChC,MAAM,OAAO,KAAK,IAAI;EACtB,MAAM,QAAQ,KAAK,IAAI,KAAK,QAAQ;EACpC,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,SAAS,KAAK,IAAI,KAAK,SAAS;EAEtC,MAAM,aAAqB,CACzB,UAAU,IACV,GAAI;GAAC;GAAK;GAAK;GAAK;EAAG,CAAC,CAAY,QAAQ,MAAM,MAAM,UAAU,EAAE,CACtE;EACA,KAAK,MAAM,MAAM,YAGf,gBACE,YACA,MACA,OACA,MACA,KACA,MACA,OACA,KACA,QAXc,OAAO,IAAI,IAAI,GAYvB,GAXS,OAAO,UAAU,KAAK,IAAI,CAa3C;CAEJ;CAEA,IAAI,YAA4B;CAChC,IAAI,iBAAiB;CACrB,IAAI,UAAmB,WAAW,EAAE,EAAE,OAAO,CAAC,SAAS,IAAI,GAAG,SAAS,EAAE,CAAC;CAC1E,IAAI,eAAe;CAEnB,KAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,SAAS,iBAAiB,OAAO,KAAK,GAAG,CAAC;EAChD,IAAI,OAAO,SAAS,GAAG;EACvB,MAAM,MAAM,WAAW,MAAM;EAC7B,MAAM,OAAO,UAAU,QAAQ,UAAU,aAAa;EAGtD,MAAM,OACJ,UAAU,QAAQ,eAAe,QAAQ,IAAI,UAAU,QAAQ,WAAW,aAAa;EACzF,MAAM,cAAc,sBAAsB,MAAM,IAAI,QAAQ,SAAS;EAGrE,MAAM,QAAQ,OAAO,MAAU,OAAO,MAAM,KAAK,OAAO,MAAM,cAAc;EAC5E,IAAI,QAAQ,cAAc;GACxB,eAAe;GACf,UAAU;EACZ;EAEA,IAAI,SAAS,KAAK,QAAQ,gBAAgB;GACxC,iBAAiB;GACjB,YAAY;EACd;CACF;CAEA,OAAO;EAAE,QAAQ,aAAa;EAAS,OAAO,aAAa;CAAK;AAClE;;;;;AAMA,SAAS,yBACP,YACA,MACA,IACA,UACA,KACA,OACA,KACA,WACM;CACN,MAAM,CAAC,IAAI,MAAM;CACjB,MAAM,QAAQ,KAAK,IAAI,KAAK,aAAa;CACzC,MAAM,UAAU,OAAO,IAAI,IAAI,GAAG;CAClC,MAAM,IAAI,OAAO,IAAI,IAAI,KAAK,KAAK;CAEnC,IAAK,OAAO,OAAO,OAAO,OAAS,OAAO,OAAO,OAAO,KAAM;EAC5D,MAAM,KAAK,OAAO,MAAM,KAAK,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG;EACxD,MAAM,KAAK,OAAO,MAAM,GAAG,IAAI,KAAK;EACpC,IAAI,MAAM,KAAK,GAAG;EAIlB,MAAM,WAAW,SAAS,QACvB,QACC,IAAI,IAAI,IAAI,QAAQ,KAAK,KACzB,IAAI,IAAI,KAAK,MACZ,cAAc,IAAI,GAAG,IAAI,IAAI,IAAI,QAAQ,KAAK,GAAG,KAAK,IAAI,KAAK,MAAM,KACpE,cAAc,IAAI,GAAG,IAAI,IAAI,IAAI,QAAQ,GAAG,GAAG,GAAG,IAAI,GAAG,MAAM,EACrE;EACA,IAAI,SAAS,WAAW,GAAG;EAC3B,MAAM,UAAU,KAAK,IAAI,GAAG,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI;EAC5D,MAAM,aAAa,KAAK,IAAI,GAAG,SAAS,KAAK,QAAQ,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI;EAC5E,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;EAClC,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;EAClC,WAAW,KAAK;GACd,KAAK;IAAC;IAAI;KAAE,GAAG,GAAG;KAAG,GAAG;IAAQ;IAAG;KAAE,GAAG,EAAE;KAAG,GAAG;IAAQ;IAAG;IAAG;GAAO;GACrE,MAAM;EACR,CAAC;EACD,WAAW,KAAK;GACd,KAAK;IAAC;IAAI;KAAE,GAAG,GAAG;KAAG,GAAG;IAAW;IAAG;KAAE,GAAG,EAAE;KAAG,GAAG;IAAW;IAAG;IAAG;GAAO;GAC3E,MAAM;EACR,CAAC;EAED,MAAM,KAAK,OAAO,MAAM,IAAI,KAAK;EACjC,MAAM,OACJ,OAAO,MAAM,KAAK,IAAI,GAAG,IAAI,QAAQ,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,QAAQ,KAAK,MAAM,CAAC;EAC3F,WAAW,KAAK;GACd,KAAK;IAAC;IAAI;KAAE,GAAG;KAAM,GAAG,GAAG;IAAE;IAAG;KAAE,GAAG;KAAM,GAAG;IAAQ;IAAG;KAAE,GAAG,EAAE;KAAG,GAAG;IAAQ;IAAG;IAAG;GAAO;GAC3F,MAAM;EACR,CAAC;EACD,WAAW,KAAK;GACd,KAAK;IACH;IACA;KAAE,GAAG;KAAM,GAAG,GAAG;IAAE;IACnB;KAAE,GAAG;KAAM,GAAG;IAAW;IACzB;KAAE,GAAG,EAAE;KAAG,GAAG;IAAW;IACxB;IACA;GACF;GACA,MAAM;EACR,CAAC;EACD;CACF;CAEA,IAAK,OAAO,OAAO,OAAO,OAAS,OAAO,OAAO,OAAO,KAAM;EAC5D,MAAM,KAAK,OAAO,MAAM,KAAK,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG;EACzD,MAAM,KAAK,OAAO,MAAM,GAAG,IAAI,KAAK;EACpC,IAAI,MAAM,KAAK,GAAG;EAClB,MAAM,WAAW,SAAS,QACvB,QACC,IAAI,IAAI,IAAI,SAAS,KAAK,KAC1B,IAAI,IAAI,KAAK,MACZ,cAAc,IAAI,GAAG,IAAI,IAAI,IAAI,OAAO,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,KAClE,cAAc,IAAI,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,EACnE;EACA,IAAI,SAAS,WAAW,GAAG;EAC3B,MAAM,WAAW,KAAK,IAAI,GAAG,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI;EAC7D,MAAM,YAAY,KAAK,IAAI,GAAG,SAAS,KAAK,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI;EAC1E,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;EAClC,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;EAClC,WAAW,KAAK;GACd,KAAK;IAAC;IAAI;KAAE,GAAG;KAAU,GAAG,GAAG;IAAE;IAAG;KAAE,GAAG;KAAU,GAAG,EAAE;IAAE;IAAG;IAAG;GAAO;GACvE,MAAM;EACR,CAAC;EACD,WAAW,KAAK;GACd,KAAK;IAAC;IAAI;KAAE,GAAG;KAAW,GAAG,GAAG;IAAE;IAAG;KAAE,GAAG;KAAW,GAAG,EAAE;IAAE;IAAG;IAAG;GAAO;GACzE,MAAM;EACR,CAAC;CACH;AACF;;;;;AAMA,SAAS,eAAe,MAAY,IAAU,UAAkB,SAAS,KAAa;CACpF,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI;CACpC,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI;CACpC,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,OAAO,GAAG,IAAI,GAAG,KAAK,IAAI;CAC5D,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,MAAM,IAAI;CAC9D,OAAO,SAAS,QACb,QAAQ,EAAE,IAAI,IAAI,IAAI,QAAQ,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,MAAM,IAAI,IAAI,GACxF;AACF;;AAGA,SAAS,gBACP,YACA,MACA,OACA,MACA,KACA,MACA,OACA,KACA,QACA,SACA,OAAO,GACD;CACN,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;CAClC,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;CAClC,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;CAClC,MAAM,KAAK,OAAO,MAAM,KAAK,KAAK;CAClC,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC;CACtD,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC;CACzD,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,QAAQ,GAAG,CAAC,CAAC;CACxD,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC;CACvD,MAAM,IAAI,OAAO,MAAM,KAAK,OAAO,KAAK;CACxC,MAAM,IAAI,OAAO,MAAM,KAAK,OAAO,KAAK;CACxC,MAAM,IAAI,OAAO,MAAM,KAAK,OAAO,KAAK;CACxC,MAAM,IAAI,OAAO,MAAM,KAAK,OAAO,KAAK;CAGxC,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG;IAAO,GAAG,EAAE;GAAE;GAAG;IAAE,GAAG;IAAO,GAAG;GAAI;GAAG;IAAE,GAAG,QAAQ;IAAG,GAAG;GAAI;GAAG;EAAO;EAC1F;CACF,CAAC;CACD,WAAW,KAAK;EACd,KAAK;GACH;GACA;GACA;IAAE,GAAG;IAAO,GAAG,EAAE;GAAE;GACnB;IAAE,GAAG;IAAO,GAAG;GAAO;GACtB;IAAE,GAAG,QAAQ;IAAG,GAAG;GAAO;GAC1B;EACF;EACA,MAAM,OAAO;CACf,CAAC;CAED,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG;IAAM,GAAG,EAAE;GAAE;GAAG;IAAE,GAAG;IAAM,GAAG;GAAI;GAAG;IAAE,GAAG,QAAQ;IAAG,GAAG;GAAI;GAAG;EAAO;EACxF;CACF,CAAC;CACD,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG;IAAM,GAAG,EAAE;GAAE;GAAG;IAAE,GAAG;IAAM,GAAG;GAAO;GAAG;IAAE,GAAG,QAAQ;IAAG,GAAG;GAAO;GAAG;EAAO;EAC9F,MAAM,OAAO;CACf,CAAC;CAED,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG,EAAE;IAAG,GAAG;GAAI;GAAG;IAAE,GAAG;IAAM,GAAG;GAAI;GAAG;IAAE,GAAG;IAAM,GAAG,QAAQ;GAAE;GAAG;EAAO;EACxF;CACF,CAAC;CACD,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG,EAAE;IAAG,GAAG;GAAI;GAAG;IAAE,GAAG;IAAO,GAAG;GAAI;GAAG;IAAE,GAAG;IAAO,GAAG,QAAQ;GAAE;GAAG;EAAO;EAC1F;CACF,CAAC;CACD,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG,EAAE;IAAG,GAAG;GAAI;GAAG;IAAE,GAAG,QAAQ;IAAG,GAAG;GAAI;GAAG;EAAO;EAClE,MAAM,OAAO;CACf,CAAC;CAED,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG,EAAE;IAAG,GAAG;GAAO;GAAG;IAAE,GAAG;IAAM,GAAG;GAAO;GAAG;IAAE,GAAG;IAAM,GAAG,QAAQ;GAAE;GAAG;EAAO;EAC9F;CACF,CAAC;CACD,WAAW,KAAK;EACd,KAAK;GACH;GACA;GACA;IAAE,GAAG,EAAE;IAAG,GAAG;GAAO;GACpB;IAAE,GAAG;IAAO,GAAG;GAAO;GACtB;IAAE,GAAG;IAAO,GAAG,QAAQ;GAAE;GACzB;EACF;EACA;CACF,CAAC;CACD,WAAW,KAAK;EACd,KAAK;GAAC;GAAI;GAAG;IAAE,GAAG,EAAE;IAAG,GAAG;GAAO;GAAG;IAAE,GAAG,QAAQ;IAAG,GAAG;GAAO;GAAG;EAAO;EACxE,MAAM,OAAO;CACf,CAAC;AACH;AAEA,SAAS,UAAU,QAAiB,WAAmB,WAA2B;CAChF,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;EAC1C,MAAM,SAAS,MAAM,KAAK,MAAM,OAAO,SAAS;EAChD,KAAK,MAAM,OAAO,WAChB,IAAI,gBAAgB,OAAO,IAAK,OAAO,IAAI,IAAK,GAAG,GAAG,KAAK;EAG7D,IAAI,CAAC;QACE,MAAM,OAAO,WAChB,IAAI,gBAAgB,OAAO,IAAK,OAAO,IAAI,IAAK,GAAG,GAAG,KAAK;EAAA;CAGjE;CACA,OAAO;AACT;AAEA,SAAS,UAAU,QAAiB,OAAe,OAAuB;CACxE,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;EAC1C,MAAM,SAAS,MAAM,KAAK,MAAM,OAAO,SAAS;EAChD,KAAK,MAAM,OAAO,OAChB,IAAI,gBAAgB,OAAO,IAAK,OAAO,IAAI,IAAK,KAAK,OAAO,MAAM,GAAG,KAAK;CAE9E;CACA,OAAO;AACT;;;;AC/pBA,SAAS,kBAAkB,eAAuE;CAChG,IAAI,kBAAkB,OAAO,OAAO;CACpC,IAAI,kBAAkB,SAAS,OAAO;CACtC,OAAO;AACT;AAQA,MAAM,mBAAmB;;AAGzB,SAAS,eAAe,SAA4C;CAClE,QAAQ,SAAR;EACE,KAAK,WACH,OAAO;EACT,KAAK,YACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAS,eAAe,KAAkC,SAAgC;CACxF,MAAM,QAAQ,QAAQ,gBAAgB;CACtC,MAAM,OAAO,OAAO,OAAO,kBAAkB,GAAG,IAAI,eAAe,QAAQ,OAAO;CAClF,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,KAAK,CAAC;AAC7C;AAEA,SAAS,gBAAgB,KAAkC,SAAgC;CACzF,MAAM,QAAQ,QAAQ,gBAAgB;CACtC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,kBAAkB,GAAG,IAAI,KAAK,CAAC;AAC/D;AAEA,SAAS,WAAW,QAAwB;CAC1C,OAAO,GAAG,mBAAmB;AAC/B;AAEA,SAAS,gBAAgB,QAA+B;CACtD,OAAO,OAAO,WAAW,gBAAgB,IAAI,OAAO,MAAM,CAAuB,IAAI;AACvF;;AAGA,SAAS,gBAAgB,SAA4C;CACnE,QAAQ,SAAR;EACE,KAAK,WACH,OAAO;EACT,KAAK,YACH,OAAO;EAET,SACE,OAAO;CACX;AACF;AAEA,SAAgB,mBAAmB,OAAmB,SAAiC;CACrF,IAAI,QAAQ,YAAY,WAAW,QAAQ,YAAY,SAAS,QAAQ,YAAY,QAClF,OAAO;CAET,OAAO,MAAM,OAAO,MAAM,MAAM,sBAAsB,CAAC,CAAC;AAC1D;AAEA,SAAS,eACP,OACA,WACe;CACf,MAAM,MAAM,aAAa;CACzB,MAAM,aAAa,QAAQ,QAAQ,QAAQ;CAC3C,MAAM,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM;EACvC,MAAM,WAAW,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;EACpD,MAAM,WAAW,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;EACpD,IAAI,aAAa,UAAU,OAAO,WAAW;EAC7C,QAAQ,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;CACtF,CAAC;CACD,MAAM,yBAAS,IAAI,IAAoB;CACvC,IAAI,OAAO;CACX,IAAI,cAAc,OAAO;CACzB,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,UAAU,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;EACnD,IAAI,UAAU,cAAc,GAAG;GAC7B,IAAI,gBAAgB,OAAO,mBAAmB,QAAQ;GACtD,cAAc;EAChB;EACA,OAAO,IAAI,EAAE,QAAQ,IAAI;CAC3B;CACA,MAAM,8BAAc,IAAI,IAAoB;CAC5C,OAAO,OAAO,KAAK,MAAM;EACvB,MAAM,IAAI,OAAO,IAAI,EAAE,MAAM,KAAK;EAClC,MAAM,QAAQ,YAAY,IAAI,CAAC,KAAK;EACpC,YAAY,IAAI,GAAG,QAAQ,CAAC;EAC5B,OAAO;GAAE,GAAG;GAAG,MAAM;GAAG;EAAM;CAChC,CAAC;AACH;AAEA,SAAS,UACP,SACA,YACA,MACA,SACA,QAAQ,IACW;CACnB,MAAM,sBAAM,IAAI,IAAkB;CAClC,IAAI,IAAI;CACR,IAAI,IAAI;CACR,IAAI,OAAO;CACX,MAAM,UAAU,gBAAgB,OAAO;CACvC,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK;CAC7B,MAAM,OAAmB,CAAC;CAC1B,IAAI,MAAgB,CAAC;CACrB,KAAK,MAAM,MAAM,SAAS;EACxB,MAAM,IAAI,WAAW,IAAI,EAAE;EAC3B,IAAI,CAAC,GAAG;EACR,IAAI,SAAS,SAAS;GAEpB,IAAI,IAAI,IAAI;IAAE,GAAG;IAAG;IAAG,OAAO,EAAE;IAAO,QAAQ,EAAE;GAAO,CAAC;GACzD,KAAK,EAAE,SAAS;GAChB;EACF;EACA,IAAI,IAAI,KAAK,IAAI,EAAE,QAAQ,SAAS;GAClC,KAAK,KAAK,GAAG;GACb,MAAM,CAAC;GACP,IAAI;GACJ,KAAK,OAAO;GACZ,OAAO;EACT;EACA,IAAI,IAAI,IAAI;GAAE;GAAG;GAAG,OAAO,EAAE;GAAO,QAAQ,EAAE;EAAO,CAAC;EACtD,IAAI,KAAK,EAAE;EACX,KAAK,EAAE,QAAQ;EACf,OAAO,KAAK,IAAI,MAAM,EAAE,MAAM;CAChC;CACA,IAAI,IAAI,QAAQ,KAAK,KAAK,GAAG;CAE7B,IAAI,SAAS,WAAW,IAAI,OAAO,GAAG;EACpC,MAAM,OAAO,KAAK,IAAI,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC;EAC9D,KAAK,MAAM,CAAC,IAAI,MAAM,KACpB,IAAI,IAAI,IAAI;GAAE,GAAG;GAAG,IAAI,OAAO,EAAE,SAAS;EAAE,CAAC;CAEjD,OAAO,IAAI,SAAS,UAAU,KAAK,SAAS,GAAG;EAI7C,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,EAAE,MAAM,GAAG,CAAC;EACzD,MAAM,OAAO,MAAM,KAAK,EAAE,QAAQ,SAAS,SAAS,CAAC;EACrD,MAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,KAAK,OAAO,SAAS,CAAC;EAC9D,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;GACjB,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;IACnC,MAAM,IAAI,IAAI,IAAI,IAAI,EAAG;IACzB,KAAK,KAAK,KAAK,IAAI,KAAK,IAAK,EAAE,KAAK;IACpC,WAAW,KAAK,KAAK,IAAI,WAAW,IAAK,EAAE,MAAM;GACnD;EACF;EACA,IAAI,KAAK;EACT,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,MAAM,KAAK;GACjB,IAAI,KAAK;GACT,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;IACnC,MAAM,KAAK,IAAI;IACf,MAAM,IAAI,IAAI,IAAI,EAAE;IACpB,IAAI,IAAI,IAAI;KAAE,GAAG;KAAI,GAAG;KAAI,OAAO,EAAE;KAAO,QAAQ,EAAE;IAAO,CAAC;IAC9D,MAAM,KAAK,KAAM;GACnB;GACA,MAAM,WAAW,KAAM;EACzB;CACF;CACA,OAAO;AACT;AAEA,SAAS,OAAO,OAAoC;CAClD,IAAI,OAAO,UACT,OAAO,UACP,OAAO,WACP,OAAO;CACT,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,OAAO;EACrB,MAAM;EACN,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,KAAK;EACnC,OAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM;CACtC;CACA,IAAI,CAAC,KAAK,OAAO;CACjB,OAAO;EAAE,GAAG;EAAM,GAAG;EAAM,OAAO,OAAO;EAAM,QAAQ,OAAO;CAAK;AACrE;AAEA,SAAS,YAAY,OAA0B,IAAY,IAAkB;CAC3E,KAAK,MAAM,CAAC,IAAI,MAAM,OACpB,MAAM,IAAI,IAAI;EAAE,GAAG;EAAG,GAAG,EAAE,IAAI;EAAI,GAAG,EAAE,IAAI;CAAG,CAAC;AAEpD;;;;;AAMA,eAAe,eACb,OACA,OACA,UACA,SACA,eAC4B;CAC5B,MAAM,UAAU,IAAI,IAAI,yBAAyB,OAAO,MAAM,EAAE,CAAC;CACjE,IAAI,QAAQ,SAAS,GAAG,uBAAO,IAAI,IAAI;CAEvC,MAAM,WAAuB;EAC3B,GAAG;EACH,OAAO,MAAM,MAAM,QAAQ,MAAM,QAAQ,IAAI,EAAE,EAAE,CAAC;EAClD,OAAO,MAAM,MAAM,QAAQ,MAAM,QAAQ,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,EAAE,EAAE,CAAC;EACzE,QAAQ,CAAC;CACX;CACA,MAAM,cAAc,SAAS,QAAQ,MAAM,QAAQ,IAAI,EAAE,MAAM,CAAC;CAChE,IAAI,YAAY,WAAW,GAAG,uBAAO,IAAI,IAAI;CAI7C,IAAI,SAAS,MAAM,WAAW,GAI5B,OAAO,UAHK,YAAY,KAAK,MAAM,EAAE,MAGlB,GAAG,IAFC,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAE7B,GADlB,kBAAkB,QAAQ,kBAAkB,OAAO,UAAU,QAClC,QAAQ,SAAS,eAAe,KAAA,GAAW,OAAO,CAAC;CAG7F,MAAM,WAAW,cAAc,UAAU,aAAa;EACpD,GAAG;EACH,WAAW;EACX,aAAa;CACf,CAAC;CACD,MAAM,OAAO,MAAM,OAAO,CAAC,CAAC,OAAO,QAAQ;CAC3C,MAAM,sBAAM,IAAI,IAAkB;CAClC,KAAK,MAAM,SAAS,KAAK,YAAY,CAAC,GAAG;EACvC,IAAI,CAAC,QAAQ,IAAI,MAAM,EAAE,GAAG;EAC5B,IAAI,IAAI,MAAM,IAAI;GAChB,GAAG,MAAM,KAAK;GACd,GAAG,MAAM,KAAK;GACd,OAAO,MAAM,SAAS;GACtB,QAAQ,MAAM,UAAU;EAC1B,CAAC;CACH;CAEA,MAAM,MAAM,OAAO,IAAI,OAAO,CAAC;CAC/B,IAAI,QAAQ,IAAI,MAAM,KAAK,IAAI,MAAM,IACnC,YAAY,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC;CAEjC,OAAO;AACT;;AAGA,SAAS,oBACP,MACA,KACA,YACA,OAC0B;CAC1B,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK;CAC5D,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,IAAI,MAAM,IAAI,MAAM;CAC7D,MAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,WAAW,KAAK;CACnD,MAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,WAAW,MAAM;CACpD,MAAM,KAAK,UAAU,QAAQ,QAAQ,UAAU,UAAU,IAAI,QAAQ;CACrE,MAAM,KAAK,UAAU,QAAQ,QAAQ,UAAU,UAAU,IAAI,QAAQ;CACrE,OAAO;EAAE,GAAG,KAAK,IAAI,IAAI,OAAO;EAAI,GAAG,KAAK,IAAI,IAAI,MAAM;CAAG;AAC/D;AAEA,SAAS,yBAAyB,OAAmB,SAA2B;CAC9E,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,OAAO;CACvD,IAAI,CAAC,OAAO,OAAO,CAAC;CACpB,MAAM,MAAM,CAAC,GAAG,MAAM,OAAO;CAC7B,MAAM,QAAQ,CAAC,GAAG,MAAM,aAAa;CACrC,OAAO,MAAM,QAAQ;EACnB,MAAM,MAAM,MAAM,IAAI;EACtB,MAAM,QAAQ,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG;EACnD,IAAI,CAAC,OAAO;EACZ,IAAI,KAAK,GAAG,MAAM,OAAO;EACzB,MAAM,KAAK,GAAG,MAAM,aAAa;CACnC;CACA,OAAO;AACT;AAEA,SAAS,cAAc,OAAmB,UAA4C;CACpF,OAAO,MAAM,OAAO,QAAQ,MAAM,EAAE,aAAa,QAAQ;AAC3D;;AAGA,SAAS,qBACP,OACA,QACA,UACqE;CAErE,MAAM,QAAgB,CAAC;CACvB,KAAK,MAAM,MAAM,OAAO,SAAS;EAC/B,MAAM,IAAI,MAAM,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;EACnD,MAAM,KAAK;GACT,MAAM;GACN;GACA,OAAO,GAAG,aAAa,MAAM,UAAU,OAAO;EAChD,CAAC;CACH;CACA,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,QAAQ,OAAO;EACnB,KAAK,MAAM,OAAO,yBAAyB,OAAO,MAAM,EAAE,GAAG;GAE3D,MAAM,IADI,MAAM,MAAM,MAAM,SAAS,KAAK,OAAO,GACvC,CAAC,EAAE,aAAa,MAAM;GAChC,IAAI,KAAK,MAAM,QAAQ,KAAK,IAAI,OAAO,CAAC;EAC1C;EACA,MAAM,KAAK;GAAE,MAAM;GAAS,IAAI,MAAM;GAAI;EAAM,CAAC;CACnD;CACA,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;CAClE,OAAO,MAAM,KAAK,EAAE,MAAM,SACxB,SAAS,SAAS;EAAE,MAAM;EAAQ;CAAG,IAAI;EAAE,MAAM;EAAS;CAAG,CAC/D;AACF;;AAGA,SAAS,qBACP,OACA,UACqE;CAErE,MAAM,QAAgB,MAAM,MACzB,QAAQ,SAAS,KAAK,WAAW,IAAI,CAAC,CACtC,KAAK,UAAU;EACd,MAAM;EACN,IAAI,KAAK;EACT,OAAO,KAAK,aAAa,MAAM,UAAU,OAAO;CAClD,EAAE;CAEJ,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,QAAQ,OAAO;EACnB,KAAK,MAAM,UAAU,yBAAyB,OAAO,MAAM,EAAE,GAAG;GAC9D,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK,OAAO,MAAM,CAAC,EAAE,aAAa,MAAM;GAClF,IAAI,UAAU,MAAM,QAAQ,KAAK,IAAI,OAAO,MAAM;EACpD;EACA,MAAM,KAAK;GAAE,MAAM;GAAS,IAAI,MAAM;GAAI;EAAM,CAAC;CACnD;CAEA,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;CAClE,OAAO,MAAM,KAAK,EAAE,MAAM,UAAU;EAAE;EAAM;CAAG,EAAE;AACnD;;;;;AAeA,eAAe,qBAAqB,KAAqB,QAA0C;CACjG,MAAM,UAAU,QAAQ,WAAW,IAAI,QAAQ;CAC/C,IAAI,CAAC,SAAS;CAEd,MAAM,WAAW,cAAc,IAAI,OAAO,QAAQ,EAAE;CAOpD,MAAM,eALJ,QAAQ,WAAW,OAAO,QAAQ,SAAS,IACvC,OAAO,UACP,SACE,qBAAqB,IAAI,OAAO,QAAQ,QAAQ,IAChD,qBAAqB,IAAI,OAAO,QAAQ;CAEhD,IAAI,aAAa,WAAW,GAAG;CAE/B,MAAM,QAAQ,QAAQ,SAAS,IAAI,QAAQ,SAAS;CACpD,MAAM,gBAAgB,kBAAkB,OAAO;CAC/C,MAAM,YAAY,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;CAGxD,KAAK,MAAM,SAAS,UAClB,IAAI,sBAAsB,KAAK,GAC7B,MAAM,qBAAqB,KAAK,KAAK;CAIzC,MAAM,QAAsB,CAAC;CAC7B,MAAM,+BAAe,IAAI,IAA+B;CAExD,KAAK,MAAM,UAAU,cAAc;EACjC,IAAI,OAAO,SAAS,QAAQ;GAC1B,MAAM,IAAI,IAAI,WAAW,IAAI,OAAO,EAAE;GACtC,IAAI,CAAC,GAAG;GACR,MAAM,KAAK;IACT,SAAS,WAAW,OAAO,EAAE;IAC7B,OAAO,EAAE;IACT,QAAQ,EAAE;GACZ,CAAC;GACD;EACF;EAEA,MAAM,QAAQ,UAAU,IAAI,OAAO,EAAE;EACrC,IAAI,CAAC,OAAO;EAEZ,IAAI;EACJ,IAAI,IAAI,YAAY,IAAI,MAAM,EAAE,KAAK,sBAAsB,KAAK,GAAG;GAEjE,MAAM,KAAK,IAAI,YAAY,IAAI,MAAM,EAAE;GACvC,MAAM,KAAK;IACT,SAAS,MAAM;IACf,OAAO,GAAG;IACV,QAAQ,GAAG;IACX,QAAQ,MAAM;IACd,KAAK,MAAM;IACX,SAAS,MAAM,WAAW,MAAM;IAChC,SAAS,MAAM;GACjB,CAAC;GACD;EACF;EAEA,MAAM,OAAO,MAAM,eAAe;EAClC,MAAM,UAAU,eAAe,MAAM,KAAK,IAAI,OAAO;EACrD,IAAI,SAAS,UAAU,SAAS,SAC9B,UAAU,UAAU,MAAM,SAAS,IAAI,YAAY,MAAM,IAAI,QAAQ,SAAS,OAAO;OAErF,UAAU,MAAM,eAAe,IAAI,OAAO,OAAO,IAAI,UAAU,IAAI,SAAS,aAAa;EAE3F,aAAa,IAAI,MAAM,IAAI,OAAO;EAElC,MAAM,MAAM,gBAAgB,KAAK;EACjC,MAAM,aAAa,OAAO,QAAQ,OAAO,CAAC,KAAK;GAAE,GAAG;GAAG,GAAG;GAAG,OAAO;GAAI,QAAQ;EAAG;EACnF,MAAM,QAAQ,WAAW,QAAQ,IAAI,OAAO,IAAI;EAChD,MAAM,SAAS,WAAW,SAAS,IAAI,MAAM,IAAI;EACjD,MAAM,KAAK;GACT,SAAS,MAAM;GACf;GACA;GACA,QAAQ,MAAM;GACd,KAAK,MAAM;GACX,SAAS,MAAM,WAAW,MAAM;GAChC,SAAS,MAAM;EACjB,CAAC;CACH;CAEA,MAAM,SAAS,cAAc;EAC3B;EACA;EACA,KAAK,gBAAgB,QAAQ,OAAO,IAAI,QAAQ,KAAK,IAAI,OAAO;EAChE,SAAS,QAAQ,WAAW,IAAI,QAAQ;EACxC,MAAM,QAAQ,QAAQ,IAAI,QAAQ;EAClC;EACA,QAAQ;GAAE,GAAA;GAAkB,GAAA;EAAiB;CAC/C,CAAC;CAED,KAAK,MAAM,QAAQ,QAAQ;EACzB,MAAM,eAAe,gBAAgB,KAAK,OAAO;EACjD,IAAI,cAAc;GAChB,MAAM,IAAI,IAAI,WAAW,IAAI,YAAY;GACzC,IAAI,GAAG;IACL,MAAM,aAAa;KAAE,GAAG;KAAG,GAAG;KAAG,OAAO,EAAE;KAAO,QAAQ,EAAE;IAAO;IAClE,MAAM,SAAS,oBACb,KAAK,QACL;KAAE,KAAK;KAAG,OAAO;KAAG,QAAQ;KAAG,MAAM;IAAE,GACvC,YACA,KACF;IACA,IAAI,WAAW,IAAI,cAAc;KAC/B,GAAG,OAAO;KACV,GAAG,OAAO;KACV,OAAO,EAAE;KACT,QAAQ,EAAE;IACZ,CAAC;GACH,OACE,IAAI,WAAW,IAAI,cAAc,EAAE,GAAG,KAAK,OAAO,CAAC;GAErD;EACF;EAEA,MAAM,QAAQ,UAAU,IAAI,KAAK,OAAO;EACxC,IAAI,CAAC,OAAO;EACZ,MAAM,MAAM,gBAAgB,KAAK;EAEjC,MAAM,UAAU,aAAa,IAAI,MAAM,EAAE;EACzC,IAAI,SAAS;GACX,IAAI,YAAY,IAAI,MAAM,IAAI,KAAK,MAAM;GACzC,MAAM,aAAa,OAAO,QAAQ,OAAO,CAAC,KAAK;IAAE,GAAG;IAAG,GAAG;IAAG,OAAO;IAAG,QAAQ;GAAE;GACjF,MAAM,SAAS,oBAAoB,KAAK,QAAQ,KAAK,YAAY,KAAK;GACtE,KAAK,MAAM,CAAC,QAAQ,UAAU,SAC5B,IAAI,WAAW,IAAI,QAAQ;IACzB,GAAG,OAAO,KAAK,MAAM,IAAI,WAAW;IACpC,GAAG,OAAO,KAAK,MAAM,IAAI,WAAW;IACpC,OAAO,MAAM;IACb,QAAQ,MAAM;GAChB,CAAC;EAEL,OAAO,IAAI,sBAAsB,KAAK,GAAG;GAGvC,MAAM,OAAO,IAAI,YAAY,IAAI,MAAM,EAAE;GACzC,IAAI,MAAM;IACR,MAAM,KAAK,KAAK,OAAO,IAAI,KAAK;IAChC,MAAM,KAAK,KAAK,OAAO,IAAI,KAAK;IAChC,IAAI,YAAY,IAAI,MAAM,IAAI,KAAK,MAAM;IACzC,IAAI,OAAO,KAAK,OAAO,GAAG;KACxB,KAAK,MAAM,OAAO,yBAAyB,IAAI,OAAO,MAAM,EAAE,GAAG;MAC/D,MAAM,IAAI,IAAI,WAAW,IAAI,GAAG;MAChC,IAAI,GAAG,IAAI,WAAW,IAAI,KAAK;OAAE,GAAG;OAAG,GAAG,EAAE,IAAI;OAAI,GAAG,EAAE,IAAI;MAAG,CAAC;KACnE;KACA,MAAM,QAAQ,CAAC,GAAG,MAAM,aAAa;KACrC,OAAO,MAAM,QAAQ;MACnB,MAAM,MAAM,MAAM,IAAI;MACtB,MAAM,KAAK,IAAI,YAAY,IAAI,GAAG;MAClC,IAAI,IAAI,IAAI,YAAY,IAAI,KAAK;OAAE,GAAG;OAAI,GAAG,GAAG,IAAI;OAAI,GAAG,GAAG,IAAI;MAAG,CAAC;MACtE,MAAM,IAAI,IAAI,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG;MACnD,IAAI,GAAG,MAAM,KAAK,GAAG,EAAE,aAAa;KACtC;IACF;GACF,OACE,IAAI,YAAY,IAAI,MAAM,IAAI,KAAK,MAAM;EAE7C,OACE,IAAI,YAAY,IAAI,MAAM,IAAI,KAAK,MAAM;CAE7C;CAGA,IAAI,QAAQ;EACV,MAAM,MAAM,OAAO,OAAO,KAAK,MAAM,EAAE,MAAM,CAAC;EAC9C,IAAI,KAAK;GACP,MAAM,MAAM,gBAAgB,MAAM;GAClC,IAAI,YAAY,IAAI,OAAO,IAAI;IAC7B,GAAG,IAAI,IAAI,IAAI;IACf,GAAG,IAAI,IAAI,IAAI;IACf,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI;IAClC,QAAQ,IAAI,SAAS,IAAI,MAAM,IAAI;GACrC,CAAC;EACH;CACF;AACF;AAEA,SAAS,mBACP,QACA,QACA,MACA,MACA,IACA,WACA,KACA,OACA,KACS;CACT,MAAM,SAAS,wBAAwB,MAAM,IAAI,WAAW,KAAK,OAAO,GAAG;CAC3E,MAAM,QAAQ,OAAO;CACrB,MAAM,MAAM,OAAO,OAAO,SAAS;CACnC,MAAM,aAAa,OAAO,MAAM,GAAG,EAAE;CACrC,OAAO;EACL,IAAI;EACJ,SAAS,CAAC,MAAM;EAChB,SAAS,CAAC,IAAI;EACd,UAAU,CACR;GACE,IAAI,GAAG,OAAO;GACd,YAAY;IAAE,GAAG,MAAM;IAAG,GAAG,MAAM;GAAE;GACrC,UAAU;IAAE,GAAG,IAAI;IAAG,GAAG,IAAI;GAAE;GAC/B;EACF,CACF;CACF;AACF;AAEA,SAAS,QAAQ,OAAe,OAAuB;CACrD,IAAI,SAAS,GAAG,OAAO;CAEvB,OAAO,MAAQ,MAAO,SAAU,QAAQ;AAC1C;AAIA,SAAS,gBAAgB,MAAY,IAAqB;CACxD,OAAO,kBAAkB,MAAM,EAAE,CAAC,CAAC;AACrC;AAEA,SAAS,iBAAiB,MAAY,IAAqB;CACzD,OAAO,kBAAkB,MAAM,EAAE,CAAC,CAAC;AACrC;;AAGA,SAAS,YAAY,MAAY,OAAa,MAAyB;CACrE,MAAM,KAAK,MAAM,IAAI,MAAM,QAAQ;CACnC,MAAM,KAAK,MAAM,IAAI,MAAM,SAAS;CACpC,IAAI,SAAS,OAAO,SAAS,KAAK,OAAO,KAAK,KAAK;CACnD,OAAO,KAAK,KAAK;AACnB;AAEA,SAAS,aAAa,GAAS,GAAkB;CAC/C,OAAO,EACL,EAAE,IAAI,EAAE,QAAQ,EAAE,KAClB,EAAE,IAAI,EAAE,QAAQ,EAAE,KAClB,EAAE,IAAI,EAAE,SAAS,EAAE,KACnB,EAAE,IAAI,EAAE,SAAS,EAAE;AAEvB;;;;;AAMA,SAAS,YAAY,MAAY,IAAuB;CACtD,MAAM,CAAC,MAAM,kBAAkB,MAAM,EAAE;CACvC,IAAI,OAAO,OAAO,OAAO,KAAK;EAC5B,MAAM,KAAK,OAAO,MAAM,KAAK,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG;EACxD,MAAM,KAAK,OAAO,MAAM,GAAG,IAAI,KAAK;EACpC,IAAI,MAAM,KAAK,GAAG,OAAO;EACzB,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;EAChC,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,MAAM;EAC1D,OAAO;GAAE,GAAG;GAAI,GAAG;GAAI,OAAO,KAAK;GAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,EAAE;EAAE;CACtE;CACA,MAAM,KAAK,OAAO,MAAM,KAAK,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG;CACzD,MAAM,KAAK,OAAO,MAAM,GAAG,IAAI,KAAK;CACpC,IAAI,MAAM,KAAK,GAAG,OAAO;CACzB,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;CAChC,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,OAAO,GAAG,IAAI,GAAG,KAAK;CACxD,OAAO;EAAE,GAAG;EAAI,GAAG;EAAI,OAAO,KAAK,IAAI,GAAG,KAAK,EAAE;EAAG,QAAQ,KAAK;CAAG;AACtE;;;;;AAMA,SAAS,kBACP,QACA,YAC0D;CAC1D,MAAM,wBAAQ,IAAI,IAAoB;CACtC,MAAM,sBAAM,IAAI,IAAoB;CAGpC,MAAM,4BAAY,IAAI,IAAsB;CAC5C,MAAM,2BAAW,IAAI,IAAsB;CAE3C,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,OAAO,WAAW,IAAI,EAAE,IAAI;EAClC,MAAM,KAAK,WAAW,IAAI,EAAE,EAAE;EAC9B,MAAM,UAAU,gBAAgB,MAAM,EAAE;EACxC,MAAM,SAAS,iBAAiB,MAAM,EAAE;EACxC,MAAM,SAAS,GAAG,EAAE,KAAK,GAAG;EAC5B,MAAM,QAAQ,GAAG,EAAE,GAAG,GAAG;EACzB,IAAI,CAAC,UAAU,IAAI,MAAM,GAAG,UAAU,IAAI,QAAQ,CAAC,CAAC;EACpD,IAAI,CAAC,SAAS,IAAI,KAAK,GAAG,SAAS,IAAI,OAAO,CAAC,CAAC;EAChD,UAAU,IAAI,MAAM,CAAC,CAAE,KAAK;GAAE,QAAQ,EAAE;GAAI,KAAK,YAAY,MAAM,IAAI,OAAO;EAAE,CAAC;EACjF,SAAS,IAAI,KAAK,CAAC,CAAE,KAAK;GAAE,QAAQ,EAAE;GAAI,KAAK,YAAY,IAAI,MAAM,MAAM;EAAE,CAAC;CAChF;CAEA,KAAK,MAAM,WAAW,UAAU,OAAO,GAAG;EACxC,QAAQ,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;EACpC,QAAQ,SAAS,GAAG,MAAM,MAAM,IAAI,EAAE,QAAQ,QAAQ,GAAG,QAAQ,MAAM,CAAC,CAAC;CAC3E;CACA,KAAK,MAAM,WAAW,SAAS,OAAO,GAAG;EACvC,QAAQ,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;EACpC,QAAQ,SAAS,GAAG,MAAM,IAAI,IAAI,EAAE,QAAQ,QAAQ,GAAG,QAAQ,MAAM,CAAC,CAAC;CACzE;CAEA,OAAO;EAAE;EAAO;CAAI;AACtB;AAEA,SAAS,mBACP,OACA,YACA,aACA,SACU;CACV,MAAM,WAAsB,CAAC;CAC7B,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,MAAM,IAAI,WAAW,IAAI,KAAK,EAAE;EAChC,IAAI,CAAC,GAAG;EACR,SAAS,KAAK;GACZ,IAAI,KAAK;GACT,GAAG,EAAE;GACL,GAAG,EAAE;GACL,OAAO,EAAE;GACT,QAAQ,EAAE;EACZ,CAAC;CACH;CAEA,MAAM,YAAY,KAAK,IAAA,IAErB,QAAQ,mBAAA,EACV;CAGA,MAAM,WAAW,KAAK,IAAI,IAAI,SAAS;CACvC,MAAM,SAAS,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,EAAE,IAAI,KAAK,WAAW,IAAI,EAAE,EAAE,CAAC;CACvF,MAAM,EAAE,OAAO,QAAQ,kBAAkB,QAAQ,UAAU;CAE3D,MAAM,8BAAc,IAAI,IAAyB;CACjD,MAAM,aAAa,YAAiC;EAClD,IAAI,MAAM,YAAY,IAAI,OAAO;EACjC,IAAI,CAAC,KAAK;GACR,MAAM,IAAI,IAAI,yBAAyB,OAAO,OAAO,CAAC;GACtD,YAAY,IAAI,SAAS,GAAG;EAC9B;EACA,OAAO;CACT;CAEA,MAAM,oBAAoB,YAAiC;EACzD,MAAM,sBAAM,IAAI,IAAY,CAAC,OAAO,CAAC;EACrC,MAAM,QAAQ,CAAC,OAAO;EACtB,OAAO,MAAM,QAAQ;GACnB,MAAM,KAAK,MAAM,IAAI;GACrB,MAAM,IAAI,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,EAAE;GAC9C,IAAI,CAAC,GAAG;GACR,KAAK,MAAM,SAAS,EAAE,eAAe;IACnC,IAAI,IAAI,IAAI,KAAK,GAAG;IACpB,IAAI,IAAI,KAAK;IACb,MAAM,KAAK,KAAK;GAClB;EACF;EACA,OAAO;CACT;;CAGA,MAAM,oBAAoB,QAAgB,YAAiC;EACzE,MAAM,uBAAO,IAAI,IAAY;EAC7B,KAAK,MAAM,KAAK,MAAM,QAAQ;GAC5B,MAAM,UAAU,UAAU,EAAE,EAAE;GAC9B,IAAI,CAAC,QAAQ,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,GAAG;GAClD,KAAK,MAAM,MAAM,iBAAiB,EAAE,EAAE,GAAG,KAAK,IAAI,EAAE;EACtD;EACA,OAAO;CACT;CAEA,MAAM,QAAQ,OAAO,KAAK,MAAM;EAC9B,MAAM,OAAO,WAAW,IAAI,EAAE,IAAI;EAClC,MAAM,KAAK,WAAW,IAAI,EAAE,EAAE;EAC9B,MAAM,YAAoB,CAAC;EAC3B,KAAK,MAAM,CAAC,IAAI,MAAM,YAAY;GAChC,IAAI,OAAO,EAAE,QAAQ,OAAO,EAAE,IAAI;GAClC,UAAU,KAAK,CAAC;EAClB;EAIA,MAAM,QAAQ,YAAY,MAAM,EAAE;EAClC,IAAI,OAAO;GACT,MAAM,uBAAO,IAAI,IAAY,CAC3B,GAAG,iBAAiB,EAAE,MAAM,EAAE,EAAE,GAChC,GAAG,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAClC,CAAC;GACD,KAAK,MAAM,CAAC,KAAK,OAAO,aAAa;IACnC,IAAI,KAAK,IAAI,GAAG,GAAG;IACnB,MAAM,UAAU,UAAU,GAAG;IAC7B,IAAI,QAAQ,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,EAAE,EAAE,GAAG;IAC9C,IAAI,CAAC,aAAa,IAAI,KAAK,GAAG;IAC9B,UAAU,KAAK,EAAE;GACnB;EACF;EACA,OAAO,mBACL,EAAE,IACF,EAAE,MACF,EAAE,IACF,MACA,IACA,WACA,UACA,MAAM,IAAI,EAAE,EAAE,KAAK,IACnB,IAAI,IAAI,EAAE,EAAE,KAAK,EACnB;CACF,CAAC;CAED,OAAO;EACL,IAAI;EACJ,eAAe;GACb,iBAAiB;GACjB,mBAAmB;GACnB,iBACE,QAAQ,cAAc,OAClB,SACA,QAAQ,cAAc,OACpB,OACA,QAAQ,cAAc,OACpB,SACA;GACV,wBAAwB;GACxB,wBAAwB,OAAO,SAAS;GACxC,wBAAwB,OAAO,QAAQ,mBAAmB,EAAE;GAC5D,eAAe;EACjB;EACA;EACA;CACF;AACF;;;;AAKA,eAAsB,uBACpB,OACA,UACA,SAC+B;CAC/B,MAAM,KAAK,YAAY,IAAI;CAC3B,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,aAAa,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC7D,MAAM,MAAsB;EAC1B;EACA;EACA;EACA;EACA,4BAAY,IAAI,IAAI;EACpB,6BAAa,IAAI,IAAI;CACvB;CAGA,IAAI,QAAQ,SACV,MAAM,qBAAqB,KAAK,IAAI;MAC/B;EAEL,MAAM,QADkB,MAAM,OAAO,QAAQ,MAAM,sBAAsB,CAAC,CAC9C,CAAC,CAAC,QAAQ,MAAM;GAC1C,IAAI,CAAC,EAAE,UAAU,OAAO;GACxB,MAAM,SAAS,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,EAAE,QAAQ;GAC3D,OAAO,CAAC,UAAU,CAAC,sBAAsB,MAAM;EACjD,CAAC;EACD,KAAK,MAAM,QAAQ,OACjB,MAAM,qBAAqB,KAAK,IAAI;CAExC;CAIA,MAAM,YAAY,IAAI,IAAI,IAAI,WAAW,KAAK,CAAC;CAC/C,MAAM,cAAc,MAAM,MAAM,QAAQ,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE;CACnF,IAAI,YAAY,QAAQ;EACtB,MAAM,cAAc,IAAI,IAAI,WAAW;EACvC,MAAM,UAAoB,CAAC;EAC3B,MAAM,QAAkB,CAAC;EACzB,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,MAAM,aAAa;GAC5B,MAAM,UAAU,MAAM,MAAM,MAAM,MAAM,EAAE,SAAS,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;GAC/E,MAAM,UAAU,MAAM,MAAM,MAAM,MAAM,EAAE,OAAO,MAAM,CAAC,YAAY,IAAI,EAAE,IAAI,CAAC;GAC/E,IAAI,WAAW,CAAC,SAAS,QAAQ,KAAK,EAAE;QACnC,IAAI,WAAW,CAAC,SAAS,MAAM,KAAK,EAAE;QACtC,MAAM,KAAK,EAAE;EACpB;EAEA,MAAM,aAAa,KAAe,SAAmC;GACnE,IAAI,IAAI,WAAW,GAAG;GAGtB,MAAM,SAAS,UACb,KACA,YAHA,cAAc,QAAQ,cAAc,OAAQ,SAAoB,SAKhE,QAAQ,SACR,eAAe,KAAA,GAAW,OAAO,CACnC;GACA,MAAM,YAAY,OAAO,OAAO,OAAO,CAAC,KAAK;IAAE,GAAG;IAAG,GAAG;IAAG,OAAO;IAAI,QAAQ;GAAG;GACjF,MAAM,cAAc,OAAO,IAAI,WAAW,OAAO,CAAC;GAClD,IAAI,UAAA;GACJ,IAAI,UAAA;GACJ,IAAI,aACF,IAAI,cAAc,QAAQ,cAAc,MAAM;IAC5C,UAAU,YAAY;IACtB,UACE,SAAS,WACL,YAAY,IAAI,UAAU,SAAS,uBACnC,YAAY,IAAI,YAAY,SAAS;GAC7C,OAAO;IACL,UAAU,YAAY;IACtB,UACE,SAAS,WACL,YAAY,IAAI,UAAU,QAAQ,uBAClC,YAAY,IAAI,YAAY,QAAQ;GAC5C;GAEF,KAAK,MAAM,CAAC,IAAI,MAAM,QACpB,IAAI,WAAW,IAAI,IAAI;IACrB,GAAG;IACH,GAAG,EAAE,IAAI,UAAU,IAAI;IACvB,GAAG,EAAE,IAAI,UAAU,IAAI;GACzB,CAAC;EAEL;EAEA,UAAU,SAAS,QAAQ;EAC3B,UAAU,CAAC,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO;EAEvC,MAAM,SAAS,OAAO,IAAI,WAAW,OAAO,CAAC;EAC7C,IAAI,WAAW,OAAO,IAAA,MAAqB,OAAO,IAAA,KAAoB;GACpE,MAAM,KAAK,KAAK,IAAI,GAAA,KAAmB,OAAO,CAAC;GAC/C,MAAM,KAAK,KAAK,IAAI,GAAA,KAAmB,OAAO,CAAC;GAC/C,IAAI,MAAM,IAAI;IACZ,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI,YACxB,IAAI,WAAW,IAAI,IAAI;KAAE,GAAG;KAAG,GAAG,EAAE,IAAI;KAAI,GAAG,EAAE,IAAI;IAAG,CAAC;IAE3D,KAAK,MAAM,CAAC,IAAI,MAAM,IAAI,aACxB,IAAI,YAAY,IAAI,IAAI;KAAE,GAAG;KAAG,GAAG,EAAE,IAAI;KAAI,GAAG,EAAE,IAAI;IAAG,CAAC;GAE9D;EACF;CACF;CAGA,MAAM,WAAW,mBAAmB,OAAO,IAAI,YAAY,IAAI,aAAa;EAC1E,GAAG;EACH;CACF,CAAC;CACD,MAAM,OAAO,MAAM,OAAO,CAAC,CAAC,OAAO,QAAQ;CAG3C,MAAM,eAA8B,eAClC,CAAC,GAAG,IAAI,WAAW,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,aAAa;EACvD;EACA;EACA,MAAM;EACN,OAAO;CACT,EAAE,GACF,SACF;CAEA,MAAM,SAAyB,CAAC;CAChC,KAAK,MAAM,KAAK,MAAM,QAAQ;EAC5B,MAAM,SAAS,IAAI,YAAY,IAAI,EAAE,EAAE;EACvC,IAAI,CAAC,QAAQ;EACb,MAAM,UAAU,gBAAgB,CAAC;EACjC,OAAO,KAAK;GACV,SAAS,EAAE;GACX;GACA,UAAU,qBACR,EAAE,OACF,QACA,QAAQ,EAAE,QAAQ,EAAE,SAAS,UAAU,EAAE,WAAW,KAAK,CAC3D;GACA;EACF,CAAC;CACH;CAGA,MAAM,WAA6B,CAAC;CACpC,KAAK,MAAM,QAAQ,KAAK,SAAS,CAAC,GAAG;EACnC,MAAM,SAAqC,CAAC;EAC5C,KAAK,MAAM,WAAW,KAAK,YAAY,CAAC,GAAG;GACzC,OAAO,KAAK,EAAE,GAAG,QAAQ,WAAW,CAAC;GACrC,KAAK,MAAM,QAAQ,QAAQ,cAAc,CAAC,GAAG,OAAO,KAAK,EAAE,GAAG,KAAK,CAAC;GACpE,OAAO,KAAK,EAAE,GAAG,QAAQ,SAAS,CAAC;EACrC;EACA,IAAI,OAAO,UAAU,GAAG,SAAS,KAAK;GAAE,QAAQ,KAAK;GAAI;EAAO,CAAC;CACnE;CAEA,MAAM,aAAa,SAAkB;EACnC,KAAK,MAAM,QAAQ,KAAK,SAAS,CAAC,GAAG;GACnC,IAAI,SAAS,MAAM,MAAM,EAAE,WAAW,KAAK,EAAE,GAAG;GAChD,MAAM,SAAqC,CAAC;GAC5C,KAAK,MAAM,WAAW,KAAK,YAAY,CAAC,GAAG;IACzC,OAAO,KAAK;KACV,IAAI,QAAQ,WAAW,KAAK,MAAM,KAAK,KAAK;KAC5C,IAAI,QAAQ,WAAW,KAAK,MAAM,KAAK,KAAK;IAC9C,CAAC;IACD,KAAK,MAAM,QAAQ,QAAQ,cAAc,CAAC,GACxC,OAAO,KAAK;KAAE,GAAG,KAAK,KAAK,KAAK,KAAK;KAAI,GAAG,KAAK,KAAK,KAAK,KAAK;IAAG,CAAC;IAEtE,OAAO,KAAK;KACV,IAAI,QAAQ,SAAS,KAAK,MAAM,KAAK,KAAK;KAC1C,IAAI,QAAQ,SAAS,KAAK,MAAM,KAAK,KAAK;IAC5C,CAAC;GACH;GACA,IAAI,OAAO,UAAU,GAAG,SAAS,KAAK;IAAE,QAAQ,KAAK;IAAI;GAAO,CAAC;EACnE;EACA,KAAK,MAAM,KAAK,KAAK,YAAY,CAAC,GAAG,UAAU,CAAC;CAClD;CACA,UAAU,IAAI;CAKd,MAAM,YAHgB,4BAA4B,OAAO,cAAc,QAGzC,CAAC,CAAC,KAAK,UAAU;EAC7C,GAAG;EACH,QAAQ,uBAAuB,uBAAuB,KAAK,MAAM,CAAC;CACpE,EAAE;CACF,MAAM,aAAgC,CAAC;CAEvC,IAAI,OAAO;CACX,IAAI,OAAO;CACX,KAAK,MAAM,KAAK,cAAc;EAC5B,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;EACjD,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM;CACpD;CACA,KAAK,MAAM,KAAK,QAAQ;EACtB,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;EACjD,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM;CACpD;CACA,KAAK,MAAM,QAAQ,WACjB,KAAK,MAAM,KAAK,KAAK,QAAQ;EAC3B,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;CAC3B;CAGF,OAAO;EACL,QAAQ;GACN,OAAO;GACP;GACA;GACA;GACA;GACA,kBAAkB;GAClB,UAAU,YAAY,IAAI,IAAI;GAC9B,OAAO,OAAO;GACd,QAAQ,OAAO;EACjB;EACA,OAAO;EACP,iBAAiB;CACnB;AACF;AAEA,MAAM,uBAAuB;;;ACzgC7B,MAAa,4BAA4B;AACzC,MAAa,4BAA4B;AAuEzC,MAAM,aAAa;AACnB,MAAM,kBAAkB;;AAExB,MAAM,SAAS;AACf,MAAM,YAAY;AAClB,MAAM,iBAAiB;AAKvB,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,kBAAkB;AACxB,MAAM,SAAS;AACf,MAAM,WAAW;AACjB,MAAM,YAAY;AAClB,MAAM,gBAAgB;AACtB,MAAM,eAAe;AAErB,SAAS,aAAa,SAA2C;CAC/D,IAAI,YAAY,WAAW,OAAO;CAClC,IAAI,YAAY,YAAY,OAAO;CACnC,OAAO;AACT;;;;;;AAOA,SAAS,oBACP,KACA,YACA,OAMA;CACA,MAAM,WAAW,KAAK,IACpB,GACA,GAAG,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK,GAClC,GAAG,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,GAC/B,GAAG,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK,GAClC,GAAG,IAAI,YAAY,KAAK,MAAM,EAAE,QAAQ,CAC1C;CAEA,MAAM,SAAS,IAAI,IAAI,IAAI,MAAM,KAAK,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;CACzD,MAAM,YAAY,IAAI,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;CAC/D,MAAM,SAAS,IAAI,IACjB,IAAI,SAAS,QAAQ,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,CAClF;CAEA,MAAM,4BAAY,IAAI,IAAY;CAClC,MAAM,0BAAU,IAAI,IAAY;CAChC,MAAM,mCAAmB,IAAI,IAAY;CAEzC,MAAM,aAAa,cAAkC;EACnD,KAAK,MAAM,QAAQ,WAAW;GAC5B,UAAU,IAAI,KAAK,UAAU;GAC7B,QAAQ,IAAI,KAAK,QAAQ;GACzB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KACxC,iBAAiB,IAAI,KAAK,SAAS,EAAE,CAAE,UAAU;GAEnD,KAAK,MAAM,MAAM,KAAK,UAAU,UAAU,GAAG,QAAQ;EACvD;CACF;CACA,UAAU,IAAI,SAAS;CAEvB,MAAM,6BAAa,IAAI,IAAoB;CAC3C,MAAM,uBAAO,IAAI,IAAoB;CACrC,MAAM,0BAAU,IAAI,IAAoB;CACxC,IAAI,SAAS;CAEb,KAAK,IAAI,QAAQ,GAAG,SAAS,UAAU,SAAS;EAC9C,IAAI,SAAS;EACb,IAAI,OAAO;EACX,IAAI,YAAY;EAEhB,IAAI,UAAU,IAAI,KAAK,GACrB,UAAU;EAEZ,IAAI,iBAAiB,IAAI,KAAK,GAC5B,UAAU;EAGZ,MAAM,OAAO,OAAO,IAAI,KAAK;EAC7B,IAAI,MACF,OAAO,KAAK,IAAI,MAAM,kBAAkB,KAAK,IAAI,IAAI,aAAa;EAEpE,IAAI,UAAU,IAAI,KAAK,GACrB,OAAO,KAAK,IAAI,MAAM,YAAY;EAEpC,IAAI,OAAO,IAAI,KAAK,GAClB,OAAO,KAAK,IAAI,MAAM,QAAQ,eAAe;EAE/C,IAAI,QAAQ,IAAI,KAAK,GACnB,aAAa;EAGf,MAAM,MAAM;EACZ,MAAM,SAAS,SAAS,SAAS,OAAO;EACxC,MAAM,SAAS,SAAS,SAAS,OAAO;EACxC,KAAK,IAAI,OAAO,GAAG;EACnB,WAAW,IAAI,OAAO,MAAM;EAC5B,QAAQ,IAAI,OAAO,MAAM;EACzB,SAAS;CACX;CAEA,MAAM,YAAY,UAAkB,aAAa,QAAQ;CACzD,OAAO;EACL,MAAM,UAAkB,WAAW,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI,QAAQ;EAC3E,UAAU,UAAkB,KAAK,IAAI,KAAK,KAAK,SAAS,KAAK;EAC7D,aAAa,UAAkB,QAAQ,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI;EACvE,SAAS,SAAS;CACpB;AACF;AAEA,SAAS,kBAAkB,MAAsB;CAE/C,OADc,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,SAAS,EAAE,CACzC,IAAI,YAAY,WAAW;AACxC;;;;AAKA,SAAgB,eACd,OACA,UACA,UAAyB,CAAC,GACC;CAC3B,MAAM,KAAK,YAAY,IAAI;CAC3B,MAAM,MAAM,MAAM;CAClB,IAAI,CAAC,KACH,OAAO,oBAAoB,EAAE;CAG/B,MAAM,QAAQ,aAAa,QAAQ,OAAO;CAC1C,MAAM,QAAQ,SAAS;CACvB,MAAM,iBAAiB,kBAAkB;CACzC,MAAM,eAAe,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CAG/D,MAAM,QAAuB,CAAC;CAC9B,MAAM,0BAAU,IAAI,IAAoB;CACxC,IAAI,IAAI;CACR,IAAI,UAAU;CAEd,KAAK,MAAM,CAAC,GAAG,OAAO,IAAI,iBAAiB,QAAQ,GAAG;EACpD,MAAM,IAAI,aAAa,IAAI,EAAE;EAC7B,MAAM,IAAI,GAAG,SAAS;EACtB,MAAM,IAAI,GAAG,UAAU;EACvB,UAAU,KAAK,IAAI,SAAS,CAAC;EAC7B,MAAM,SAAe;GAAE;GAAG,GAAG;GAAQ,OAAO;GAAG,QAAQ;EAAE;EACzD,MAAM,KAAK;GAAE,QAAQ;GAAI;GAAQ,MAAM;GAAG,OAAO;EAAE,CAAC;EACpD,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC;EACzB,KAAK,IAAI;CACX;CAGA,MAAM,EAAE,KAAK,SAAS,YAAY,YAAY,oBAAoB,KAD/C,SAAS,UAAU,aAAa,OACgC,KAAK;CAExF,MAAM,WAAoC,CAAC;CAC3C,MAAM,YAA8B,CAAC;CACrC,MAAM,aAAyC,CAAC;CAChD,IAAI,YAAY;CAEhB,KAAK,MAAM,OAAO,IAAI,UAAU;EAE9B,IAAI,IAAI,cAAc,IAAI,SAAS,WAAW,aAAa;EAC3D,MAAM,IAAI,IAAI,IAAI,KAAK;EACvB,MAAM,QACJ,IAAI,QAAQ,QAAQ,IAAI,IAAI,IAAI,IAC5B,QAAQ,IAAI,IAAI,IAAI,IACpB,IAAI,SAAS,WACV,QAAQ,IAAI,IAAI,EAAG,KAAK,UAAU,KACnC;EACR,MAAM,MACJ,IAAI,MAAM,QAAQ,IAAI,IAAI,EAAE,IACxB,QAAQ,IAAI,IAAI,EAAE,IAClB,IAAI,SAAS,UACV,QAAQ,IAAI,IAAI,IAAK,KAAK,UAAU,KACrC;EAER,IAAI;EACJ,IAAI,IAAI,SAAS,WAAW;GAC1B,MAAM,KAAK,QAAQ,IAAI,IAAI,IAAK,KAAK;GACrC,SAAS;IACP;KAAE,GAAG,KAAK;KAAG,GAAG,IAAI;IAAE;IACtB;KAAE,GAAG,KAAK;KAAG,GAAG,IAAI;IAAE;IACtB;KAAE,GAAG,KAAK;KAAG,GAAG,IAAI;IAAE;IACtB;KAAE,GAAG,KAAK;KAAG,GAAG,IAAI;IAAE;GACxB;EACF,OAAO,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,SAAS,IAAI,IAAI;GACpD,MAAM,KAAK,QAAQ,IAAI,IAAI,IAAI;GAC/B,MAAM,YAAY,KAAK,IAAI,IAAI,kBAAkB,KAAK;GACtD,SAAS;IACP;KAAE,GAAG;KAAI,GAAG,IAAI,YAAY;IAAK;IACjC;KAAE,GAAG,KAAK;KAAa,GAAG,IAAI,YAAY;IAAK;IAC/C;KAAE,GAAG,KAAK;KAAa,GAAG,IAAI,YAAY;IAAK;IAC/C;KAAE,GAAG;KAAI,GAAG,IAAI,YAAY;IAAK;GACnC;EACF,OACE,SAAS,CACP;GAAE,GAAG;GAAO;EAAE,GACd;GAAE,GAAG;GAAK;EAAE,CACd;EAGF,MAAM,cACJ,OAAO,UAAU,IACb;GACE,IAAI,OAAO,EAAE,CAAE,IAAI,OAAO,OAAO,SAAS,EAAE,CAAE,KAAK;GACnD,GAAG,KAAK,IAAI,OAAO,EAAE,CAAE,GAAG,OAAO,OAAO,SAAS,EAAE,CAAE,CAAC,IAAI;EAC5D,IACA,KAAA;EAEN,SAAS,KAAK;GACZ,WAAW,IAAI;GACf,MAAM,IAAI;GACV;GACA,OAAO,IAAI;GACX;GACA,QAAQ,IAAI,cAAc,IAAI,SAAS,YAAY,YAAY,KAAA;EACjE,CAAC;EAED,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,SAAS,OAAO,IAAI,OAAO,KACvD,UAAU,KAAK;GAAE,QAAQ,IAAI;GAAI;EAAO,CAAC;CAG7C;CAEA,MAAM,YAAsC,CAAC;CAC7C,KAAK,MAAM,MAAM,IAAI,kBAAkB;EACrC,MAAM,KAAK,QAAQ,IAAI,EAAE;EACzB,MAAM,OAAO,MAAM,MAAM,MAAM,EAAE,WAAW,EAAE;EAC9C,UAAU,KAAK;GACb,eAAe;GACf,GAAG;GACH,IAAI,KAAK,OAAO,IAAI,KAAK,OAAO;GAChC,IAAI;EACN,CAAC;CACH;CAEA,MAAM,cAA0C,IAAI,YAAY,KAAK,MAAM;EACzE,MAAM,KAAK,QAAQ,IAAI,EAAE,aAAa,KAAK;EAC3C,MAAM,KAAK,IAAI,EAAE,UAAU,IAAI;EAC/B,MAAM,KAAK,IAAI,EAAE,QAAQ,IAAI;EAC7B,OAAO;GACL,IAAI,EAAE;GACN,eAAe,EAAE;GACjB,YAAY,EAAE;GACd,UAAU,EAAE;GACZ,QAAQ;IACN,GAAG,KAAK,eAAe;IACvB,GAAG,KAAK,IAAI,IAAI,EAAE;IAClB,OAAO;IACP,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC;GACvC;EACF;CACF,CAAC;CAED,MAAM,YAAsC,CAAC;CAC7C,MAAM,cAAc,MAAwB,UAAwB;EAClE,MAAM,KAAK,IAAI,iBAAiB,KAAK,OAAO,QAAQ,IAAI,EAAE,CAAE;EAC5D,MAAM,OAAO,KAAK,IAAI,GAAG,EAAE,IAAI,iBAAiB,QAAQ;EACxD,MAAM,OAAO,KAAK,IAAI,GAAG,EAAE,IAAI,iBAAiB,QAAQ;EAExD,MAAM,KAAK,QAAQ,KAAK,UAAU,IAAI;EACtC,MAAM,KAAK,WAAW,KAAK,QAAQ,IAAI;EACvC,MAAM,aAAuB,CAAC;EAC9B,MAAM,gBAA+D,CAAC;EACtE,MAAM,eAAuD,CAAC;EAE9D,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;GAC7C,MAAM,KAAK,KAAK,SAAS;GACzB,MAAM,QAAQ,MAAM,IAAI,KAAK,QAAQ,GAAG,UAAU;GAClD,MAAM,WACJ,MAAM,KAAK,SAAS,SAAS,IAAI,KAAK,QAAQ,KAAK,SAAS,IAAI,EAAE,CAAE,UAAU;GAChF,aAAa,KAAK;IAChB,YAAY,GAAG;IACf,UAAU,GAAG;IACb,WAAW,GAAG;IACd,QAAQ;KACN,GAAG;KACH,GAAG;KACH,OAAO,OAAO;KACd,QAAQ,KAAK,IAAI,GAAG,WAAW,KAAK;IACtC;GACF,CAAC;GACD,IAAI,IAAI,GAAG;IACT,WAAW,KAAK,KAAK;IACrB,IAAI,GAAG,OACL,cAAc,KAAK;KAAE,MAAM,GAAG;KAAO,GAAG,OAAO;KAAG,GAAG,QAAQ;IAAE,CAAC;GAEpE;EACF;EACA,IAAI,KAAK,OACP,cAAc,QAAQ;GACpB,MAAM,GAAG,4BAA4B,KAAK,QAAQ,EAAE,IAAI,KAAK,MAAM;GACnE,GAAG,OAAO;GACV,GAAG,KAAK;EACV,CAAC;OAED,cAAc,QAAQ;GACpB,MAAM,4BAA4B,KAAK,QAAQ;GAC/C,GAAG,OAAO;GACV,GAAG,KAAK;EACV,CAAC;EAGH,UAAU,KAAK;GACb,IAAI,KAAK;GACT,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,WAAW,KAAK;GAChB,gBAAgB,KAAK;GACrB,QAAQ;IAAE,GAAG;IAAM,GAAG;IAAI,OAAO,OAAO;IAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,EAAE;GAAE;GAC5E,YAAY,KAAK;GACjB,UAAU,KAAK;GACf;GACA;GACA;EACF,CAAC;EAED,KAAK,MAAM,MAAM,KAAK,UACpB,KAAK,MAAM,SAAS,GAAG,UAAU,WAAW,OAAO,QAAQ,CAAC;CAEhE;CACA,KAAK,MAAM,QAAQ,IAAI,WAAW,WAAW,MAAM,CAAC;CAEpD,MAAM,QAA8B,IAAI,MAAM,KAAK,MAAM;EACvD,MAAM,IAAI,IAAI,EAAE,KAAK;EACrB,MAAM,IAAI,kBAAkB,EAAE,IAAI;EAClC,MAAM,MAAM,EAAE,eAAe,QAAQ,OAAO,QAAQ,IAAI,EAAE,CAAC;EAC3D,IAAI;EACJ,IAAI;EACJ,IAAI,EAAE,cAAc,UAAU,IAAI,QAAQ;GACxC,MAAM,KAAK,IAAI,KAAK,OAAO,QAAQ,IAAI,EAAE,CAAE;GAC3C,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI;GACvB,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI;EACzB,OAAO,IAAI,EAAE,cAAc,UAAU,IAAI,IAAI;GAC3C,MAAM,KAAK,QAAQ,IAAI,IAAI,EAAE;GAC7B,KAAK,KAAK;GACV,KAAK,KAAK;EACZ,OAAO,IAAI,IAAI,IAAI;GACjB,MAAM,KAAK,QAAQ,IAAI,IAAI,EAAE;GAC7B,KAAK,KAAK;GACV,KAAK,KAAK;EACZ,OAAO;GACL,KAAK;GACL,KAAK;EACP;EACA,MAAM,IAAI,KAAK,IAAI,IAAI,KAAK,EAAE;EAC9B,OAAO;GACL,IAAI,EAAE;GACN,MAAM,EAAE;GACR,QAAQ;IAAE,GAAG;IAAI,GAAG,IAAI,IAAI;IAAG,OAAO;IAAG,QAAQ;GAAE;EACrD;CACF,CAAC;CAED,MAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,OAAO,GAAG,MAAM;CACnD,MAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,OAAO,GAAG,MAAM;CAUlD,MAAM,WAAoC;EACxC;EACA;EACA;EACA;EACA,UAdwC,IAAI,SAAS,KAAK,OAAO;GACjE,IAAI,EAAE;GAEN,GAAG,IAAI,EAAE,KAAK,IAAI;GAClB,IAAI,SAAS;GACb,IAAI,QAAQ;GACZ,OAAO,EAAE;EACX,EAOS;EACP;CACF;CAEA,IAAI,OAAO;CACX,IAAI,OAAO;CACX,KAAK,MAAM,KAAK,WAAW;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;EACjD,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM;CACpD;CACA,KAAK,MAAM,KAAK,OAAO;EACrB,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;EACjD,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM;CACpD;CACA,KAAK,MAAM,QAAQ,WACjB,KAAK,MAAM,KAAK,KAAK,QAAQ;EAC3B,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;CAC3B;CAgBF,OAAO;EACL,QAAA;GAbA;GACA,QAAQ,CAAC;GACT;GACA;GACA,WAAW;GACX,kBAAkB;GAClB,UAAU,YAAY,IAAI,IAAI;GAC9B,OAAO,OAAO;GACd,QAAQ,OAAO;GACf;EAIK;EACL,OAAO;EACP,iBAAiB;CACnB;AACF;AAEA,SAAS,oBAAoB,IAAuC;CAClE,OAAO;EACL,QAAQ;GACN,OAAO,CAAC;GACR,QAAQ,CAAC;GACT,WAAW,CAAC;GACZ,YAAY,CAAC;GACb,WAAW;GACX,kBAAkB;GAClB,UAAU,YAAY,IAAI,IAAI;GAC9B,OAAO;GACP,QAAQ;EACV;EACA,OAAO,CAAC;EACR,iBAAiB;CACnB;AACF;AAEA,SAAgB,gBAAgB,OAA4B;CAC1D,OAAO,MAAM,gBAAgB,cAAc,MAAM,YAAY;AAC/D;;;AC3eA,SAAS,qBACP,MACA,SACA,SACA,UACA,WACA,OACM;CACN,MAAM,IAAI,WAAW,KAAK,KAAK;CAC/B,MAAM,IAAI,WAAW,KAAK,KAAK;CAC/B,MAAM,SAAS;EACb;EACA;EACA,OAAO,KAAK,SAAS;EACrB,QAAQ,KAAK,UAAU;CACzB;CACA,MAAM,IAAI,KAAK,IAAI;EAAE;EAAQ;CAAS,CAAC;CACvC,IAAI,KAAK,OAAO,QACd,UAAU,IAAI,KAAK,IAAI,MAAM;CAE/B,KAAK,MAAM,SAAS,KAAK,YAAY,CAAC,GACpC,qBAAqB,OAAO,GAAG,GAAG,KAAK,IAAI,WAAW,KAAK;AAE/D;;;;;;AAOA,SAAS,qBACP,OACA,UACA,UACO;CACP,IAAI,CAAC,YAAY,CAAC,UAAU,OAAO;EAAE,GAAG;EAAG,GAAG;CAAE;CAEhD,MAAM,aAAa,eAAe,QAAQ;CAC1C,MAAM,aAAa,eAAe,QAAQ;CAE1C,MAAM,4BAAY,IAAI,IAAY;CAClC,IAAI,MAAqB;CACzB,OAAO,KAAK;EACV,UAAU,IAAI,GAAG;EACjB,MAAM,MAAM,IAAI,GAAG,CAAC,EAAE,YAAY;CACpC;CAEA,MAAM;CACN,OAAO,KAAK;EACV,IAAI,UAAU,IAAI,GAAG,GAAG;GACtB,MAAM,MAAM,MAAM,IAAI,GAAG;GACzB,OAAO,MAAM;IAAE,GAAG,IAAI,OAAO;IAAG,GAAG,IAAI,OAAO;GAAE,IAAI;IAAE,GAAG;IAAG,GAAG;GAAE;EACnE;EACA,MAAM,MAAM,IAAI,GAAG,CAAC,EAAE,YAAY;CACpC;CAEA,OAAO;EAAE,GAAG;EAAG,GAAG;CAAE;AACtB;AAEA,SAAS,qBACP,MACA,OACA,OACA,QACA,MACM;CACN,KAAK,MAAM,QAAQ,KAAK,SAAS,CAAC,GAAG;EACnC,IAAI,KAAK,IAAI,KAAK,EAAE,GAAG;EACvB,KAAK,IAAI,KAAK,EAAE;EAEhB,MAAM,SAAS,qBAAqB,OAAO,KAAK,UAAU,IAAI,KAAK,UAAU,EAAE;EAC/E,MAAM,SAAS,WAAW,MAAM,OAAO,GAAG,OAAO,CAAC;EAClD,IAAI,OAAO,UAAU,GAAG,MAAM,KAAK;GAAE,QAAQ,KAAK;GAAI;EAAO,CAAC;EAE9D,KAAK,MAAM,SAAS,KAAK,UAAU,CAAC,GAAG;GACrC,IAAI,MAAM,KAAK,QAAQ,MAAM,KAAK,QAAQ,CAAC,MAAM,SAAS,CAAC,MAAM,QAAQ;GACzE,MAAM,SAAS;IACb,GAAG,OAAO,IAAI,MAAM;IACpB,GAAG,OAAO,IAAI,MAAM;IACpB,OAAO,MAAM;IACb,QAAQ,MAAM;GAChB;GACA,OAAO,KAAK;IACV,QAAQ,KAAK;IACb,MAAM,MAAM;IACZ;IACA,QAAQ;KAAE,GAAG,OAAO,IAAI,OAAO,QAAQ;KAAG,GAAG,OAAO,IAAI,OAAO,SAAS;IAAE;GAC5E,CAAC;EACH;CACF;CACA,KAAK,MAAM,SAAS,KAAK,YAAY,CAAC,GACpC,qBAAqB,OAAO,OAAO,OAAO,QAAQ,IAAI;AAE1D;AAEA,SAAS,WAAW,MAAe,SAAiB,SAA0B;CAC5E,MAAM,SAAkB,CAAC;CACzB,KAAK,MAAM,WAAW,KAAK,YAAY,CAAC,GAAG;EACzC,OAAO,KAAK;GAAE,GAAG,QAAQ,WAAW,IAAI;GAAS,GAAG,QAAQ,WAAW,IAAI;EAAQ,CAAC;EACpF,KAAK,MAAM,QAAQ,QAAQ,cAAc,CAAC,GACxC,OAAO,KAAK;GAAE,GAAG,KAAK,IAAI;GAAS,GAAG,KAAK,IAAI;EAAQ,CAAC;EAE1D,OAAO,KAAK;GAAE,GAAG,QAAQ,SAAS,IAAI;GAAS,GAAG,QAAQ,SAAS,IAAI;EAAQ,CAAC;CAClF;CACA,OAAO,aAAa,MAAM;AAC5B;AAEA,SAAS,aAAa,QAA0B;CAC9C,MAAM,MAAe,CAAC;CACtB,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,OAAO,IAAI,IAAI,SAAS;EAC9B,IAAI,QAAQ,KAAK,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,MAAO,KAAK,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,IAAK;EAC1E,IAAI,KAAK,CAAC;CACZ;CACA,OAAO;AACT;AAEA,SAAS,gBACP,OACA,WACe;CACf,MAAM,MAAM,aAAa;CACzB,MAAM,aAAa,QAAQ,QAAQ,QAAQ;CAC3C,MAAM,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM;EACvC,MAAM,WAAW,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;EACpD,MAAM,WAAW,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;EACpD,IAAI,aAAa,UAAU,OAAO,WAAW;EAG7C,QAFmB,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO,MACnC,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;CAExD,CAAC;CAED,MAAM,yBAAS,IAAI,IAAoB;CACvC,IAAI,OAAO;CACX,IAAI,cAAc,OAAO;CACzB,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,UAAU,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO;EACnD,IAAI,UAAU,cAAc,GAAG;GAC7B,IAAI,gBAAgB,OAAO,mBAAmB,QAAQ;GACtD,cAAc;EAChB;EACA,OAAO,IAAI,EAAE,QAAQ,IAAI;CAC3B;CAEA,MAAM,8BAAc,IAAI,IAAoB;CAC5C,OAAO,OAAO,KAAK,MAAM;EACvB,MAAM,IAAI,OAAO,IAAI,EAAE,MAAM,KAAK;EAClC,MAAM,QAAQ,YAAY,IAAI,CAAC,KAAK;EACpC,YAAY,IAAI,GAAG,QAAQ,CAAC;EAC5B,OAAO;GACL,QAAQ,EAAE;GACV,QAAQ,EAAE;GACV,MAAM;GACN;EACF;CACF,CAAC;AACH;AAEA,SAAS,cACP,OACA,UACA,cACgB;CAChB,MAAM,WAAW,mBAAmB,OAAO,YAAY;CACvD,MAAM,OAAO,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;CAExD,KAAK,MAAM,SAAS,MAAM,QAAQ;EAChC,MAAM,YAAY,SAAS,IAAI,SAAS,MAAM,IAAI;EAClD,IAAI,CAAC,aAAa,UAAU,SAAS,KAAK,UAAU,UAAU,GAAG;EACjE,MAAM,UAAU,gBAAgB,KAAK;EACrC,KAAK,IAAI,MAAM,IAAI;GACjB,SAAS,MAAM;GACf,QAAQ;GACR,UAAU,qBACR,MAAM,OACN,WACA,QAAQ,MAAM,QAAQ,MAAM,SAAS,UAAU,MAAM,WAAW,KAAK,CACvE;GACA;EACF,CAAC;CACH;CAEA,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC;AAC1B;;;;AAKA,eAAsB,sBACpB,OACA,UACA,UAAyB,CAAC,GACQ;CAClC,IAAI,gBAAgB,KAAK,GACvB,OAAO,eAAe,OAAO,UAAU,OAAO;CAEhD,IAAI,mBAAmB,OAAO,OAAO,GACnC,OAAO,uBAAuB,OAAO,UAAU,OAAO;CAGxD,MAAM,KAAK,YAAY,IAAI;CAC3B,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,WAAW,cAAc,OAAO,UAAU;EAAE,GAAG;EAAS;CAAU,CAAC;CACzE,MAAM,OAAiB,MAAM,OAAO,CAAC,CAAC,OAAO,QAAQ;CAErD,MAAM,2BAAW,IAAI,IAAkB;CACvC,MAAM,wBAAQ,IAAI,IAA0B;CAC5C,qBAAqB,MAAM,GAAG,GAAG,MAAM,UAAU,KAAK;CAUtD,MAAM,eAAe,gBARD,MAAM,MACvB,KAAK,MAAM;EACV,MAAM,IAAI,SAAS,IAAI,EAAE,EAAE;EAC3B,IAAI,CAAC,GAAG,OAAO;EACf,OAAO;GAAE,QAAQ,EAAE;GAAI,QAAQ;EAAE;CACnC,CAAC,CAAC,CACD,QAAQ,MAAkC,KAAK,IAEH,GAAG,SAAS;CAC3D,MAAM,SAAS,cAAc,OAAO,UAAU,YAAY;CAE1D,MAAM,WAA6B,CAAC;CACpC,MAAM,YAA+B,CAAC;CACtC,qBAAqB,MAAM,OAAO,UAAU,2BAAW,IAAI,IAAI,CAAC;CAIhE,MAAM,YAAY,gBADI,4BAA4B,OAAO,cAAc,QAEzD,GACZ,aAAa,KAAK,MAAM,EAAE,MAAM,GAChC,KAAK,IAAA,IAA6B,QAAQ,mBAAA,EAA0C,CACtF;CACA,MAAM,aAAa;CAEnB,IAAI,OAAO;CACX,IAAI,OAAO;CACX,KAAK,MAAM,KAAK,cAAc;EAC5B,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;EACjD,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM;CACpD;CACA,KAAK,MAAM,KAAK,QAAQ;EACtB,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;EACjD,OAAO,KAAK,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,OAAO,MAAM;CACpD;CACA,KAAK,MAAM,QAAQ,WACjB,KAAK,MAAM,KAAK,KAAK,QAAQ;EAC3B,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;EACzB,OAAO,KAAK,IAAI,MAAM,EAAE,CAAC;CAC3B;CAEF,KAAK,MAAM,SAAS,YAAY;EAC9B,OAAO,KAAK,IAAI,MAAM,MAAM,OAAO,IAAI,MAAM,OAAO,KAAK;EACzD,OAAO,KAAK,IAAI,MAAM,MAAM,OAAO,IAAI,MAAM,OAAO,MAAM;CAC5D;CAcA,OAAO;EACL,QAAA;GAZA,OAAO;GACP;GACA;GACA;GACA;GACA,kBAAkB;GAClB,UAAU,YAAY,IAAI,IAAI;GAC9B,OAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC,IAAI;GACzC,QAAQ,KAAK,IAAI,MAAM,KAAK,UAAU,CAAC,IAAI;EAItC;EACL,OAAO;EACP,iBAAiB;CACnB;AACF;;;AC/SA,MAAM,iBAAgC;CACpC,WAAW;CACX,SAAS;CACT,cAAc;CACd,kBAAkB;CAClB,aAAa;CACb,eAAe;AACjB;AAEA,eAAsB,gBACpB,OACA,aAA4B,CAAC,GACN;CACvB,MAAM,OAAO,aAAa,gBAAgB,UAAU;CAGpD,QAAO,MADc,sBAAsB,OAD1B,aAAa,KAC2B,CAAC,CAAC,OAAO,IAAI,EAAA,CACxD;AAChB;;;;ACrBA,IAAI,kBAAwC;AAC5C,IAAI,aAAa;AAEjB,SAAgB,oBAA6B;CAC3C,OAAO;AACT;AAEA,SAAgB,mBAAmB,SAAgC;CACjE,IAAI,OAAO,aAAa,aAAa,OAAO,QAAQ,QAAQ;CAC5D,IAAI,YAAY,OAAO,QAAQ,QAAQ;CACvC,IAAI,iBAAiB,OAAO;CAE5B,mBAAmB,YAAY;EAC7B,MAAM,OAAO,IAAI,SAAS,SAAS,OAAO,QAAQ,IAAI;GACpD,QAAQ;GACR,OAAO;EACT,CAAC;EACD,MAAM,KAAK,KAAK;EAChB,SAAS,MAAM,IAAI,IAAI;EACvB,MAAM,SAAS,MAAM,KAAK,oBAAkB;EAC5C,aAAa;CACf,EAAA,CAAG;CAEH,OAAO;AACT;;;ACnBA,MAAM,kBAAkB;;;;;AAMxB,SAAgB,qBACd,OACA,QACA,WACkB;CAClB,MAAM,UAAU,IAAI,IAAI,OAAO,MAAM,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC9D,MAAM,aAAa,IAAI,IAAI,MAAM,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;CAC5D,MAAM,YAAY,OAAO,MAAM,KAAK,OAAO;EAAE,QAAQ,EAAE;EAAQ,MAAM,EAAE;CAAO,EAAE;CAEhF,OAAO,UAAU,KAAK,SAAS;EAC7B,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM,EAAE,OAAO,KAAK,MAAM;EACzD,IAAI,CAAC,QAAS,CAAC,KAAK,cAAc,CAAC,KAAK,UAAW,OAAO;EAC1D,IAAI,KAAK,OAAO,SAAS,GAAG,OAAO;EAEnC,MAAM,WAAW,WAAW,IAAI,KAAK,IAAI;EACzC,MAAM,SAAS,WAAW,IAAI,KAAK,EAAE;EACrC,MAAM,WAAW,QAAQ,IAAI,KAAK,IAAI;EACtC,MAAM,SAAS,QAAQ,IAAI,KAAK,EAAE;EAClC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,OAAO;EAEzD,IAAI;EACJ,IAAI;EAEJ,IAAI,KAAK,cAAc,eAAe,QAAQ,GAAG;GAC/C,MAAM,MAAM,gBAAgB,SAAS,SAAS,KAAK,UAAU;GAC7D,IAAI,OAAO,GAAG,QAAQ,cAAc,SAAS,OAAO,GAAG,KAAK,SAAS,SAAS,CAAC;EACjF;EACA,IAAI,KAAK,YAAY,eAAe,MAAM,GAAG;GAC3C,MAAM,MAAM,gBAAgB,OAAO,SAAS,KAAK,QAAQ;GACzD,IAAI,OAAO,GAAG,MAAM,cAAc,OAAO,OAAO,GAAG,KAAK,OAAO,SAAS,CAAC;EAC3E;EACA,IAAI,SAAS,QAAQ,OAAO,MAAM,OAAO;EAEzC,MAAM,QAAQ,oBAAoB,SAAS,QAAQ,OAAO,QAAQ,KAAK,MAAM;EAC7E,MAAM,QAAQ,YAAY,SAAS,QAAQ,MAAM,UAAU,SAAS,KAAK,OAAO,EAAE,CAAE,CAAC;EACrF,MAAM,MAAM,YACV,OAAO,QACP,MAAM,QACN,OAAO,KAAK,OAAO,KAAK,OAAO,SAAS,EAAE,CAAE,CAC9C;EAEA,IAAI,SAAS,kBAAkB,OAAO,KAAK,KAAK,QAAQ,KAAK;EAE7D,IACE,MAAM,aAAa,MAAM,UACzB,qBAAqB,QAAQ,WAAW,KAAK,MAAM,KAAK,EAAE,GAC1D;GACA,MAAM,UAAgB,MAAM,aAAa,SAAS,UAAU;GAC5D,MAAM,WAAW;IAAE,UAAU;IAAS,QAAQ;GAAQ;GAGtD,MAAM,MAAM,kBAFK,YAAY,SAAS,QAAQ,SAAS,MAAM,CAExB,GADtB,YAAY,OAAO,QAAQ,SAAS,IAAI,CACV,GAAG,KAAK,QAAQ,QAAQ;GACrE,IAAI,CAAC,qBAAqB,KAAK,WAAW,KAAK,MAAM,KAAK,EAAE,GAC1D,SAAS;EAEb;EAEA,OAAO;GAAE,GAAG;GAAM;EAAO;CAC3B,CAAC;AACH;;AAGA,SAAgB,oBACd,YACA,UACA,UACkC;CAClC,MAAM,YAAY,WAAW,IAAI,WAAW;CAC5C,MAAM,UAAU,SAAS,IAAI,SAAS;CACtC,MAAM,aAAa,SAAS,IAAI;CAChC,MAAM,YAAY,WAAW,IAAI;CAEjC,IAAI,aAAa,GAAG,OAAO;EAAE,UAAU;EAAS,QAAQ;CAAO;CAC/D,IAAI,YAAY,GAAG,OAAO;EAAE,UAAU;EAAQ,QAAQ;CAAQ;CAI9D,MAAM,UAAU,WAAW,IAAI,WAAW,QAAQ;CAClD,MAAM,OAAO,SAAS;CAEtB,MAAM,QADa,OAAO,KAAK,KAAK,UAAU,QACd,SAAS;CACzC,OAAO;EAAE,UAAU;EAAM,QAAQ;CAAK;AACxC;AAEA,SAAS,YAAY,QAAc,MAAY,GAAkB;CAC/D,OAAO;EACL,GAAG,SAAS,SAAS,OAAO,IAAI,OAAO,IAAI,OAAO;EAClD;CACF;AACF;AAEA,SAAS,kBACP,OACA,KACA,UACA,OACS;CACT,IAAI,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,IAC9B,OAAO,CAAC,OAAO,GAAG;CAEpB,IAAI,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,IAC9B,OAAO,CAAC,OAAO,GAAG;CAIpB,IAAI,MAAM,aAAa,MAAM,QAAQ;EACnC,MAAM,OACJ,MAAM,aAAa,SACf,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,kBAC3B,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI;EACjC,OAAO;GAAC;GAAO;IAAE,GAAG;IAAM,GAAG,MAAM;GAAE;GAAG;IAAE,GAAG;IAAM,GAAG,IAAI;GAAE;GAAG;EAAG;CACpE;CAGA,MAAM,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC;CAClC,MAAM,KAAK,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC;CAClC,IAAI,QAAQ,MAAM,IAAI,IAAI,KAAK;CAC/B,MAAM,WAAW,SAAS,MAAM,GAAG,EAAE;CACrC,IAAI,SAAS,QAAQ;EACnB,MAAM,KAAK,SAAS,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC;EACxD,MAAM,YAAY,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;EAC7C,IAAI,aAAa,MAAM,aAAa,IAAI,OAAO;CACjD;CAEA,OAAO;EAAC;EAAO;GAAE,GAAG;GAAM,GAAG,MAAM;EAAE;EAAG;GAAE,GAAG;GAAM,GAAG,IAAI;EAAE;EAAG;CAAG;AACpE;AAEA,SAAS,qBACP,QACA,WACA,QACA,MACS;CACT,MAAM,0BAAU,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;EAC1C,MAAM,IAAI,OAAO;EACjB,MAAM,IAAI,OAAO,IAAI;EACrB,KAAK,MAAM,EAAE,QAAQ,UAAU,WAAW;GACxC,IAAI,QAAQ,IAAI,MAAM,GAAG;GACzB,IAAI,wBAAwB,GAAG,GAAG,IAAI,GAAG,OAAO;EAClD;CACF;CACA,OAAO;AACT;;AAGA,SAAS,wBAAwB,MAAa,IAAW,MAAqB;CAC5E,MAAM,OAAO,KAAK;CAClB,MAAM,QAAQ,KAAK,IAAI,KAAK;CAC5B,MAAM,MAAM,KAAK;CACjB,MAAM,SAAS,KAAK,IAAI,KAAK;CAC7B,MAAM,MAAM;CAEZ,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK;EACjC,MAAM,IAAI,KAAK;EACf,IAAI,KAAK,MAAM,OAAO,KAAK,SAAS,KAAK,OAAO;EAChD,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;EAChC,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;EAChC,OAAO,KAAK,QAAQ,OAAO,KAAK,OAAO;CACzC;CAEA,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK;EACjC,MAAM,IAAI,KAAK;EACf,IAAI,KAAK,OAAO,OAAO,KAAK,QAAQ,KAAK,OAAO;EAChD,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;EAChC,MAAM,KAAK,KAAK,IAAI,KAAK,GAAG,GAAG,CAAC;EAChC,OAAO,KAAK,SAAS,OAAO,KAAK,MAAM;CACzC;CAEA,OAAO;AACT;AAEA,SAAgB,qBAAqB,MAId;CACrB,IAAI,KAAK,cAAc,KAAK,UAC1B,OAAO,GAAG,KAAK,SAAS,KAAK,KAAK;CAEpC,IAAI,KAAK,UAAU,OAAO,KAAK;CAC/B,IAAI,KAAK,YAAY,OAAO,KAAK;CACjC,OAAO,KAAK;AACd"}