@libs-ui/services-grid-layout 0.2.357-20 → 0.2.357-22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/canvas/grid-layout-canvas.component.d.ts +112 -4
- package/defines/collision.define.d.ts +56 -0
- package/drag-controller.d.ts +34 -0
- package/esm2022/canvas/grid-layout-canvas.component.mjs +387 -8
- package/esm2022/defines/collision.define.mjs +329 -0
- package/esm2022/defines/gridster-config.define.mjs +4 -5
- package/esm2022/drag-controller.mjs +89 -0
- package/esm2022/grid-layout.service.mjs +245 -3
- package/esm2022/index.mjs +3 -1
- package/esm2022/interfaces/grid-layout.interface.mjs +1 -1
- package/esm2022/tree.service.mjs +20 -1
- package/fesm2022/libs-ui-services-grid-layout.mjs +1066 -14
- package/fesm2022/libs-ui-services-grid-layout.mjs.map +1 -1
- package/grid-layout.service.d.ts +100 -0
- package/index.d.ts +2 -0
- package/interfaces/grid-layout.interface.d.ts +108 -0
- package/package.json +3 -3
- package/tree.service.d.ts +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libs-ui-services-grid-layout.mjs","sources":["../../../../../libs-ui/services/grid-layout/src/defines/gridster-config.define.ts","../../../../../libs-ui/services/grid-layout/src/tree.service.ts","../../../../../libs-ui/services/grid-layout/src/grid-layout.service.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.html","../../../../../libs-ui/services/grid-layout/src/index.ts","../../../../../libs-ui/services/grid-layout/src/libs-ui-services-grid-layout.ts"],"sourcesContent":["import { CompactType, DisplayGrid, GridsterConfig, GridType } from 'gridster18';\nimport { T_gridLayout_node } from '../interfaces/grid-layout.interface';\n\n/**\n * Cấu hình gridster cho lưới CẤP TRANG.\n *\n * Mọi giá trị dưới đây đều đến từ một lỗi đã đo được trên sản phẩm thật, không phải chọn theo cảm\n * tính. Đổi bất kỳ dòng nào có dấu 🔴 sẽ làm sống lại đúng lỗi ghi trong comment.\n */\nexport const gridLayoutRootConfig = (): GridsterConfig => ({\n // 🔴 VerticalFixed — CẤM đổi sang Fit hay ScrollVertical.\n // `Fit` chia đều chiều cao khung cho số hàng đang dùng, nên card khai `rows: 2` phình từ 124px lên\n // 247px. `ScrollVertical` KHÔNG đọc `fixedRowHeight` (mã lib: chỉ `Fixed` và `VerticalFixed` đọc).\n gridType: GridType.VerticalFixed,\n\n // 🔴 None — CẤM quay lại CompactUp.\n // `CompactUp` hút mọi khối lên sát nhau NGAY sau mỗi thao tác, nên:\n // · kéo mép dưới cho khối cao thêm → chỗ khối dưới vừa nhường bị hút lấp lại tức thì, cú kéo bị\n // `checkGridCollision` báo va chạm rồi HOÀN NGUYÊN (khối đứng im dù kéo);\n // · kéo thả đổi vị trí → khối vừa nhường chỗ bị hút về ngay, khối đang kéo không có chỗ đặt và\n // treo lơ lửng giữa hai khối.\n // Muốn dồn khít thì gọi `sapGon()` của service.\n compactType: CompactType.None,\n displayGrid: DisplayGrid.OnDragAndResize,\n\n // 🔴 pushItems: true — CẤM để false.\n // `swap` của lib CHỈ hoán vị được HAI KHỐI CÙNG KÍCH THƯỚC (mã lib `checkSwap`: tính diffX/diffY\n // rồi hoán vị, lệch kích thước thì `checkCollision` báo va chạm và hoàn nguyên). Khối 3x2 gặp\n // container 7x5 nên không swap được, mà `pushItems: false` cũng không cho container nhường đường\n // → BẾ TẮC: khối đang kéo không đặt được ở đâu.\n pushItems: true,\n // chỉ đẩy XUỐNG: đẩy ngang làm xô lệch bố cục cột người dùng vừa đặt\n pushDirections: { north: false, east: false, south: true, west: false },\n pushResizeItems: true,\n swap: true,\n swapWhileDragging: true,\n\n draggable: {\n enabled: true,\n // 🔴 KHÔNG được bỏ. Không có nó thì gridster vào chế độ kéo ngay từ `mousedown`, nên chỉ bấm\n // CHỌN một khối là nó đã nhích theo dù chuột đứng yên. Lib tự huỷ kéo khi nhả chuột trước mốc\n // này nên cú bấm chọn vẫn ăn nguyên vẹn.\n delayStart: 160,\n // 🔴 `checkDragHandleClass` duyệt DOM từ chỗ bấm NGƯỢC LÊN CHA, và trên MỖI node nó kiểm\n // `dragHandleClass` TRƯỚC `ignoreContentClass`. Vì vậy một phần tử KHÔNG được mang cả hai class\n // cùng lúc — mang cả hai thì lib gặp tay cầm trước, trả `true`, class chặn không tới lượt.\n ignoreContentClass: 'libs-ui-grid-layout-block-parent-drag',\n ignoreContent: true,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle',\n },\n\n resizable: {\n enabled: true,\n // đủ 8 hướng như cửa sổ thường; chỉ có góc dưới-phải thì quá khó trúng\n handles: { s: true, e: true, n: true, w: true, se: true, ne: true, sw: true, nw: true },\n },\n\n margin: 12,\n outerMargin: true,\n outerMarginBottom: 40,\n minCols: 12,\n maxCols: 12,\n minRows: 2,\n\n // 🔴 KHÔNG giới hạn chiều cao khối. Lib có BA trần mặc định phải vô hiệu hoá CÙNG LÚC, thiếu một\n // cái là vẫn bị chặn: `maxItemRows: 50` · `maxItemCols: 50` · `maxItemArea: 2500` (trần DIỆN TÍCH\n // cols × rows — khó thấy nhất: khối 12 cột chỉ cần 209 hàng là đụng trần dù hai trần kia còn dư).\n // `maxRows` là trần của CẢ LƯỚI, cũng phải nới theo.\n maxRows: 5000,\n maxItemRows: 5000,\n maxItemCols: 12,\n maxItemArea: 60000,\n\n // 🔴 Trần LỚP CHỒNG. Mặc định của lib là 2 — quá thấp: khi bật chồng khối, thư viện gán mỗi khối\n // một lớp riêng để chúng khác nhau, nên chỉ 3 khối là đã đụng trần và các khối sau lại rơi về\n // cùng lớp, tức chồng nhau bị chặn trở lại.\n maxLayerIndex: 5000,\n\n setGridSize: true,\n fixedRowHeight: 56,\n defaultItemCols: 3,\n defaultItemRows: 2,\n minItemRows: 1,\n mobileBreakpoint: -1,\n});\n\n/**\n * Cấu hình cho lưới LỒNG (ruột một container).\n *\n * Kế thừa lưới trang rồi ghi đè phần khác biệt. Ba điểm quan trọng nhất: `setGridSize` phải TẮT,\n * tay cầm phải mang TÊN RIÊNG, và tự-cuộn-khi-kéo phải TẮT.\n */\nexport const gridLayoutNestedConfig = (): GridsterConfig => ({\n ...gridLayoutRootConfig(),\n\n // 🔴 PHẢI tắt cho lưới lồng. `setGridSize` làm gridster tự ghi style width/height lên CHÍNH nó,\n // sinh vòng lặp đo-rồi-ghi với ResizeObserver của khung ngoài (khung đổi → onResize xoá style →\n // setGridSize ghi lại) → lưới con co dần về 64x64px trong khung 868px.\n setGridSize: false,\n\n // khe 2px: khối con là các dòng thông tin của CÙNG một card, khe rộng làm chúng trông như card rời\n margin: 2,\n // Lưới lồng KHÔNG tự chừa lề — lề là của VỎ container (`containerPadding`), không phải của lưới.\n // Đặt ở vỏ thì ruột co lại đúng bằng phần còn lại, tay cầm resize của khối con luôn nằm trong tầm\n // chuột (người dùng chốt 28/08/2026: \"lưới cha có padding chứ ko phải con\").\n outerMargin: false,\n outerMarginBottom: 0,\n\n // hàng 16px cho bước kéo mịn, và sàn 1 hàng = 16px nên khối co được nhỏ hơn nhiều\n fixedRowHeight: 16,\n minRows: 1,\n minItemRows: 1,\n defaultItemCols: 2,\n defaultItemRows: 2,\n\n // 🔴 Tay cầm RIÊNG — CẤM dùng chung tên với lưới trang.\n // `checkDragHandleClass` trả `true` ở node ĐẦU TIÊN có `dragHandleClass`. Dùng chung một tên thì\n // lưới CHA cũng nhận ra tay cầm của khối con và nhấc luôn container.\n draggable: {\n ...gridLayoutRootConfig().draggable,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle-child',\n },\n\n // 🔴 KÉO MÉP thì khối dưới ĐỨNG YÊN, chỉ khoảng trống giữa hai khối co giãn. Bật (kế thừa từ lưới\n // trang) thì mỗi cú kéo đẩy dồn cả cột xuống — người dùng chỉ muốn một khối to hơn một chút mà cả\n // card dài ra. `pushItems` vẫn giữ: nó lo việc KÉO THẢ đổi chỗ, khác việc đổi kích thước.\n pushResizeItems: false,\n\n // 🔴 Tắt tự cuộn khi kéo tới sát mép. Lib thấy chuột gần biên là cuộn lưới theo\n // (`scrollSensitivity`), nhưng lưới con nằm trong card có `overflow: hidden` — cuộn ở đây đẩy khối\n // con ra NGOÀI khung container rồi kẹt luôn ở đó.\n disableScrollHorizontal: true,\n disableScrollVertical: true,\n});\n\n/**\n * Cây rỗng dùng khi chưa có dữ liệu — mặt phẳng vẽ ra một lưới trống thay vì vỡ.\n * Xảy ra trong nhịp giữa lúc component dựng và lúc `init()` chạy.\n */\nexport const emptyRootNode = (): T_gridLayout_node => ({ id: 'root', x: 0, y: 0, cols: 12, rows: 0, children: [] });\n","import { Injectable } from '@angular/core';\nimport { uuid } from '@libs-ui/utils';\nimport { T_gridLayout_newNode, T_gridLayout_node } from './interfaces/grid-layout.interface';\n\n/**\n * Thao tác trên cây khối: tìm, thêm, xoá, dồn khít, chặn lồng cấp quá sâu.\n *\n * 🔴 NỘI BỘ thư viện — không xuất ra ngoài. Nơi dùng đi qua `LibsUiGridLayoutService`, ở đó mỗi\n * thao tác sửa bố cục vừa vẽ lại vừa bắn `outChange` đúng MỘT lần. Các hàm ở đây cố tình KHÔNG tự\n * vẽ lại: để chúng tự gọi thì mỗi thao tác vẽ hai lượt và bắn hai sự kiện (người dùng chốt\n * 28/08/2026: \"đặt đúng các điểm mà làm cho layout có thể thay đổi thôi\").\n */\n@Injectable()\nexport class LibsUiGridLayoutTreeService {\n findById(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n if (node.id === id) {\n return node;\n }\n\n for (const child of node.children ?? []) {\n const found = this.findById(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n findParent(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n for (const child of node.children ?? []) {\n if (child.id === id) {\n return node;\n }\n\n const found = this.findParent(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n /**\n * Thêm khối vào cuối một container. Thư viện tự sinh `id` và tự đặt `x` · `y` xuống hàng trống.\n *\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addChild(root: T_gridLayout_node, parentId: string, item: T_gridLayout_newNode): T_gridLayout_node | undefined {\n const parent = this.findById(root, parentId);\n\n if (!parent) {\n return undefined;\n }\n\n parent.children = parent.children ?? [];\n // 🔴 Thư viện tự sinh `id`. Đây là mã máy dùng để tra cứu, không phải thứ người dùng nghĩ ra —\n // bắt họ tự đặt là mời họ tạo trùng, mà trùng id thì `findById` trả nhầm khối và cả cây hỏng\n // im lặng (người dùng chốt 28/08/2026).\n const node: T_gridLayout_node = { ...item, id: item.id ?? uuid(), x: 0, y: this.nextFreeRow(parent.children) };\n\n parent.children.push(node);\n\n // Trả về khối vừa tạo để nơi dùng biết `id` thư viện vừa sinh.\n return node;\n }\n\n /** Xoá một khối khỏi cây. Không cho xoá gốc. */\n removeById(root: T_gridLayout_node, id: string): boolean {\n if (root.id === id) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n if (!parent?.children) {\n return false;\n }\n\n parent.children = parent.children.filter((item) => item.id !== id);\n\n return true;\n }\n\n /**\n * Chuyển một khối đơn thành CONTAINER: nội dung cũ trở thành khối con đầu tiên.\n *\n * Không mất dữ liệu — `data` của khối được mang theo xuống khối con.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối đã là container rồi.\n */\n toContainer(root: T_gridLayout_node, id: string, colCount: number): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) > 0) {\n return false;\n }\n\n node.children = [{ ...node, id: uuid(), x: 0, y: 0, cols: colCount, rows: 4, children: [] }];\n\n return true;\n }\n\n /**\n * Chuyển một CONTAINER về khối đơn: các khối con được NÂNG lên cấp trên, không bị xoá.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối vốn không phải container.\n */\n toSingle(root: T_gridLayout_node, id: string): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) === 0) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n for (const child of node.children ?? []) {\n parent?.children?.push({ ...child, cols: node.cols, rows: 2 });\n }\n\n node.children = [];\n\n return true;\n }\n\n /**\n * Làm phẳng mọi container lồng vượt trần.\n *\n * 🔴 Cần thiết vì bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện. Một bản lưu cũ — sinh\n * trước khi có trần, hoặc do thao tác lỗi — vẫn nạp thẳng vào và hiện container lồng container.\n * Container vượt trần bị hạ thành khối thường, con của nó nâng lên cấp trên: KHÔNG mất dữ liệu.\n *\n * @returns số container đã làm phẳng\n */\n flattenOverDepthContainers(node: T_gridLayout_node, maxDepth: number): number {\n return this.walkFlatten(node, 0, maxDepth);\n }\n\n /**\n * Dồn khối khít lên trên theo thứ tự đọc, lấp hết chỗ trống.\n *\n * 🔴 KHÔNG sửa `node.rows` của container. Chiều cao container tính theo đơn vị hàng của lưới CHA,\n * còn `currentRow` đếm theo đơn vị hàng của lưới CON — trộn hai thang đo là container phình lên\n * gấp mấy lần.\n */\n compact(node: T_gridLayout_node, colCount: number): void {\n this.walkCompact(node, colCount);\n }\n\n private walkCompact(node: T_gridLayout_node, colCount: number): void {\n const children = node.children;\n\n if (!children?.length) {\n return;\n }\n\n const inReadingOrder = [...children].sort((a, b) => a.y - b.y || a.x - b.x);\n let currentRow = 0;\n let usedCols = 0;\n let tallestInRow = 0;\n\n for (const item of inReadingOrder) {\n const width = Math.min(item.cols, colCount);\n\n if (usedCols > 0 && usedCols + width > colCount) {\n currentRow += tallestInRow;\n usedCols = 0;\n tallestInRow = 0;\n }\n\n item.x = usedCols;\n item.y = currentRow;\n item.cols = width;\n usedCols += width;\n tallestInRow = Math.max(tallestInRow, item.rows);\n\n if ((item.children?.length ?? 0) > 0) {\n this.walkCompact(item, colCount);\n }\n }\n }\n\n private walkFlatten(node: T_gridLayout_node, containerDepth: number, maxDepth: number): number {\n const children = node.children;\n\n if (!children?.length) {\n return 0;\n }\n\n let fixedCount = 0;\n const result: Array<T_gridLayout_node> = [];\n\n for (const child of children) {\n const isContainer = (child.children?.length ?? 0) > 0;\n\n if (isContainer && containerDepth >= maxDepth) {\n fixedCount += 1;\n\n for (const item of child.children ?? []) {\n fixedCount += this.walkFlatten(item, containerDepth, maxDepth);\n result.push(item);\n }\n\n continue;\n }\n\n fixedCount += this.walkFlatten(child, isContainer ? containerDepth + 1 : containerDepth, maxDepth);\n result.push(child);\n }\n\n node.children = result;\n\n return fixedCount;\n }\n\n private nextFreeRow(children: Array<T_gridLayout_node>): number {\n return children.reduce((max, child) => Math.max(max, child.y + child.rows), 0);\n }\n}\n","import { ComponentRef, DestroyRef, Injectable, ViewContainerRef, inject, signal } from '@angular/core';\nimport { GridsterConfig, GridsterItem } from 'gridster18';\nimport { cloneDeep } from '@libs-ui/utils';\nimport { Subscription, take } from 'rxjs';\nimport { gridLayoutNestedConfig, gridLayoutRootConfig } from './defines/gridster-config.define';\nimport { LibsUiGridLayoutTreeService } from './tree.service';\nimport {\n E_gridLayout_mode_string,\n T_gridLayout_changeEvent,\n T_gridLayout_newNode,\n T_gridLayout_config,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\n\n/**\n * Dựng một mặt phẳng kéo thả và tự gắn component của nơi dùng lên từng khối.\n *\n * Nơi dùng chỉ cần đưa vào: loại component muốn dựng\n * (`nodeComponentType`) và cây dữ liệu (`data`). Toàn bộ việc vẽ lưới, kéo thả, đổi kích thước,\n * lồng container và dọn dẹp do thư viện lo.\n *\n * 🔴 Đây là service theo TỪNG mặt phẳng, KHÔNG `providedIn: 'root'`. Khai trong `providers` của\n * component dùng nó; hai mặt phẳng trên cùng một màn phải là hai thực thể riêng, dùng chung thì\n * `componentRefs` của mặt phẳng này bị mặt phẳng kia dọn mất.\n */\n@Injectable()\nexport class LibsUiGridLayoutService {\n // 🔴 TỰ TẠO, không `inject`. Nơi dùng chỉ phải viết `providers: [LibsUiGridLayoutService]` —\n // không phải biết bên trong thư viện còn service nào khác (người dùng chốt 28/08/2026).\n // `TreeService` không giữ trạng thái dùng chung nên mỗi mặt phẳng một bản là đúng.\n private readonly treeService = new LibsUiGridLayoutTreeService();\n /** Lượt tải component đang chờ, theo id khối — để huỷ khi khối bị gỡ giữa chừng. */\n private readonly pendingLoads = new Map<string, Subscription>();\n\n constructor() {\n // 🔴 Service khai trong `providers` của component nên Angular huỷ nó cùng component — thư viện\n // tự dọn ở đây, nơi dùng KHÔNG phải gọi `destroy()` trong `ngOnDestroy` (người dùng chốt\n // 28/08/2026). Bắt nhớ một bước dọn dẹp là kiểu API dễ quên, và quên thì rò rỉ bộ nhớ im lặng.\n inject(DestroyRef).onDestroy(() => this.destroy());\n }\n\n private config?: T_gridLayout_config;\n private readonly componentRefs = new Map<string, ComponentRef<unknown>>();\n\n private readonly rootNode = signal<T_gridLayout_node | undefined>(undefined);\n private readonly editMode = signal<boolean>(false);\n /** tăng mỗi lần cây đổi — component con đọc để biết phải tính lại */\n private readonly version = signal<number>(0);\n\n /**\n * Signal chỉ đọc để nơi dùng theo dõi.\n *\n * 🔴 Là THUỘC TÍNH, không phải getter. Getter trả signal thì chỗ đọc phải viết `Version()()` —\n * quên cặp ngoặc thứ hai là computed KHÔNG phụ thuộc vào nó, cây đổi mà lưới đứng im, và\n * TypeScript không hề báo lỗi (đo 28/08/2026: thêm khối không hiện, sắp gọn không nhúc nhích).\n */\n readonly Root = this.rootNode.asReadonly();\n readonly IsEditMode = this.editMode.asReadonly();\n /** tăng mỗi lần cây hoặc cấu hình đổi */\n readonly Version = this.version.asReadonly();\n\n /**\n * trần số cấp container lồng nhau — canvas đọc để biết có cho chuyển thành container không */\n private maxContainerDepth(): number {\n return this.config?.maxContainerDepth ?? 1;\n }\n\n /**\n * lề trong của container, px — canvas đọc để đặt padding lên vỏ container */\n private containerPadding(): number {\n return this.config?.containerPadding ?? 12;\n }\n\n /** Khởi tạo mặt phẳng. Gọi lại sẽ dọn sạch component cũ rồi dựng lại từ đầu. */\n init(config: T_gridLayout_config): void {\n this.destroy();\n this.config = config;\n // 🔴 Bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện: bản lưu cũ (sinh trước khi có trần,\n // hoặc do thao tác lỗi) vẫn mang container lồng container. Trần `maxContainerDepth` chỉ ẩn NÚT\n // trên canvas — nó không sửa dữ liệu, nên thiếu dòng này là vẽ ra đúng cây quá sâu đó.\n // Nơi dùng KHÔNG tự gọi được: `LibsUiGridLayoutTreeService` cố ý không xuất.\n this.treeService.flattenOverDepthContainers(config.data, this.maxContainerDepth());\n this.assignOverlapLayers(config.data);\n // 🔴 Nhân bản như `refresh()`: `init()` lại (đổi chế độ, bật/tắt chồng khối) trên CÙNG object cây\n // thì `@for` không dựng lại `gridster-item`, nên `layerIndex` vừa gán không tới `$item` và khối\n // vẫn không đè nhau được (đo 28/08/2026: `item.layerIndex` = 1|2|3|4|7 mà `$item.layerIndex`\n // toàn `undefined`).\n this.rootNode.set(this.shallowCloneTree(config.data));\n this.editMode.set(config.isEditMode ?? false);\n this.version.update((v) => v + 1);\n }\n\n setEditMode(value: boolean): void {\n this.editMode.set(value);\n // 🔴 PHẢI bơm `version`: `gridsterOptions()` đọc `editMode` để bật/tắt kéo–thả, mà computed\n // `gridOptions` bên canvas chỉ chạy lại khi `Version` đổi. Thiếu dòng này thì đổi chế độ xong\n // gridster vẫn giữ options cũ — chuyển sang XEM mà khối vẫn kéo được.\n this.version.update((v) => v + 1);\n }\n\n /**\n * Bật/tắt cho khối chồng lên nhau — KHÔNG dựng lại mặt phẳng.\n *\n * Trước đây nơi dùng phải gọi `init()` lại để đổi cờ này, mà `init()` huỷ sạch rồi dựng lại mọi\n * component nội dung — lãng phí, và người dùng thấy màn chớp (người dùng chốt 28/08/2026).\n */\n setAllowOverlap(value: boolean): void {\n if (!this.config) {\n return;\n }\n\n this.config = { ...this.config, allowOverlap: value };\n\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n // 🔴 Gán lớp vào CÂY ĐANG VẼ (`rootNode`), KHÔNG phải `config.data`.\n // `init()` đã clone `config.data` sang `rootNode` nên hai object KHÁC nhau; gán vào `config.data`\n // thì `refresh()` clone lại từ `rootNode` — lớp vừa gán không tới `gridster-item` nào, `z-index`\n // của mọi khối đứng ở `1` và khối nào vẽ sau thì nằm trên: chồng khối \"lúc được lúc không\"\n // (đo 04/09/2026: `item.layerIndex` undefined, `getLayerIndex()` = 0 cho cả 8 khối).\n this.assignOverlapLayers(root);\n // Thay tham chiếu cây để `layerIndex` vừa gán tới được `$item` của gridster; component nội dung\n // KHÔNG bị dựng lại vì `attachNode` nhận ra id cũ và chỉ `setInput`.\n this.refresh();\n }\n\n /**\n *\n * Cấu hình gridster cho một cấp lưới.\n *\n * @param depth 0 = lưới cấp trang, ≥ 1 = lưới lồng trong container\n */\n private buildGridsterOptions(depth: number, itemChangeCallback?: () => void): GridsterConfig {\n const base = depth === 0 ? gridLayoutRootConfig() : gridLayoutNestedConfig();\n const config = this.config;\n\n if (!config) {\n return base;\n }\n\n const isFreeMode = config.mode === E_gridLayout_mode_string.free;\n const canEdit = this.editMode();\n const canOverlap = isFreeMode || (config.allowOverlap ?? false);\n\n return {\n ...base,\n ...(config.cols ? { minCols: config.cols, maxCols: config.cols, maxItemCols: config.cols } : {}),\n ...(config.rowHeight && depth === 0 ? { fixedRowHeight: config.rowHeight } : {}),\n // Khe và chiều cao hàng khác nhau theo cấp: lưới trang thoáng, lưới lồng khít.\n ...(depth === 0 && config.margin !== undefined ? { margin: config.margin } : {}),\n ...(depth > 0 && config.nestedMargin !== undefined ? { margin: config.nestedMargin } : {}),\n ...(depth > 0 && config.nestedRowHeight !== undefined ? { fixedRowHeight: config.nestedRowHeight } : {}),\n ...(depth === 0 && config.outerMargin !== undefined ? { outerMargin: config.outerMargin } : {}),\n ...(depth === 0 && config.outerMarginBottom !== undefined ? { outerMarginBottom: config.outerMarginBottom } : {}),\n ...(config.minItemRows !== undefined ? { minItemRows: config.minItemRows } : {}),\n ...(config.defaultItemCols !== undefined ? { defaultItemCols: config.defaultItemCols } : {}),\n ...(config.defaultItemRows !== undefined ? { defaultItemRows: config.defaultItemRows } : {}),\n\n // 🔴 Chế độ XEM phải TẮT hẳn kéo và đổi kích thước.\n // `base` luôn để `enabled: true`; không ghi đè theo `editMode` thì người xem vẫn kéo được khối\n // và đổi bố cục của người khác (người dùng báo 28/08/2026: \"đang xem mà vẫn kéo thả thay đổi\n // vị trí và thêm khối được\").\n draggable: { ...base.draggable, enabled: canEdit },\n resizable: { ...base.resizable, enabled: canEdit },\n\n // Chế độ tự do LUÔN cho chồng; chế độ lưới thì theo cờ của nơi dùng.\n allowMultiLayer: canOverlap,\n // 🔴 Bật `allowMultiLayer` MỘT MÌNH không đủ. Mã lib so `layerIndex` của hai khối: KHÁC nhau\n // thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n // `defaultLayerIndex` — tức cùng lớp, và vẫn bị đẩy nhau như lưới thường (người dùng báo\n // 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n // Cho chồng thì phải TẮT đẩy khối, nếu không khối bị dạt đi trước khi kịp đè lên nhau.\n ...(canOverlap ? { pushItems: false, pushResizeItems: false, swap: false, swapWhileDragging: false } : {}),\n\n itemChangeCallback: (item: GridsterItem) => {\n // 🔴 Khối vừa thao tác phải lên LỚP TRÊN CÙNG.\n // `layerIndex` gán một lần theo thứ tự cây lúc khởi tạo, nên khối kéo lên chỉ nổi TRONG LÚC\n // kéo (nhờ `z-index: 30` của lớp `gridster-item-moving`); thả tay ra là về lớp cũ và bị khối\n // đứng sau trong cây đè ngược lên (người dùng báo 28/08/2026, đo được: kéo z=30, thả về\n // z=10 trong khi hai khối kế bên đang z=11 và z=12).\n if (canOverlap) {\n this.raiseToTopLayer(item);\n }\n\n this.version.update((v) => v + 1);\n itemChangeCallback?.();\n },\n };\n }\n\n /**\n *\n * Gắn component của nơi dùng lên một khối.\n *\n * @param host chỗ gắn RIÊNG của ô đó — mỗi khối một `ViewContainerRef`, dùng chung một cái thì\n * mọi component bị dồn hết vào một ô.\n */\n private attachNode(node: T_gridLayout_node, depth: number, host: ViewContainerRef): void {\n const config = this.config;\n\n if (!config) {\n return;\n }\n\n const existing = this.componentRefs.get(node.id);\n\n if (existing) {\n this.applyInputs(existing, node, depth);\n\n return;\n }\n\n // Khối tự khai thì hỏi nó; không thì hỏi hàm phân giải chung. Cả hai đều nhận `node` để đọc\n // được `data.type` mà quyết định trả component nào.\n const stream = (node.getComponentOutlet ?? config.getComponentOutlet)?.(node);\n\n if (!stream) {\n return;\n }\n\n // 🔴 Huỷ lượt tải CŨ của đúng khối này trước khi mở lượt mới.\n // Khối bị gỡ rồi gắn lại (đổi bố cục, sắp gọn) trong lúc `import()` chưa xong thì lượt cũ vẫn\n // chạy tiếp và dựng component vào một `ViewContainerRef` đã chết.\n this.pendingLoads.get(node.id)?.unsubscribe();\n\n const sub = stream.pipe(take(1)).subscribe((componentType) => {\n this.pendingLoads.delete(node.id);\n\n // Khối có thể đã bị xoá trong lúc chờ tải — dựng vào đây là rò rỉ.\n if (!this.treeService.findById(this.rootNode() ?? node, node.id)) {\n return;\n }\n\n const ref = host.createComponent(componentType);\n\n this.applyInputs(ref, node, depth);\n this.componentRefs.set(node.id, ref);\n });\n\n this.pendingLoads.set(node.id, sub);\n }\n\n /**\n * Gỡ component của một khối và huỷ nó. */\n private detachNode(nodeId: string): void {\n // Khối bị gỡ khi component của nó còn đang tải — phải huỷ lượt tải, không thì nó dựng vào một\n // `ViewContainerRef` đã chết.\n this.pendingLoads.get(nodeId)?.unsubscribe();\n this.pendingLoads.delete(nodeId);\n\n const ref = this.componentRefs.get(nodeId);\n\n if (!ref) {\n return;\n }\n\n ref.destroy();\n this.componentRefs.delete(nodeId);\n }\n\n private destroy(): void {\n for (const sub of this.pendingLoads.values()) {\n sub.unsubscribe();\n }\n\n for (const ref of this.componentRefs.values()) {\n ref.destroy();\n }\n\n this.pendingLoads.clear();\n this.componentRefs.clear();\n this.config = undefined;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // Nhóm hàm cho nơi dùng CHỦ ĐỘNG gọi — không phải chờ người dùng bấm nút trên khối.\n // Sửa cây thì dùng thẳng `TreeService` rồi gọi `refresh()` — xem demo trong core-ui.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Báo cho service biết cây vừa đổi từ bên ngoài (thêm/xoá khối, sắp gọn, nạp bố cục khác).\n *\n * 🔴 PHẢI thay THAM CHIẾU của node gốc, không chỉ bơm `version`.\n * `@for … track item.id` giữ nguyên object khi id không đổi, nên `<gridster-item [item]=\"…\">` vẫn\n * nhận đúng object cũ và gridster không hề biết `x/y/cols/rows/layerIndex` vừa bị sửa. Bơm mỗi\n * `version` thì computed chạy lại nhưng trả về CÙNG mảng cũ — lưới đứng im (đo 28/08/2026: bấm\n * \"Sắp gọn\" cây đã dồn khít mà màn hình không nhúc nhích; bật chồng khối mà `$item.layerIndex`\n * vẫn trống).\n *\n * Nhân bản NÔNG cả node gốc và danh sách con là đủ: mảng mới → `@for` dựng lại item, object con\n * mới → gridster đọc lại toàn bộ toạ độ.\n */\n refresh(event?: T_gridLayout_changeEvent): void {\n const root = event?.root ?? this.rootNode();\n\n if (!root) {\n this.version.update((v) => v + 1);\n\n return;\n }\n\n if (this.config) {\n this.config = { ...this.config, data: root };\n }\n\n this.rootNode.set(this.shallowCloneTree(root));\n this.version.update((v) => v + 1);\n }\n\n /** Nhân bản nông theo cả chiều sâu: mỗi node và mảng `children` thành tham chiếu mới. */\n /**\n * Nhân bản SÂU cả cây — dùng cho `exportLayout()`.\n *\n * 🔴 BỎ `getComponentOutlet` khỏi bản sao: nó là một HÀM, không tuần tự hoá được nên gửi xuống\n * backend là hỏng (`JSON.stringify` nuốt mất, `structuredClone` ném lỗi). Nạp lại thì hàm phân\n * giải chung của cấu hình lo — component suy ra từ `data.type`, không cần lưu.\n */\n private deepCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n const copy: T_gridLayout_node = { ...node };\n\n // Cắt hàm phân giải — xem chú thích trên.\n delete copy.getComponentOutlet;\n\n const { children, data, ...rest } = copy;\n\n return {\n ...rest,\n ...(data === undefined ? {} : { data: cloneDeep(data) }),\n ...(children ? { children: children.map((child) => this.deepCloneTree(child)) } : {}),\n };\n }\n\n private shallowCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n if (!node.children?.length) {\n return { ...node };\n }\n\n return { ...node, children: node.children.map((child) => this.shallowCloneTree(child)) };\n }\n\n /**\n * Gán `layerIndex` khác nhau cho từng khối khi bật chồng khối.\n *\n * 🔴 `allowMultiLayer: true` MỘT MÌNH không cho khối đè nhau. Mã lib so `layerIndex` của hai khối:\n * KHÁC nhau thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n * `defaultLayerIndex` — tức CÙNG lớp, nên kéo vào nhau là bị chặn y như lưới thường (người dùng\n * báo 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n *\n * Nơi dùng tự khai `layerIndex` thì giữ nguyên; ai không khai thì thư viện xếp mỗi khối một lớp\n * theo thứ tự, đủ để mọi cặp đều khác lớp.\n */\n private assignOverlapLayers(root: T_gridLayout_node): void {\n const config = this.config;\n const canOverlap = config?.mode === E_gridLayout_mode_string.free || (config?.allowOverlap ?? false);\n\n if (!canOverlap) {\n return;\n }\n\n let layer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n if (child.layerIndex === undefined) {\n layer += 1;\n child.layerIndex = layer;\n }\n\n walk(child);\n }\n };\n\n walk(root);\n\n }\n\n /** Đưa một khối lên trên tất cả: lớp của nó = lớp lớn nhất đang có + 1. */\n private raiseToTopLayer(item: GridsterItem): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n let topLayer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n topLayer = Math.max(topLayer, child.layerIndex ?? 0);\n walk(child);\n }\n };\n\n walk(root);\n\n // `item` gridster trả về CHÍNH là object node của cây (truyền thẳng qua `[item]`), nên gán vào\n // đây là cây cũng đổi theo.\n const node = item as unknown as T_gridLayout_node;\n\n if (node.layerIndex === topLayer) {\n\n return;\n }\n\n node.layerIndex = topLayer + 1;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // SỬA CÂY — thư viện đã giữ cây nên bạn KHÔNG phải truyền nó vào.\n // Mọi hàm dưới đây tự vẽ lại; không cần gọi `refresh()`.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Thêm một khối.\n *\n * @param item khối mới — KHÔNG cần `id` (thư viện sinh) và `x`/`y` (tự đặt xuống hàng trống).\n * @param parentId container muốn thêm vào; bỏ trống thì thêm vào mặt phẳng gốc.\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addBlock(item: T_gridLayout_newNode, parentId?: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root ? this.treeService.addChild(root, parentId ?? root.id, item) : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n /** Xoá một khối. Xoá container là xoá cả ruột. Trả `false` khi không xoá được (vd khối gốc). */\n removeBlock(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.removeById(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Biến khối đơn thành CONTAINER — nội dung cũ thành khối con đầu tiên, không mất dữ liệu. */\n toContainer(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toContainer(root, id, this.config?.cols ?? 12) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Đưa CONTAINER về khối đơn — khối con được nâng lên cấp trên, không bị xoá. */\n toSingle(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toSingle(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Dồn khối khít lên trên, lấp hết chỗ trống. Đệ quy vào container. */\n compact(): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n this.treeService.compact(root, this.config?.cols ?? 12);\n this.refresh();\n }\n\n /**\n * Bố cục HIỆN TẠI, đã cắt mọi tham chiếu — gửi thẳng xuống backend được.\n *\n * Dùng khi bấm nút Lưu. Khác `Root()` ở chỗ đây là bản SAO: nơi dùng có sửa gì trên kết quả cũng\n * không đụng tới cây mà thư viện đang vẽ.\n *\n * @returns `undefined` khi mặt phẳng chưa `init()`.\n */\n exportLayout(): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.deepCloneTree(root) : undefined;\n }\n\n /** Tìm một khối theo id. */\n findBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findById(root, id) : undefined;\n }\n\n /** Tìm khối cha trực tiếp của một khối. */\n findParentBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findParent(root, id) : undefined;\n }\n\n /**\n * Cổng DUY NHẤT cho canvas của thư viện. Nơi dùng KHÔNG gọi tới đây.\n *\n * Mọi thứ canvas cần đều là `private` để không lọt ra API công khai; gom vào một getter theo đúng\n * khuôn `FunctionsControl` của bộ quy ước, thay vì để rải rác hàm public mà người ngoài tưởng\n * mình phải gọi (người dùng chốt 28/08/2026).\n */\n get FunctionsControl() {\n return {\n maxContainerDepth: () => this.maxContainerDepth(),\n containerPadding: () => this.containerPadding(),\n gridsterOptions: (depth: number, cb?: () => void) => this.buildGridsterOptions(depth, cb),\n attachNode: (node: T_gridLayout_node, depth: number, host: ViewContainerRef) => this.attachNode(node, depth, host),\n detachNode: (nodeId: string) => this.detachNode(nodeId),\n };\n }\n\n private applyInputs(ref: ComponentRef<unknown>, node: T_gridLayout_node, depth: number): void {\n ref.setInput('data', node.data);\n ref.setInput('node', node);\n ref.setInput('isEditMode', this.editMode());\n ref.setInput('depth', depth);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n OnDestroy,\n ViewContainerRef,\n computed,\n inject,\n input,\n output,\n effect,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { GridsterComponent, GridsterModule } from 'gridster18';\nimport { emptyRootNode } from '../defines/gridster-config.define';\nimport { LibsUiGridLayoutService } from '../grid-layout.service';\nimport {\n T_gridLayout_actionEvent,\n T_gridLayout_addEvent,\n T_gridLayout_changeEvent,\n T_gridLayout_newNode,\n T_gridLayout_node,\n} from '../interfaces/grid-layout.interface';\n\n/**\n * Mặt phẳng kéo thả. Đệ quy: khối có `children` thì ruột nó lại là một mặt phẳng nữa.\n *\n * Nơi dùng KHÔNG dựng component này trực tiếp cho từng khối — chỉ đặt MỘT thẻ ở gốc và truyền\n * `nodeComponentType` qua `LibsUiGridLayoutService.init()`. Thư viện tự gắn component cho mọi khối.\n */\n@Component({\n selector: 'libs_ui-services-grid_layout-canvas',\n standalone: true,\n imports: [GridsterModule, LibsUiComponentsButtonsButtonComponent],\n templateUrl: './grid-layout-canvas.component.html',\n styleUrl: './grid-layout-canvas.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiGridLayoutCanvasComponent implements OnDestroy {\n /**\n * @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền khi vẽ ruột container.\n *\n * Nơi dùng KHÔNG truyền: mặt phẳng gốc đọc cây từ service (đã đưa vào qua `init()`), truyền thêm\n * ở đây là khai hai lần cùng một thứ (người dùng chốt 28/08/2026).\n */\n readonly node = input<T_gridLayout_node>();\n /** @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền. */\n readonly depth = input<number>(0);\n\n /**\n * Bố cục vừa đổi do NGƯỜI DÙNG kéo hoặc đổi kích thước khối.\n *\n * Nơi dùng tự gọi `addBlock` · `removeBlock` · `compact` thì KHÔNG bắn — họ vừa gọi thì đã biết,\n * bắn ngược lại là thừa (người dùng chốt 28/08/2026).\n */\n readonly outChange = output<T_gridLayout_changeEvent>();\n /**\n * Người dùng bấm nút XOÁ trên một khối. Thư viện CHƯA xoá — gọi `event.confirm()` để xoá thật.\n * Cần hỏi trước thì hỏi xong mới gọi; không cho phép thì đừng gọi.\n */\n readonly outRemoveNode = output<T_gridLayout_actionEvent>();\n /**\n * Người dùng bấm nút THÊM trên một container. Thư viện KHÔNG tự thêm — nó không biết bạn có\n * những loại khối nào. Mở menu chọn loại rồi gọi `event.confirm(item)` với khối bạn muốn thêm.\n */\n readonly outAddBlockInside = output<T_gridLayout_addEvent>();\n /** Người dùng bấm nút GỘP/TÁCH. Thư viện chưa làm gì — gọi `event.confirm()` để thực hiện. */\n readonly outToggleType = output<T_gridLayout_actionEvent>();\n\n\n private readonly gridsterRef = viewChild(GridsterComponent);\n /** mỗi ô một chỗ gắn riêng — cùng thứ tự với `children()` */\n private readonly itemHosts = viewChildren('itemHost', { read: ViewContainerRef });\n\n /** Sáu chấm của tay cầm kéo — chỉ để `@for` dựng đủ 6 thẻ, giá trị không dùng tới. */\n protected readonly dragBarDots = [0, 1, 2, 3, 4, 5];\n\n private readonly service = inject(LibsUiGridLayoutService);\n\n /**\n * Node THẬT của mặt phẳng này.\n *\n * 🔴 Mặt phẳng GỐC (depth 0) đọc cây từ SERVICE, không dùng input.\n * Nơi dùng thường sửa cây TẠI CHỖ (`treeService.compact(tree)`) rồi gọi `refresh()`, nên signal\n * `root()` của họ giữ nguyên tham chiếu và input `node` không hề đổi — `@for` không dựng lại\n * `gridster-item`, lưới đứng im dù dữ liệu đã khác (đo 28/08/2026: bấm \"Sắp gọn\" không tác dụng).\n * `refresh()` của service thay tham chiếu cây, nên đọc từ đó mới thấy thay đổi.\n *\n * Mặt phẳng LỒNG vẫn dùng input: nó nhận node con từ mặt phẳng cha, vốn đã là object mới.\n */\n protected readonly currentNode = computed(() => {\n this.service.Version();\n\n if (this.depth() > 0) {\n return this.node() ?? emptyRootNode();\n }\n\n return this.service.Root() ?? emptyRootNode();\n });\n\n protected readonly children = computed(() => this.currentNode().children ?? []);\n\n protected readonly isNestedCanvas = computed(() => this.depth() > 0);\n\n /** trần lồng container — khối đã chạm trần thì không cho chuyển thành container */\n protected readonly maxContainerDepth = computed(() => this.service.FunctionsControl.maxContainerDepth());\n\n /**\n * Lề trong của container, px.\n *\n * 🔴 Đặt trên VỎ container, không đặt vào lưới con. Lưới con giữ nguyên `margin: 2` như cũ; lề\n * này chỉ co ruột lại khỏi biên vỏ, nhờ đó tay cầm đổi kích thước của khối con luôn nằm trong tầm\n * chuột (người dùng chốt 28/08/2026).\n */\n protected readonly containerPadding = computed(() => `${this.service.FunctionsControl.containerPadding()}px`);\n\n /** Dải kéo chỉ hiện ở chế độ sửa — chế độ xem không kéo được nên hiện dải là gây nhầm. */\n protected readonly isEditMode = computed(() => this.service.IsEditMode());\n\n protected readonly gridOptions = computed(() => {\n // Đọc `Version` để `init()` lại (đổi chế độ, bật/tắt chồng khối) sinh ra options MỚI —\n // gridster chỉ áp dụng cấu hình khi tham chiếu `options` đổi.\n this.service.Version();\n\n return this.service.FunctionsControl.gridsterOptions(this.depth(), () => this.outChange.emit({ root: this.currentNode() }));\n });\n\n constructor() {\n // Gắn component của nơi dùng vào từng ô, và gắn LẠI mỗi khi cây đổi.\n // Dùng effect vì `itemHosts()` chỉ có giá trị sau khi Angular dựng xong @for.\n effect(() => {\n const hosts = this.itemHosts();\n const items = this.children();\n\n items.forEach((item, i) => {\n const host = hosts[i];\n\n if (!host) {\n return;\n }\n\n // Khối có con là CONTAINER: ruột nó do mặt phẳng lồng vẽ, không gắn component nội dung.\n if ((item.children?.length ?? 0) > 0) {\n return;\n }\n\n this.service.FunctionsControl.attachNode(item, this.depth() + 1, host);\n });\n });\n }\n\n ngOnDestroy(): void {\n for (const item of this.children()) {\n this.service.FunctionsControl.detachNode(item.id);\n }\n }\n\n /** Vẽ lại lưới — gọi khi khung ngoài đổi kích thước hoặc cây vừa đổi diện rộng. */\n get FunctionControl() {\n return {\n veLaiLuoi: () => this.gridsterRef()?.optionsChanged(),\n };\n }\n\n protected handlerTrackNode(_index: number, item: T_gridLayout_node): string {\n return item.id;\n }\n\n /**\n * 🔴 Chặn `mousedown` nổi lên lưới CHA khi thao tác trong lưới con.\n * Không chặn thì cả hai lưới cùng nhận một cú bấm: kéo khối con là nhấc luôn container.\n */\n /**\n * Chặn `mousedown` của khối trong lưới LỒNG nổi lên lưới cha.\n *\n * Chỉ chặn ở lưới lồng: lưới cấp trang không có cha nào để chặn, và chặn ở đó sẽ nuốt luôn thao\n * tác của chính nó.\n */\n /**\n * 🔴 Ba handler dưới đây PHẢI `stopPropagation`.\n * Nút nằm trong vùng mang `dragHandleClass`, không chặn thì cú bấm bị gridster hiểu là bắt đầu kéo\n * và `delayStart: 160` nuốt luôn `click` — người dùng thấy như nút chết.\n */\n protected handlerRemove(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.outRemoveNode.emit({ nodeId: node.id, node, confirm: () => this.service.removeBlock(node.id) });\n }\n\n protected handlerAddInside(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.outAddBlockInside.emit({\n nodeId: node.id,\n node,\n confirm: (item: T_gridLayout_newNode) => this.service.addBlock(item, node.id),\n });\n }\n\n protected handlerToggleType(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.outToggleType.emit({\n nodeId: node.id,\n node,\n // Gộp hay tách suy ra từ chính khối: đang là container thì tách, không thì gộp.\n confirm: () => (this.isContainer(node) ? this.service.toSingle(node.id) : this.service.toContainer(node.id)),\n });\n }\n\n /** khối này có phải container không (có khối con) */\n protected isContainer(item: T_gridLayout_node): boolean {\n return (item.children?.length ?? 0) > 0;\n }\n\n /** container đã chạm trần lồng thì không cho thêm khối vào trong nữa */\n protected canAddInside(item: T_gridLayout_node): boolean {\n return this.isContainer(item) && this.depth() < this.maxContainerDepth();\n }\n\n /** khối đơn ở cấp chưa chạm trần mới được chuyển thành container */\n protected canToggleType(item: T_gridLayout_node): boolean {\n if (this.isContainer(item)) {\n return true;\n }\n\n return this.depth() < this.maxContainerDepth();\n }\n\n protected handlerBlockParentDrag(event: Event): void {\n if (!this.isNestedCanvas()) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerMouseDownTrongLuoi(event: Event): void {\n if (this.depth() === 0) {\n return;\n }\n\n event.stopPropagation();\n }\n}\n","<!-- 🔴 `relative` là BẮT BUỘC, CẤM bỏ.\n gridster đổi vị trí chuột thành ô lưới bằng `e.clientY + (el.scrollTop - el.offsetTop)` — công\n thức đó chỉ đúng khi `offsetParent` của <gridster> CHÍNH LÀ khối cuộn này. Thiếu `relative` thì\n `offsetParent` nhảy lên khối bao ngoài: `offsetTop` trả 16 trong khi lệch thật là 65 → gridster\n tính ô sai 49px, ô chờ đặt hiện lệch khỏi con trỏ nên kéo thả không đổi được vị trí, và kéo mép\n cũng tính sai điểm dừng. -->\n<div\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0\"\n [class.overflow-y-auto]=\"!isNestedCanvas()\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\">\n <gridster class=\"h-full w-full\" [options]=\"gridOptions()\">\n @for (item of children(); track item.id) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n @if (isEditMode()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item)\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">Khối ghép</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode()) {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px. -->\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n }\n </div>\n </gridster-item>\n }\n </gridster>\n</div>\n","// Bề mặt CÔNG KHAI — chỉ những gì nơi dùng thật sự cần.\n//\n// `LibsUiGridLayoutTreeService` CỐ Ý không xuất: mọi thao tác trên cây đã có mặt trên\n// `LibsUiGridLayoutService` với chữ ký gọn hơn (không phải truyền `root` — thư viện đang giữ nó).\n// Cấu hình gridster cũng không xuất: nó đã được vá theo hàng chục lỗi đo trên sản phẩm thật, để nơi\n// dùng sửa lại là mở đường cho chính những lỗi đó quay về.\nexport * from './grid-layout.service';\nexport * from './canvas/grid-layout-canvas.component';\nexport * from './interfaces/grid-layout.interface';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"libs-ui-services-grid-layout.mjs","sources":["../../../../../libs-ui/services/grid-layout/src/defines/gridster-config.define.ts","../../../../../libs-ui/services/grid-layout/src/defines/collision.define.ts","../../../../../libs-ui/services/grid-layout/src/tree.service.ts","../../../../../libs-ui/services/grid-layout/src/grid-layout.service.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.ts","../../../../../libs-ui/services/grid-layout/src/canvas/grid-layout-canvas.component.html","../../../../../libs-ui/services/grid-layout/src/drag-controller.ts","../../../../../libs-ui/services/grid-layout/src/index.ts","../../../../../libs-ui/services/grid-layout/src/libs-ui-services-grid-layout.ts"],"sourcesContent":["import { CompactType, DisplayGrid, GridsterConfig, GridType } from 'gridster18';\nimport { T_gridLayout_node } from '../interfaces/grid-layout.interface';\n\n/**\n * Cấu hình gridster cho lưới CẤP TRANG.\n *\n * Mọi giá trị dưới đây đều đến từ một lỗi đã đo được trên sản phẩm thật, không phải chọn theo cảm\n * tính. Đổi bất kỳ dòng nào có dấu 🔴 sẽ làm sống lại đúng lỗi ghi trong comment.\n */\nexport const gridLayoutRootConfig = (): GridsterConfig => ({\n // 🔴 VerticalFixed — CẤM đổi sang Fit hay ScrollVertical.\n // `Fit` chia đều chiều cao khung cho số hàng đang dùng, nên card khai `rows: 2` phình từ 124px lên\n // 247px. `ScrollVertical` KHÔNG đọc `fixedRowHeight` (mã lib: chỉ `Fixed` và `VerticalFixed` đọc).\n gridType: GridType.VerticalFixed,\n\n // 🔴 None — CẤM quay lại CompactUp.\n // `CompactUp` hút mọi khối lên sát nhau NGAY sau mỗi thao tác, nên:\n // · kéo mép dưới cho khối cao thêm → chỗ khối dưới vừa nhường bị hút lấp lại tức thì, cú kéo bị\n // `checkGridCollision` báo va chạm rồi HOÀN NGUYÊN (khối đứng im dù kéo);\n // · kéo thả đổi vị trí → khối vừa nhường chỗ bị hút về ngay, khối đang kéo không có chỗ đặt và\n // treo lơ lửng giữa hai khối.\n // Muốn dồn khít thì gọi `sapGon()` của service.\n compactType: CompactType.None,\n displayGrid: DisplayGrid.OnDragAndResize,\n\n // 🔴 pushItems: true — CẤM để false.\n // `swap` của lib CHỈ hoán vị được HAI KHỐI CÙNG KÍCH THƯỚC (mã lib `checkSwap`: tính diffX/diffY\n // rồi hoán vị, lệch kích thước thì `checkCollision` báo va chạm và hoàn nguyên). Khối 3x2 gặp\n // container 7x5 nên không swap được, mà `pushItems: false` cũng không cho container nhường đường\n // → BẾ TẮC: khối đang kéo không đặt được ở đâu.\n pushItems: true,\n // chỉ đẩy XUỐNG: đẩy ngang làm xô lệch bố cục cột người dùng vừa đặt\n pushDirections: { north: false, east: false, south: true, west: false },\n pushResizeItems: true,\n swap: true,\n swapWhileDragging: true,\n\n draggable: {\n enabled: true,\n // delayStart: 0 vì kéo qua tay cầm chuyên dụng (dragHandleClass) và ignoreContent: true.\n // Khi người dùng bấm vào thanh tay cầm là chủ động kéo, không cần trễ 160ms tránh huỷ kéo.\n delayStart: 0,\n // 🔴 `checkDragHandleClass` duyệt DOM từ chỗ bấm NGƯỢC LÊN CHA, và trên MỖI node nó kiểm\n // `dragHandleClass` TRƯỚC `ignoreContentClass`. Vì vậy một phần tử KHÔNG được mang cả hai class\n // cùng lúc — mang cả hai thì lib gặp tay cầm trước, trả `true`, class chặn không tới lượt.\n ignoreContentClass: 'libs-ui-grid-layout-block-parent-drag',\n ignoreContent: true,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle',\n },\n\n resizable: {\n enabled: true,\n // đủ 8 hướng như cửa sổ thường; chỉ có góc dưới-phải thì quá khó trúng\n handles: { s: true, e: true, n: true, w: true, se: true, ne: true, sw: true, nw: true },\n },\n\n margin: 12,\n outerMargin: true,\n outerMarginBottom: 40,\n minCols: 12,\n maxCols: 12,\n minRows: 2,\n\n // 🔴 KHÔNG giới hạn chiều cao khối. Lib có BA trần mặc định phải vô hiệu hoá CÙNG LÚC, thiếu một\n // cái là vẫn bị chặn: `maxItemRows: 50` · `maxItemCols: 50` · `maxItemArea: 2500` (trần DIỆN TÍCH\n // cols × rows — khó thấy nhất: khối 12 cột chỉ cần 209 hàng là đụng trần dù hai trần kia còn dư).\n // `maxRows` là trần của CẢ LƯỚI, cũng phải nới theo.\n maxRows: 5000,\n maxItemRows: 5000,\n maxItemCols: 12,\n maxItemArea: 60000,\n\n // 🔴 Trần LỚP CHỒNG. Mặc định của lib là 2 — quá thấp: khi bật chồng khối, thư viện gán mỗi khối\n // một lớp riêng để chúng khác nhau, nên chỉ 3 khối là đã đụng trần và các khối sau lại rơi về\n // cùng lớp, tức chồng nhau bị chặn trở lại.\n maxLayerIndex: 5000,\n\n setGridSize: true,\n fixedRowHeight: 56,\n defaultItemCols: 3,\n defaultItemRows: 2,\n minItemRows: 1,\n mobileBreakpoint: -1,\n});\n\n/**\n * Cấu hình cho lưới LỒNG (ruột một container).\n *\n * Kế thừa lưới trang rồi ghi đè phần khác biệt. Ba điểm quan trọng nhất: `setGridSize` phải TẮT,\n * tay cầm phải mang TÊN RIÊNG, và tự-cuộn-khi-kéo phải TẮT.\n */\nexport const gridLayoutNestedConfig = (): GridsterConfig => ({\n ...gridLayoutRootConfig(),\n\n // 🔴 PHẢI tắt cho lưới lồng. `setGridSize` làm gridster tự ghi style width/height lên CHÍNH nó,\n // sinh vòng lặp đo-rồi-ghi với ResizeObserver của khung ngoài (khung đổi → onResize xoá style →\n // setGridSize ghi lại) → lưới con co dần về 64x64px trong khung 868px.\n setGridSize: false,\n\n // khe 2px: khối con là các dòng thông tin của CÙNG một card, khe rộng làm chúng trông như card rời\n margin: 2,\n // Lưới lồng KHÔNG tự chừa lề — lề là của VỎ container (`containerPadding`), không phải của lưới.\n // Đặt ở vỏ thì ruột co lại đúng bằng phần còn lại, tay cầm resize của khối con luôn nằm trong tầm\n // chuột (người dùng chốt 28/08/2026: \"lưới cha có padding chứ ko phải con\").\n outerMargin: false,\n outerMarginBottom: 0,\n\n // hàng 16px cho bước kéo mịn, và sàn 1 hàng = 16px nên khối co được nhỏ hơn nhiều\n fixedRowHeight: 16,\n minRows: 1,\n minItemRows: 1,\n defaultItemCols: 2,\n defaultItemRows: 2,\n\n // 🔴 Tay cầm RIÊNG — CẤM dùng chung tên với lưới trang.\n // `checkDragHandleClass` trả `true` ở node ĐẦU TIÊN có `dragHandleClass`. Dùng chung một tên thì\n // lưới CHA cũng nhận ra tay cầm của khối con và nhấc luôn container.\n draggable: {\n ...gridLayoutRootConfig().draggable,\n dragHandleClass: 'libs-ui-grid-layout-drag-handle-child',\n },\n\n // 🔴 KÉO MÉP thì khối dưới ĐỨNG YÊN, chỉ khoảng trống giữa hai khối co giãn. Bật (kế thừa từ lưới\n // trang) thì mỗi cú kéo đẩy dồn cả cột xuống — người dùng chỉ muốn một khối to hơn một chút mà cả\n // card dài ra. `pushItems` vẫn giữ: nó lo việc KÉO THẢ đổi chỗ, khác việc đổi kích thước.\n pushResizeItems: false,\n\n // 🔴 Tắt tự cuộn khi kéo tới sát mép. Lib thấy chuột gần biên là cuộn lưới theo\n // (`scrollSensitivity`), nhưng lưới con nằm trong card có `overflow: hidden` — cuộn ở đây đẩy khối\n // con ra NGOÀI khung container rồi kẹt luôn ở đó.\n disableScrollHorizontal: true,\n disableScrollVertical: true,\n});\n\n/**\n * Cây rỗng dùng khi chưa có dữ liệu — mặt phẳng vẽ ra một lưới trống thay vì vỡ.\n * Xảy ra trong nhịp giữa lúc component dựng và lúc `init()` chạy.\n */\nexport const emptyRootNode = (): T_gridLayout_node => ({ id: 'root', x: 0, y: 0, cols: 12, rows: 0, children: [] });\n","import {\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_newNode,\n T_gridLayout_node,\n} from '../interfaces/grid-layout.interface';\nimport { uuid } from '@libs-ui/utils';\n\n/**\n * Checks whether the rectangular region [x, x + cols) x [y, y + rows)\n * is completely vacant among existing items.\n */\nexport const isRegionFree = (\n children: Array<T_gridLayout_node>,\n x: number,\n y: number,\n cols: number,\n rows: number,\n ignoredId?: string,\n): boolean => {\n for (const child of children) {\n if (ignoredId && child.id === ignoredId) {\n continue;\n }\n const hOverlap = !(child.x + child.cols <= x || child.x >= x + cols);\n const vOverlap = !(child.y + child.rows <= y || child.y >= y + rows);\n\n if (hOverlap && vOverlap) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Computes optimal (col, row) inside a group container.\n * Snaps flush to adjacent card right edge if slot is vacant.\n */\nexport const findSnapPositionInsideGroup = (\n children: Array<T_gridLayout_node>,\n rawCol: number,\n rawRow: number,\n innerCols: number,\n innerRows: number,\n totalCols = 24,\n): { col: number; row: number } => {\n let bestCandidate: { col: number; row: number; dist: number } | undefined;\n\n for (const child of children) {\n const rightEdge = child.x + child.cols;\n const canFit = rightEdge + innerCols <= totalCols;\n const isFree = canFit && isRegionFree(children, rightEdge, child.y, innerCols, innerRows);\n\n if (!isFree) {\n continue;\n }\n\n const nearX = Math.abs(rawCol - rightEdge) <= 2 || (rawCol >= child.x + Math.floor(child.cols / 2) && rawCol <= rightEdge + 1);\n const nearY = Math.abs(rawRow - child.y) <= 2;\n\n if (nearX && nearY) {\n const dist = Math.abs(rawCol - rightEdge) + Math.abs(rawRow - child.y);\n\n if (!bestCandidate || dist < bestCandidate.dist) {\n bestCandidate = { col: rightEdge, row: child.y, dist };\n }\n }\n }\n\n if (bestCandidate) {\n return { col: bestCandidate.col, row: bestCandidate.row };\n }\n\n const clampedCol = Math.max(0, Math.min(totalCols - innerCols, rawCol));\n const clampedRow = Math.max(0, rawRow);\n\n return { col: clampedCol, row: clampedRow };\n};\n\n/**\n * Adjusts position of pair if horizontal overlap occurs.\n */\nconst adjustItemPair = (a: T_gridLayout_node, b: T_gridLayout_node): boolean => {\n const hOverlap = !(a.x + a.cols <= b.x || a.x >= b.x + b.cols);\n\n if (hOverlap && b.y < a.y + a.rows) {\n b.y = a.y + a.rows;\n\n return true;\n }\n\n return false;\n};\n\n/**\n * Resolves vertical collisions when inserting a new card at (newNode.x, newNode.y).\n * Any existing card that horizontally overlaps and whose vertical span overlaps\n * or is below the insertion point is pushed down so there is no overlap.\n */\nexport const resolveCollisionsAndInsert = (\n children: Array<T_gridLayout_node>,\n newNode: T_gridLayout_node,\n): void => {\n const items = [...children];\n\n for (const item of items) {\n const hOverlap = !(item.x + item.cols <= newNode.x || item.x >= newNode.x + newNode.cols);\n const vOverlap = !(item.y + item.rows <= newNode.y || item.y >= newNode.y + newNode.rows);\n\n if (hOverlap && vOverlap) {\n item.y = newNode.y + newNode.rows;\n }\n }\n\n items.sort((a, b) => a.y - b.y);\n let changed = true;\n\n while (changed) {\n changed = false;\n for (let i = 0; i < items.length; i++) {\n for (let j = i + 1; j < items.length; j++) {\n changed = adjustItemPair(items[i], items[j]) || changed;\n }\n }\n }\n\n children.push(newNode);\n};\n\nexport function parseDropPayload<T>(activePayload: T | undefined, dataTransfer: DataTransfer | null): T | undefined {\n if (activePayload) {\n return activePayload;\n }\n if (dataTransfer) {\n try {\n const raw = dataTransfer.getData('application/json');\n\n if (raw) {\n return JSON.parse(raw) as T;\n }\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n}\n\ninterface I_hoveredGroup {\n groupNode: T_gridLayout_node;\n groupGridster: HTMLElement;\n}\n\nexport const findHoveredGroup = (\n elements: Element[],\n canvasContainer: HTMLElement,\n root: T_gridLayout_node,\n): I_hoveredGroup | undefined => {\n const rootGridster = canvasContainer.querySelector('gridster');\n\n for (const el of elements) {\n const gridsterEl = (el.tagName.toLowerCase() === 'gridster' ? el : el.closest('gridster')) as HTMLElement | null;\n\n if (gridsterEl && gridsterEl !== rootGridster) {\n const outerItem = gridsterEl.closest('gridster-item');\n const rootItems = rootGridster ? Array.from(rootGridster.querySelectorAll(':scope > gridster-item')) : [];\n const idx = outerItem ? rootItems.indexOf(outerItem) : -1;\n\n if (idx >= 0 && root.children?.[idx]) {\n return { groupNode: root.children[idx], groupGridster: gridsterEl };\n }\n }\n }\n\n for (const el of elements) {\n const itemEl = el.tagName.toLowerCase() === 'gridster-item' ? el : el.closest('gridster-item');\n if (!itemEl) {\n continue;\n }\n const rootItems = rootGridster ? Array.from(rootGridster.querySelectorAll(':scope > gridster-item')) : [];\n const idx = rootItems.indexOf(itemEl);\n if (idx >= 0 && root.children?.[idx]) {\n const node = root.children[idx];\n if ((node.children?.length ?? 0) > 0) {\n return { groupNode: node, groupGridster: (itemEl.querySelector('gridster') as HTMLElement | null) ?? (itemEl as HTMLElement) };\n }\n }\n }\n\n return undefined;\n};\n\n/**\n * Calculates snapped spatial coordinates and pixel dimensions for drop ghost preview box.\n */\nexport const calculateDropGhost = (\n event: DragEvent,\n canvasContainer: HTMLElement,\n root: T_gridLayout_node,\n payload: T_gridLayout_externalDragPayload,\n totalCols = 24,\n): T_gridLayout_dropGhost | undefined => {\n if (typeof document === 'undefined' || !canvasContainer) {\n return undefined;\n }\n\n const cardTitle = payload.title || 'Thẻ';\n const cardIconClass = payload.iconClass;\n const cardIconText = payload.iconText;\n const payloadAny = payload as Record<string, unknown>;\n let defaultCols = typeof payload.cols === 'number'\n ? payload.cols\n : (typeof payloadAny['defaultCols'] === 'number' ? (payloadAny['defaultCols'] as number) : (totalCols >= 24 ? 12 : 6));\n let defaultRows = typeof payload.rows === 'number'\n ? payload.rows\n : (typeof payloadAny['defaultRows'] === 'number' ? (payloadAny['defaultRows'] as number) : 4);\n\n if (typeof payloadAny['resolveNode'] === 'function') {\n try {\n const sample = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(false);\n if (sample) {\n if (typeof sample.cols === 'number') { defaultCols = sample.cols; }\n if (typeof sample.rows === 'number') { defaultRows = sample.rows; }\n }\n } catch {\n // fallback to default cols and rows\n }\n }\n\n const stageEl = (canvasContainer.querySelector('#bi-canvas-stage') as HTMLElement | null) ?? canvasContainer;\n const stageRect = stageEl.getBoundingClientRect();\n\n const rootGridster = stageEl.querySelector('gridster') as HTMLElement | null;\n const gridsterEl = rootGridster ?? stageEl;\n const gridsterRect = gridsterEl.getBoundingClientRect();\n const unscaledWidth = gridsterEl.offsetWidth || gridsterEl.clientWidth || 0;\n const zoom = (gridsterRect.width && unscaledWidth > 0)\n ? Math.max(0.2, Math.min(3, gridsterRect.width / unscaledWidth))\n : 1;\n\n const elements = typeof document.elementsFromPoint === 'function'\n ? document.elementsFromPoint(event.clientX, event.clientY)\n : [];\n const hovered = findHoveredGroup(elements, canvasContainer, root);\n\n const stageMouseX = (event.clientX - stageRect.left) / zoom;\n const stageMouseY = (event.clientY - stageRect.top) / zoom;\n\n if (hovered) {\n const { groupNode, groupGridster } = hovered;\n const groupGridsterRect = groupGridster.getBoundingClientRect();\n const groupStageLeft = (groupGridsterRect.left - stageRect.left) / zoom;\n const groupStageTop = (groupGridsterRect.top - stageRect.top) / zoom;\n\n let innerCols = defaultCols;\n let innerRows = defaultRows;\n if (typeof payloadAny['resolveNode'] === 'function') {\n try {\n const sampleInside = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(true);\n if (sampleInside) {\n if (typeof sampleInside.cols === 'number') { innerCols = sampleInside.cols; }\n if (typeof sampleInside.rows === 'number') { innerRows = sampleInside.rows; }\n }\n } catch {\n // fallback to default cols and rows\n }\n }\n innerCols = Math.min(innerCols, totalCols);\n\n const groupWidth = groupGridster.clientWidth || (groupGridsterRect.width / zoom) || 400;\n const colStep = (groupWidth + 2) / totalCols;\n const rowStep = 18;\n const relX = (event.clientX - groupGridsterRect.left) / zoom + groupGridster.scrollLeft;\n const relY = (event.clientY - groupGridsterRect.top) / zoom + groupGridster.scrollTop;\n const rawCol = Math.floor(relX / colStep);\n const rawRow = Math.floor(relY / rowStep);\n const snap = findSnapPositionInsideGroup(\n groupNode.children ?? [],\n rawCol,\n rawRow,\n innerCols,\n innerRows,\n totalCols,\n );\n\n return {\n col: snap.col,\n row: snap.row,\n cols: innerCols,\n rows: innerRows,\n pixelLeft: groupStageLeft + snap.col * colStep,\n pixelTop: groupStageTop + snap.row * rowStep,\n pixelWidth: Math.max(30, innerCols * colStep - 2),\n pixelHeight: Math.max(20, innerRows * rowStep - 2),\n isInsideGroup: true,\n targetParentId: groupNode.id,\n groupTitle: 'Khối ghép',\n cardTitle,\n cardIconClass,\n cardIconText,\n hoveredGridster: groupGridster as HTMLElement,\n };\n }\n\n const margin = 12;\n const rowStep = 68;\n const gridsterWidth = unscaledWidth || gridsterEl.clientWidth || 1200;\n const colStep = Math.max(20, (gridsterWidth - margin) / totalCols);\n const gridsterStageLeft = (gridsterRect.left - stageRect.left) / zoom;\n const gridsterStageTop = (gridsterRect.top - stageRect.top) / zoom;\n const relX = stageMouseX - gridsterStageLeft + gridsterEl.scrollLeft - margin;\n const relY = stageMouseY - gridsterStageTop + gridsterEl.scrollTop - margin;\n const itemCols = Math.min(defaultCols, totalCols);\n const col = Math.max(0, Math.min(totalCols - itemCols, Math.floor(relX / colStep)));\n const row = Math.max(0, Math.floor(relY / rowStep));\n\n return {\n col,\n row,\n cols: itemCols,\n rows: defaultRows,\n pixelLeft: gridsterStageLeft + margin + col * colStep,\n pixelTop: gridsterStageTop + margin + row * rowStep,\n pixelWidth: itemCols * colStep - margin,\n pixelHeight: defaultRows * rowStep - margin,\n isInsideGroup: false,\n cardTitle,\n cardIconClass,\n cardIconText,\n hoveredGridster: (rootGridster as HTMLElement) ?? undefined,\n };\n};\n\n\n/** Tìm khối theo id trong cây, đi sâu vào mọi container. */\nexport const findNodeRecursive = (root: T_gridLayout_node, id: string): T_gridLayout_node | undefined => {\n if (root.id === id) {\n return root;\n }\n\n for (const child of root.children ?? []) {\n const found = findNodeRecursive(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\n/** Tìm khối CHA trực tiếp của một khối, đi sâu vào mọi container. */\nexport const findParentRecursive = (root: T_gridLayout_node, id: string): T_gridLayout_node | undefined => {\n for (const child of root.children ?? []) {\n if (child.id === id) {\n return root;\n }\n\n const found = findParentRecursive(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n};\n\n/**\n * Thả khối vào đúng ô mà ghost đang chỉ, đẩy các khối va chạm xuống dưới.\n *\n * Ghost đang nằm trong một container (`isInsideGroup`) thì thả vào ruột container đó; không tìm thấy\n * container thì trả `false` chứ KHÔNG rơi về lưới gốc — thả nhầm cấp khó nhận ra hơn là không thả.\n */\nexport const dropNodeAtCoordinates = (\n root: T_gridLayout_node,\n ghost: T_gridLayout_dropGhost,\n newNode: T_gridLayout_newNode\n): boolean => {\n const nodeToAdd: T_gridLayout_node = {\n ...newNode,\n id: newNode.id ?? uuid(),\n x: ghost.col,\n y: ghost.row,\n cols: ghost.cols,\n rows: ghost.rows,\n };\n\n if (ghost.isInsideGroup && ghost.targetParentId) {\n const parentNode = findNodeRecursive(root, ghost.targetParentId);\n\n if (!parentNode) {\n return false;\n }\n parentNode.children = parentNode.children ?? [];\n resolveCollisionsAndInsert(parentNode.children, nodeToAdd);\n\n return true;\n }\n\n root.children = root.children ?? [];\n resolveCollisionsAndInsert(root.children, nodeToAdd);\n\n return true;\n};\n\n\n/** Khối có phải CONTAINER không — tức có khối con bên trong. */\nexport const isContainerNode = (node: T_gridLayout_node): boolean => (node.children?.length ?? 0) > 0;\n\n/** Khối có nằm LỒNG bên trong một container không (không phải con trực tiếp của gốc). */\nexport const isNodeNestedInside = (root: T_gridLayout_node | undefined, nodeId: string): boolean => {\n if (!root?.children) {\n return false;\n }\n\n return !root.children.some((child) => child.id === nodeId);\n};\n\n/**\n * Có được đổi khối đơn ↔ container không.\n *\n * 🔴 Ba hàm cờ này PHẢI là nguồn duy nhất cho cả thanh công cụ của thư viện lẫn menu do nơi dùng tự\n * dựng. Trước đây nơi dùng phải chép lại quy tắc để dựng menu trước lúc render, và hai bản lệch nhau\n * mỗi khi thư viện đổi trần lồng cấp mà không có gì báo.\n */\nexport const canToggleTypeNode = (root: T_gridLayout_node | undefined, node: T_gridLayout_node): boolean =>\n isContainerNode(node) || !isNodeNestedInside(root, node.id);\n\n/** Có được thêm khối vào BÊN TRONG khối này không. */\nexport const canAddInsideNode = (root: T_gridLayout_node | undefined, node: T_gridLayout_node): boolean =>\n isContainerNode(node) && !isNodeNestedInside(root, node.id);\n","import { Injectable } from '@angular/core';\nimport { uuid } from '@libs-ui/utils';\nimport { T_gridLayout_newNode, T_gridLayout_node } from './interfaces/grid-layout.interface';\nimport { resolveCollisionsAndInsert } from './defines/collision.define';\n\n/**\n * Thao tác trên cây khối: tìm, thêm, xoá, dồn khít, chặn lồng cấp quá sâu.\n *\n * 🔴 NỘI BỘ thư viện — không xuất ra ngoài. Nơi dùng đi qua `LibsUiGridLayoutService`, ở đó mỗi\n * thao tác sửa bố cục vừa vẽ lại vừa bắn `outChange` đúng MỘT lần. Các hàm ở đây cố tình KHÔNG tự\n * vẽ lại: để chúng tự gọi thì mỗi thao tác vẽ hai lượt và bắn hai sự kiện (người dùng chốt\n * 28/08/2026: \"đặt đúng các điểm mà làm cho layout có thể thay đổi thôi\").\n */\n@Injectable()\nexport class LibsUiGridLayoutTreeService {\n findById(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n if (node.id === id) {\n return node;\n }\n\n for (const child of node.children ?? []) {\n const found = this.findById(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n findParent(node: T_gridLayout_node, id: string): T_gridLayout_node | undefined {\n for (const child of node.children ?? []) {\n if (child.id === id) {\n return node;\n }\n\n const found = this.findParent(child, id);\n\n if (found) {\n return found;\n }\n }\n\n return undefined;\n }\n\n /**\n * Thêm khối vào cuối một container. Thư viện tự sinh `id` và tự đặt `x` · `y` xuống hàng trống.\n *\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addChild(root: T_gridLayout_node, parentId: string, item: T_gridLayout_newNode): T_gridLayout_node | undefined {\n const parent = this.findById(root, parentId);\n\n if (!parent) {\n return undefined;\n }\n\n parent.children = parent.children ?? [];\n // 🔴 Thư viện tự sinh `id`. Đây là mã máy dùng để tra cứu, không phải thứ người dùng nghĩ ra —\n // bắt họ tự đặt là mời họ tạo trùng, mà trùng id thì `findById` trả nhầm khối và cả cây hỏng\n // im lặng (người dùng chốt 28/08/2026).\n const node: T_gridLayout_node = { ...item, id: item.id ?? uuid(), x: 0, y: this.nextFreeRow(parent.children) };\n\n parent.children.push(node);\n\n // Trả về khối vừa tạo để nơi dùng biết `id` thư viện vừa sinh.\n return node;\n }\n\n /**\n * Thêm khối vào vị trí (x, y) cụ thể và tự động đẩy các khối va chạm xuống dưới.\n */\n insertWithCollision(\n root: T_gridLayout_node,\n parentId: string | undefined,\n item: T_gridLayout_newNode,\n targetCol = 0,\n targetRow = 0,\n ): T_gridLayout_node | undefined {\n const targetParent = parentId ? this.findById(root, parentId) : root;\n\n if (!targetParent) {\n return undefined;\n }\n\n targetParent.children = targetParent.children ?? [];\n const node: T_gridLayout_node = {\n ...item,\n id: item.id ?? uuid(),\n x: targetCol,\n y: targetRow,\n };\n\n resolveCollisionsAndInsert(targetParent.children, node);\n\n return node;\n }\n\n /** Xoá một khối khỏi cây. Không cho xoá gốc. */\n removeById(root: T_gridLayout_node, id: string): boolean {\n if (root.id === id) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n if (!parent?.children) {\n return false;\n }\n\n parent.children = parent.children.filter((item) => item.id !== id);\n\n return true;\n }\n\n /**\n * Chuyển một khối đơn thành CONTAINER: nội dung cũ trở thành khối con đầu tiên.\n *\n * Không mất dữ liệu — `data` của khối được mang theo xuống khối con.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối đã là container rồi.\n */\n toContainer(root: T_gridLayout_node, id: string, colCount: number): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) > 0) {\n return false;\n }\n\n node.children = [{ ...node, id: uuid(), x: 0, y: 0, cols: colCount, rows: 4, children: [] }];\n\n return true;\n }\n\n /**\n * Chuyển một CONTAINER về khối đơn: các khối con được NÂNG lên cấp trên, không bị xoá.\n *\n * @returns `false` khi không tìm thấy khối, hoặc khối vốn không phải container.\n */\n toSingle(root: T_gridLayout_node, id: string): boolean {\n const node = this.findById(root, id);\n\n if (!node || (node.children?.length ?? 0) === 0) {\n return false;\n }\n\n const parent = this.findParent(root, id);\n\n for (const child of node.children ?? []) {\n parent?.children?.push({ ...child, cols: node.cols, rows: 2 });\n }\n\n node.children = [];\n\n return true;\n }\n\n /**\n * Làm phẳng mọi container lồng vượt trần.\n *\n * 🔴 Cần thiết vì bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện. Một bản lưu cũ — sinh\n * trước khi có trần, hoặc do thao tác lỗi — vẫn nạp thẳng vào và hiện container lồng container.\n * Container vượt trần bị hạ thành khối thường, con của nó nâng lên cấp trên: KHÔNG mất dữ liệu.\n *\n * @returns số container đã làm phẳng\n */\n flattenOverDepthContainers(node: T_gridLayout_node, maxDepth: number): number {\n return this.walkFlatten(node, 0, maxDepth);\n }\n\n /**\n * Dồn khối khít lên trên theo thứ tự đọc, lấp hết chỗ trống.\n *\n * 🔴 KHÔNG sửa `node.rows` của container. Chiều cao container tính theo đơn vị hàng của lưới CHA,\n * còn `currentRow` đếm theo đơn vị hàng của lưới CON — trộn hai thang đo là container phình lên\n * gấp mấy lần.\n */\n compact(node: T_gridLayout_node, colCount: number): void {\n this.walkCompact(node, colCount);\n }\n\n private walkCompact(node: T_gridLayout_node, colCount: number): void {\n const children = node.children;\n\n if (!children?.length) {\n return;\n }\n\n const inReadingOrder = [...children].sort((a, b) => a.y - b.y || a.x - b.x);\n let currentRow = 0;\n let usedCols = 0;\n let tallestInRow = 0;\n\n for (const item of inReadingOrder) {\n const width = Math.min(item.cols, colCount);\n\n if (usedCols > 0 && usedCols + width > colCount) {\n currentRow += tallestInRow;\n usedCols = 0;\n tallestInRow = 0;\n }\n\n item.x = usedCols;\n item.y = currentRow;\n item.cols = width;\n usedCols += width;\n tallestInRow = Math.max(tallestInRow, item.rows);\n\n if ((item.children?.length ?? 0) > 0) {\n this.walkCompact(item, colCount);\n }\n }\n }\n\n private walkFlatten(node: T_gridLayout_node, containerDepth: number, maxDepth: number): number {\n const children = node.children;\n\n if (!children?.length) {\n return 0;\n }\n\n let fixedCount = 0;\n const result: Array<T_gridLayout_node> = [];\n\n for (const child of children) {\n const isContainer = (child.children?.length ?? 0) > 0;\n\n if (isContainer && containerDepth >= maxDepth) {\n fixedCount += 1;\n\n for (const item of child.children ?? []) {\n fixedCount += this.walkFlatten(item, containerDepth, maxDepth);\n result.push(item);\n }\n\n continue;\n }\n\n fixedCount += this.walkFlatten(child, isContainer ? containerDepth + 1 : containerDepth, maxDepth);\n result.push(child);\n }\n\n node.children = result;\n\n return fixedCount;\n }\n\n private nextFreeRow(children: Array<T_gridLayout_node>): number {\n return children.reduce((max, child) => Math.max(max, child.y + child.rows), 0);\n }\n}\n","import { ComponentRef, DestroyRef, Injectable, ViewContainerRef, inject, signal } from '@angular/core';\nimport { GridsterComponentInterface, GridsterConfig, GridsterItem } from 'gridster18';\nimport { cloneDeep } from '@libs-ui/utils';\nimport { Subscription, take } from 'rxjs';\nimport { gridLayoutNestedConfig, gridLayoutRootConfig } from './defines/gridster-config.define';\nimport { findNodeRecursive, findParentRecursive } from './defines/collision.define';\nimport { LibsUiGridLayoutTreeService } from './tree.service';\nimport {\n E_gridLayout_mode_string,\n T_gridLayout_changeEvent,\n T_gridLayout_newNode,\n T_gridLayout_config,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\n\n/**\n * Dựng một mặt phẳng kéo thả và tự gắn component của nơi dùng lên từng khối.\n *\n * Nơi dùng chỉ cần đưa vào: loại component muốn dựng\n * (`nodeComponentType`) và cây dữ liệu (`data`). Toàn bộ việc vẽ lưới, kéo thả, đổi kích thước,\n * lồng container và dọn dẹp do thư viện lo.\n *\n * 🔴 Đây là service theo TỪNG mặt phẳng, KHÔNG `providedIn: 'root'`. Khai trong `providers` của\n * component dùng nó; hai mặt phẳng trên cùng một màn phải là hai thực thể riêng, dùng chung thì\n * `componentRefs` của mặt phẳng này bị mặt phẳng kia dọn mất.\n */\n@Injectable()\nexport class LibsUiGridLayoutService {\n // 🔴 TỰ TẠO, không `inject`. Nơi dùng chỉ phải viết `providers: [LibsUiGridLayoutService]` —\n // không phải biết bên trong thư viện còn service nào khác (người dùng chốt 28/08/2026).\n // `TreeService` không giữ trạng thái dùng chung nên mỗi mặt phẳng một bản là đúng.\n private readonly treeService = new LibsUiGridLayoutTreeService();\n /** Lượt tải component đang chờ, theo id khối — để huỷ khi khối bị gỡ giữa chừng. */\n private readonly pendingLoads = new Map<string, Subscription>();\n /**\n * Bộ theo dõi bề rộng của từng lưới LỒNG, để ngắt khi service bị huỷ.\n *\n * 🔴 Giữ tham chiếu là BẮT BUỘC: `ResizeObserver` không tự tắt theo vòng đời component. Không dọn\n * thì mỗi lần nạp lại bố cục (đổi tab) lại chồng thêm một bộ, và chúng vẫn chạy trên DOM đã gỡ.\n */\n private readonly nestedResizeObservers = new Set<ResizeObserver>();\n\n constructor() {\n // 🔴 Service khai trong `providers` của component nên Angular huỷ nó cùng component — thư viện\n // tự dọn ở đây, nơi dùng KHÔNG phải gọi `destroy()` trong `ngOnDestroy` (người dùng chốt\n // 28/08/2026). Bắt nhớ một bước dọn dẹp là kiểu API dễ quên, và quên thì rò rỉ bộ nhớ im lặng.\n inject(DestroyRef).onDestroy(() => this.destroy());\n }\n\n private config?: T_gridLayout_config;\n private readonly componentRefs = new Map<string, ComponentRef<unknown>>();\n\n private readonly rootNode = signal<T_gridLayout_node | undefined>(undefined);\n private readonly editMode = signal<boolean>(false);\n /** tăng mỗi lần cây đổi — component con đọc để biết phải tính lại */\n private readonly version = signal<number>(0);\n private readonly zoomLevel = signal<number>(1);\n\n /**\n * Signal chỉ đọc để nơi dùng theo dõi.\n *\n * 🔴 Là THUỘC TÍNH, không phải getter. Getter trả signal thì chỗ đọc phải viết `Version()()` —\n * quên cặp ngoặc thứ hai là computed KHÔNG phụ thuộc vào nó, cây đổi mà lưới đứng im, và\n * TypeScript không hề báo lỗi (đo 28/08/2026: thêm khối không hiện, sắp gọn không nhúc nhích).\n */\n readonly Root = this.rootNode.asReadonly();\n readonly IsEditMode = this.editMode.asReadonly();\n /** tăng mỗi lần cây hoặc cấu hình đổi */\n readonly Version = this.version.asReadonly();\n readonly Zoom = this.zoomLevel.asReadonly();\n\n /**\n * trần số cấp container lồng nhau — canvas đọc để biết có cho chuyển thành container không */\n private maxContainerDepth(): number {\n return this.config?.maxContainerDepth ?? 1;\n }\n\n /**\n * lề trong của container, px — canvas đọc để đặt padding lên vỏ container */\n private containerPadding(): number {\n return this.config?.containerPadding ?? 12;\n }\n\n /** Khởi tạo mặt phẳng. Gọi lại sẽ dọn sạch component cũ rồi dựng lại từ đầu. */\n init(config: T_gridLayout_config): void {\n this.destroy();\n this.config = config;\n // 🔴 Bố cục ĐÃ LƯU không đi qua luật chặn nào của giao diện: bản lưu cũ (sinh trước khi có trần,\n // hoặc do thao tác lỗi) vẫn mang container lồng container. Trần `maxContainerDepth` chỉ ẩn NÚT\n // trên canvas — nó không sửa dữ liệu, nên thiếu dòng này là vẽ ra đúng cây quá sâu đó.\n // Nơi dùng KHÔNG tự gọi được: `LibsUiGridLayoutTreeService` cố ý không xuất.\n this.treeService.flattenOverDepthContainers(config.data, this.maxContainerDepth());\n this.assignOverlapLayers(config.data);\n // 🔴 Nhân bản như `refresh()`: `init()` lại (đổi chế độ, bật/tắt chồng khối) trên CÙNG object cây\n // thì `@for` không dựng lại `gridster-item`, nên `layerIndex` vừa gán không tới `$item` và khối\n // vẫn không đè nhau được (đo 28/08/2026: `item.layerIndex` = 1|2|3|4|7 mà `$item.layerIndex`\n // toàn `undefined`).\n this.rootNode.set(this.shallowCloneTree(config.data));\n this.editMode.set(config.isEditMode ?? false);\n\n let initialZoom = config.initialZoom ?? 1;\n if (config.storageKey && typeof localStorage !== 'undefined') {\n try {\n const saved = localStorage.getItem(config.storageKey);\n if (saved) {\n const parsed = parseFloat(saved);\n const min = config.zoomMin ?? 0.4;\n const max = config.zoomMax ?? 1.5;\n if (!isNaN(parsed) && parsed >= min && parsed <= max) {\n initialZoom = parsed;\n }\n }\n } catch {\n // ignore localStorage access error\n }\n }\n this.zoomLevel.set(initialZoom);\n\n this.version.update((v) => v + 1);\n }\n\n setEditMode(value: boolean): void {\n this.editMode.set(value);\n // 🔴 PHẢI bơm `version`: `gridsterOptions()` đọc `editMode` để bật/tắt kéo–thả, mà computed\n // `gridOptions` bên canvas chỉ chạy lại khi `Version` đổi. Thiếu dòng này thì đổi chế độ xong\n // gridster vẫn giữ options cũ — chuyển sang XEM mà khối vẫn kéo được.\n this.version.update((v) => v + 1);\n }\n\n /**\n * Bật/tắt cho khối chồng lên nhau — KHÔNG dựng lại mặt phẳng.\n *\n * Trước đây nơi dùng phải gọi `init()` lại để đổi cờ này, mà `init()` huỷ sạch rồi dựng lại mọi\n * component nội dung — lãng phí, và người dùng thấy màn chớp (người dùng chốt 28/08/2026).\n */\n setAllowOverlap(value: boolean): void {\n if (!this.config) {\n return;\n }\n\n this.config = { ...this.config, allowOverlap: value };\n\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n // 🔴 Gán lớp vào CÂY ĐANG VẼ (`rootNode`), KHÔNG phải `config.data`.\n // `init()` đã clone `config.data` sang `rootNode` nên hai object KHÁC nhau; gán vào `config.data`\n // thì `refresh()` clone lại từ `rootNode` — lớp vừa gán không tới `gridster-item` nào, `z-index`\n // của mọi khối đứng ở `1` và khối nào vẽ sau thì nằm trên: chồng khối \"lúc được lúc không\"\n // (đo 04/09/2026: `item.layerIndex` undefined, `getLayerIndex()` = 0 cho cả 8 khối).\n this.assignOverlapLayers(root);\n // Thay tham chiếu cây để `layerIndex` vừa gán tới được `$item` của gridster; component nội dung\n // KHÔNG bị dựng lại vì `attachNode` nhận ra id cũ và chỉ `setInput`.\n this.refresh();\n }\n\n /**\n *\n * Cấu hình gridster cho một cấp lưới.\n *\n * @param depth 0 = lưới cấp trang, ≥ 1 = lưới lồng trong container\n */\n private buildGridsterOptions(depth: number, itemChangeCallback?: () => void): GridsterConfig {\n const base = depth === 0 ? gridLayoutRootConfig() : gridLayoutNestedConfig();\n const config = this.config;\n\n if (!config) {\n return base;\n }\n\n const isFreeMode = config.mode === E_gridLayout_mode_string.free;\n const canEdit = this.editMode();\n const canOverlap = isFreeMode || (config.allowOverlap ?? false);\n\n return {\n ...base,\n scale: this.zoomLevel(),\n ...(config.cols ? { minCols: config.cols, maxCols: config.cols, maxItemCols: config.cols } : {}),\n ...(config.rowHeight && depth === 0 ? { fixedRowHeight: config.rowHeight } : {}),\n ...(depth === 0 && config.minRows !== undefined ? { minRows: config.minRows } : {}),\n ...(depth > 0 && config.nestedMinRows !== undefined ? { minRows: config.nestedMinRows } : {}),\n // Khe và chiều cao hàng khác nhau theo cấp: lưới trang thoáng, lưới lồng khít.\n ...(depth === 0 && config.margin !== undefined ? { margin: config.margin } : {}),\n ...(depth > 0 && config.nestedMargin !== undefined ? { margin: config.nestedMargin } : {}),\n ...(depth > 0 && config.nestedRowHeight !== undefined ? { fixedRowHeight: config.nestedRowHeight } : {}),\n ...(depth === 0 && config.outerMargin !== undefined ? { outerMargin: config.outerMargin } : {}),\n ...(depth === 0 && config.outerMarginBottom !== undefined ? { outerMarginBottom: config.outerMarginBottom } : {}),\n ...(config.minItemRows !== undefined ? { minItemRows: config.minItemRows } : {}),\n ...(config.defaultItemCols !== undefined ? { defaultItemCols: config.defaultItemCols } : {}),\n ...(config.defaultItemRows !== undefined ? { defaultItemRows: config.defaultItemRows } : {}),\n\n // 🔴 Chế độ XEM phải TẮT hẳn kéo và đổi kích thước.\n // `base` luôn để `enabled: true`; không ghi đè theo `editMode` thì người xem vẫn kéo được khối\n // và đổi bố cục của người khác (người dùng báo 28/08/2026: \"đang xem mà vẫn kéo thả thay đổi\n // vị trí và thêm khối được\").\n draggable: { ...base.draggable, enabled: canEdit },\n resizable: { ...base.resizable, enabled: canEdit },\n\n // Chế độ tự do LUÔN cho chồng; chế độ lưới thì theo cờ của nơi dùng.\n allowMultiLayer: canOverlap,\n // 🔴 Bật `allowMultiLayer` MỘT MÌNH không đủ. Mã lib so `layerIndex` của hai khối: KHÁC nhau\n // thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n // `defaultLayerIndex` — tức cùng lớp, và vẫn bị đẩy nhau như lưới thường (người dùng báo\n // 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n // Cho chồng thì phải TẮT đẩy khối, nếu không khối bị dạt đi trước khi kịp đè lên nhau.\n ...(canOverlap ? { pushItems: false, pushResizeItems: false, swap: false, swapWhileDragging: false } : {}),\n\n ...this.buildNestedResizeHooks(base, depth),\n\n itemChangeCallback: (item: GridsterItem) => {\n // 🔴 Khối vừa thao tác phải lên LỚP TRÊN CÙNG.\n // `layerIndex` gán một lần theo thứ tự cây lúc khởi tạo, nên khối kéo lên chỉ nổi TRONG LÚC\n // kéo (nhờ `z-index: 30` của lớp `gridster-item-moving`); thả tay ra là về lớp cũ và bị khối\n // đứng sau trong cây đè ngược lên (người dùng báo 28/08/2026, đo được: kéo z=30, thả về\n // z=10 trong khi hai khối kế bên đang z=11 và z=12).\n if (canOverlap) {\n this.raiseToTopLayer(item);\n }\n\n this.version.update((v) => v + 1);\n itemChangeCallback?.();\n },\n };\n }\n\n /**\n * Bắt lưới LỒNG đo lại NGAY khi khung chứa nó đổi bề rộng — dùng lúc người dùng kéo mép khối cha.\n *\n * Gridster có sẵn đường tự đo (`resize$`), nhưng luồng đó là `switchMap(() => timer(100))`: mỗi\n * lần phát lại huỷ timer trước, mà kéo chuột bắn dày hơn 100ms nên timer không bao giờ tới đích.\n * Đo được (11/09/2026): kéo mép nhóm thì lưới con co theo cha từng khung hình (234 → 384 px) còn\n * THẺ con đứng im ở 106 px suốt cú kéo, chỉ nhảy đúng sau khi thả tay.\n *\n * Giữ CẢ HAI đường: `itemResizeCallback` bắn đồng bộ ngay khi gridster ghi bề rộng mới lên khối\n * (sớm hơn `ResizeObserver` một khung hình) lo độ tức thì; `ResizeObserver` lo những lần khung đổi\n * vì lý do khác — đổi zoom, thu gọn cột bên trái.\n *\n * Tắt bằng `config.autoResizeNestedGrids: false`.\n */\n private buildNestedResizeHooks(base: GridsterConfig, depth: number): Partial<GridsterConfig> {\n if (this.config?.autoResizeNestedGrids === false) {\n return {};\n }\n const gocItemResize = base.itemResizeCallback;\n const gocInit = base.initCallback;\n\n return {\n itemResizeCallback: (item, itemComponent) => {\n gocItemResize?.(item, itemComponent);\n const el = (itemComponent as { el?: HTMLElement } | undefined)?.el;\n\n el?.querySelectorAll('gridster').forEach((nested) => this.resizeGridsterElement(nested as HTMLElement));\n },\n ...(depth > 0\n ? { initCallback: (gridster: GridsterComponentInterface) => this.registerNestedGrid(gridster, gocInit) }\n : {}),\n };\n }\n\n /** Gọi `resize()` của một thẻ `<gridster>` qua chính instance mà nó tự gắn lên phần tử. */\n private resizeGridsterElement(nested: HTMLElement): void {\n const giuInstance = nested as unknown as { __gridsterInstance?: { options?: { api?: { resize?: () => void } } } };\n\n giuInstance.__gridsterInstance?.options?.api?.resize?.();\n }\n\n /**\n * Gắn instance lên chính phần tử `<gridster>` rồi theo dõi bề rộng của nó.\n *\n * Phải gắn ngược lên DOM vì `itemResizeCallback` của khối CHA chỉ cầm được `HTMLElement`, không có\n * đường nào khác đi từ đó về instance của lưới lồng bên trong.\n */\n private registerNestedGrid(\n gridster: GridsterComponentInterface,\n goc?: (gridster: GridsterComponentInterface) => void\n ): void {\n goc?.(gridster);\n const instance = gridster as unknown as { el?: HTMLElement; options?: { api?: { resize?: () => void } } } | undefined;\n const el = instance?.el;\n\n if (!el || typeof ResizeObserver === 'undefined') {\n return;\n }\n (el as unknown as { __gridsterInstance?: unknown }).__gridsterInstance = instance;\n\n const theoDoi = new ResizeObserver(() => instance?.options?.api?.resize?.());\n\n theoDoi.observe(el);\n this.nestedResizeObservers.add(theoDoi);\n }\n\n /**\n *\n * Gắn component của nơi dùng lên một khối.\n *\n * @param host chỗ gắn RIÊNG của ô đó — mỗi khối một `ViewContainerRef`, dùng chung một cái thì\n * mọi component bị dồn hết vào một ô.\n */\n private attachNode(node: T_gridLayout_node, depth: number, host: ViewContainerRef): void {\n const config = this.config;\n\n if (!config) {\n return;\n }\n\n const existing = this.componentRefs.get(node.id);\n\n if (existing) {\n this.applyInputs(existing, node, depth);\n\n return;\n }\n\n // Khối tự khai thì hỏi nó; không thì hỏi hàm phân giải chung. Cả hai đều nhận `node` để đọc\n // được `data.type` mà quyết định trả component nào.\n const stream = (node.getComponentOutlet ?? config.getComponentOutlet)?.(node);\n\n if (!stream) {\n return;\n }\n\n // 🔴 Huỷ lượt tải CŨ của đúng khối này trước khi mở lượt mới.\n // Khối bị gỡ rồi gắn lại (đổi bố cục, sắp gọn) trong lúc `import()` chưa xong thì lượt cũ vẫn\n // chạy tiếp và dựng component vào một `ViewContainerRef` đã chết.\n this.pendingLoads.get(node.id)?.unsubscribe();\n\n const sub = stream.pipe(take(1)).subscribe((componentType) => {\n this.pendingLoads.delete(node.id);\n\n // Khối có thể đã bị xoá trong lúc chờ tải — dựng vào đây là rò rỉ.\n if (!this.treeService.findById(this.rootNode() ?? node, node.id)) {\n return;\n }\n\n const ref = host.createComponent(componentType);\n\n this.applyInputs(ref, node, depth);\n this.componentRefs.set(node.id, ref);\n });\n\n this.pendingLoads.set(node.id, sub);\n }\n\n /**\n * Gỡ component của một khối và huỷ nó. */\n private detachNode(nodeId: string): void {\n // Khối bị gỡ khi component của nó còn đang tải — phải huỷ lượt tải, không thì nó dựng vào một\n // `ViewContainerRef` đã chết.\n this.pendingLoads.get(nodeId)?.unsubscribe();\n this.pendingLoads.delete(nodeId);\n\n const ref = this.componentRefs.get(nodeId);\n\n if (!ref) {\n return;\n }\n\n ref.destroy();\n this.componentRefs.delete(nodeId);\n }\n\n private destroy(): void {\n for (const sub of this.pendingLoads.values()) {\n sub.unsubscribe();\n }\n\n for (const ref of this.componentRefs.values()) {\n ref.destroy();\n }\n\n for (const observer of this.nestedResizeObservers) {\n observer.disconnect();\n }\n\n this.pendingLoads.clear();\n this.componentRefs.clear();\n this.nestedResizeObservers.clear();\n this.config = undefined;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // Nhóm hàm cho nơi dùng CHỦ ĐỘNG gọi — không phải chờ người dùng bấm nút trên khối.\n // Sửa cây thì dùng thẳng `TreeService` rồi gọi `refresh()` — xem demo trong core-ui.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Báo cho service biết cây vừa đổi từ bên ngoài (thêm/xoá khối, sắp gọn, nạp bố cục khác).\n *\n * 🔴 PHẢI thay THAM CHIẾU của node gốc, không chỉ bơm `version`.\n * `@for … track item.id` giữ nguyên object khi id không đổi, nên `<gridster-item [item]=\"…\">` vẫn\n * nhận đúng object cũ và gridster không hề biết `x/y/cols/rows/layerIndex` vừa bị sửa. Bơm mỗi\n * `version` thì computed chạy lại nhưng trả về CÙNG mảng cũ — lưới đứng im (đo 28/08/2026: bấm\n * \"Sắp gọn\" cây đã dồn khít mà màn hình không nhúc nhích; bật chồng khối mà `$item.layerIndex`\n * vẫn trống).\n *\n * Nhân bản NÔNG cả node gốc và danh sách con là đủ: mảng mới → `@for` dựng lại item, object con\n * mới → gridster đọc lại toàn bộ toạ độ.\n */\n refresh(event?: T_gridLayout_changeEvent): void {\n const root = event?.root ?? this.rootNode();\n\n if (!root) {\n this.version.update((v) => v + 1);\n\n return;\n }\n\n if (this.config) {\n this.config = { ...this.config, data: root };\n }\n\n this.rootNode.set(this.shallowCloneTree(root));\n this.version.update((v) => v + 1);\n }\n\n /** Nhân bản nông theo cả chiều sâu: mỗi node và mảng `children` thành tham chiếu mới. */\n /**\n * Nhân bản SÂU cả cây — dùng cho `exportLayout()`.\n *\n * 🔴 BỎ `getComponentOutlet` khỏi bản sao: nó là một HÀM, không tuần tự hoá được nên gửi xuống\n * backend là hỏng (`JSON.stringify` nuốt mất, `structuredClone` ném lỗi). Nạp lại thì hàm phân\n * giải chung của cấu hình lo — component suy ra từ `data.type`, không cần lưu.\n */\n private deepCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n const copy: T_gridLayout_node = { ...node };\n\n // Cắt hàm phân giải — xem chú thích trên.\n delete copy.getComponentOutlet;\n\n const { children, data, ...rest } = copy;\n\n return {\n ...rest,\n ...(data === undefined ? {} : { data: cloneDeep(data) }),\n ...(children ? { children: children.map((child) => this.deepCloneTree(child)) } : {}),\n };\n }\n\n private shallowCloneTree(node: T_gridLayout_node): T_gridLayout_node {\n if (!node.children?.length) {\n return { ...node };\n }\n\n return { ...node, children: node.children.map((child) => this.shallowCloneTree(child)) };\n }\n\n /**\n * Gán `layerIndex` khác nhau cho từng khối khi bật chồng khối.\n *\n * 🔴 `allowMultiLayer: true` MỘT MÌNH không cho khối đè nhau. Mã lib so `layerIndex` của hai khối:\n * KHÁC nhau thì cho đè, GIỐNG nhau vẫn báo va chạm. Khối không khai `layerIndex` đều rơi về\n * `defaultLayerIndex` — tức CÙNG lớp, nên kéo vào nhau là bị chặn y như lưới thường (người dùng\n * báo 28/08/2026: \"bật chồng khối nhưng khi kéo thì các khối vẫn di chuyển theo\").\n *\n * Nơi dùng tự khai `layerIndex` thì giữ nguyên; ai không khai thì thư viện xếp mỗi khối một lớp\n * theo thứ tự, đủ để mọi cặp đều khác lớp.\n */\n private assignOverlapLayers(root: T_gridLayout_node): void {\n const config = this.config;\n const canOverlap = config?.mode === E_gridLayout_mode_string.free || (config?.allowOverlap ?? false);\n\n if (!canOverlap) {\n return;\n }\n\n let layer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n if (child.layerIndex === undefined) {\n layer += 1;\n child.layerIndex = layer;\n }\n\n walk(child);\n }\n };\n\n walk(root);\n\n }\n\n /** Đưa một khối lên trên tất cả: lớp của nó = lớp lớn nhất đang có + 1. */\n private raiseToTopLayer(item: GridsterItem): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n let topLayer = 0;\n const walk = (node: T_gridLayout_node): void => {\n for (const child of node.children ?? []) {\n topLayer = Math.max(topLayer, child.layerIndex ?? 0);\n walk(child);\n }\n };\n\n walk(root);\n\n // `item` gridster trả về CHÍNH là object node của cây (truyền thẳng qua `[item]`), nên gán vào\n // đây là cây cũng đổi theo.\n const node = item as unknown as T_gridLayout_node;\n\n if (node.layerIndex === topLayer) {\n\n return;\n }\n\n node.layerIndex = topLayer + 1;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────────────────\n // SỬA CÂY — thư viện đã giữ cây nên bạn KHÔNG phải truyền nó vào.\n // Mọi hàm dưới đây tự vẽ lại; không cần gọi `refresh()`.\n // ─────────────────────────────────────────────────────────────────────────────────────────\n\n /**\n * Thêm một khối.\n *\n * @param item khối mới — KHÔNG cần `id` (thư viện sinh) và `x`/`y` (tự đặt xuống hàng trống).\n * @param parentId container muốn thêm vào; bỏ trống thì thêm vào mặt phẳng gốc.\n * @returns khối vừa tạo (kèm `id` vừa sinh), hoặc `undefined` khi không tìm thấy container.\n */\n addBlock(item: T_gridLayout_newNode, parentId?: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root ? this.treeService.addChild(root, parentId ?? root.id, item) : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n /**\n * Thêm một khối tại toạ độ (col, row) cụ thể và tự động đẩy các khối va chạm xuống dưới.\n */\n insertBlockWithCollision(\n item: T_gridLayout_newNode,\n targetCol = 0,\n targetRow = 0,\n parentId?: string,\n ): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const added = root\n ? this.treeService.insertWithCollision(root, parentId ?? root.id, item, targetCol, targetRow)\n : undefined;\n\n if (added) {\n this.refresh();\n }\n\n return added;\n }\n\n private readonly activeDragPayload = signal<unknown | undefined>(undefined);\n\n /** Đặt payload khi bắt đầu kéo từ bên ngoài vào (ví dụ: palette, drawer) */\n setDragPayload(payload: unknown): void {\n this.activeDragPayload.set(payload);\n }\n\n /** Lấy payload đang kéo */\n getDragPayload(): unknown {\n return this.activeDragPayload();\n }\n\n /** Xoá payload khi kết thúc kéo */\n clearDragPayload(): void {\n this.activeDragPayload.set(undefined);\n }\n\n /** Xoá một khối. Xoá container là xoá cả ruột. Trả `false` khi không xoá được (vd khối gốc). */\n removeBlock(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.removeById(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /**\n * Số cột thật của lưới cấp trang.\n *\n * 🔴 Mặc định phải TRÙNG `minCols/maxCols` của `gridLayoutRootConfig()`. Trước đây chỗ này trả 24\n * trong khi lưới vẽ 12: nơi dùng không truyền `cols` thì va chạm, `toContainer` và `compact` tính\n * theo 24 cột còn màn hình chỉ có 12 — khối rơi ra ngoài mép phải mà không ai hiểu vì sao.\n */\n get totalColumns(): number {\n return this.config?.cols ?? gridLayoutRootConfig().maxCols ?? 12;\n }\n\n /**\n * Đổi số cột / số hàng của một khối rồi vẽ lại.\n *\n * Kéo `cols` rộng quá mép phải thì dịch khối sang trái cho vừa, thay vì để nó tràn ra ngoài lưới.\n */\n resizeBlock(id: string, size: { cols?: number; rows?: number }): boolean {\n const node = this.findBlock(id);\n\n if (!node) {\n return false;\n }\n\n if (size.cols !== undefined) {\n node.cols = size.cols;\n if (node.x + size.cols > this.totalColumns) {\n node.x = Math.max(0, this.totalColumns - size.cols);\n }\n }\n\n if (size.rows !== undefined) {\n node.rows = size.rows;\n }\n this.refresh();\n\n return true;\n }\n\n /**\n * Nhân bản một khối — đặt kế bên phải nếu còn chỗ, không thì xuống dòng dưới.\n *\n * `transformData` để nơi dùng đổi phần dữ liệu riêng của mình (vd nối thêm \"(Bản sao)\" vào tiêu\n * đề); thư viện không tự đoán trường nào là tiêu đề.\n */\n duplicateBlock(id: string, transformData?: (data: unknown) => unknown): T_gridLayout_node | undefined {\n const root = this.rootNode();\n const node = root ? findNodeRecursive(root, id) : undefined;\n\n if (!root || !node) {\n return undefined;\n }\n const parent = findParentRecursive(root, id);\n const isNested = Boolean(parent && parent.id !== root.id);\n const clonedData = cloneDeep(node.data);\n\n let targetX = node.x + node.cols;\n let targetY = node.y;\n\n if (targetX + node.cols > this.totalColumns) {\n targetX = 0;\n targetY = node.y + node.rows;\n }\n\n return this.addBlock(\n {\n x: targetX,\n y: targetY,\n cols: node.cols,\n rows: node.rows,\n data: transformData ? transformData(clonedData) : clonedData,\n getComponentOutlet: node.getComponentOutlet,\n },\n isNested ? parent?.id : undefined\n );\n }\n\n /** Biến khối đơn thành CONTAINER — nội dung cũ thành khối con đầu tiên, không mất dữ liệu. */\n toContainer(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toContainer(root, id, this.totalColumns) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Đưa CONTAINER về khối đơn — khối con được nâng lên cấp trên, không bị xoá. */\n toSingle(id: string): boolean {\n const root = this.rootNode();\n const done = root ? this.treeService.toSingle(root, id) : false;\n\n if (done) {\n this.refresh();\n }\n\n return done;\n }\n\n /** Dồn khối khít lên trên, lấp hết chỗ trống. Đệ quy vào container. */\n compact(): void {\n const root = this.rootNode();\n\n if (!root) {\n return;\n }\n\n this.treeService.compact(root, this.totalColumns);\n this.refresh();\n }\n\n /**\n * Bố cục HIỆN TẠI, đã cắt mọi tham chiếu — gửi thẳng xuống backend được.\n *\n * Dùng khi bấm nút Lưu. Khác `Root()` ở chỗ đây là bản SAO: nơi dùng có sửa gì trên kết quả cũng\n * không đụng tới cây mà thư viện đang vẽ.\n *\n * @returns `undefined` khi mặt phẳng chưa `init()`.\n */\n exportLayout(): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.deepCloneTree(root) : undefined;\n }\n\n /** Tìm một khối theo id. */\n findBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findById(root, id) : undefined;\n }\n\n /** Tìm khối cha trực tiếp của một khối. */\n findParentBlock(id: string): T_gridLayout_node | undefined {\n const root = this.rootNode();\n\n return root ? this.treeService.findParent(root, id) : undefined;\n }\n\n /**\n * Đặt tỷ lệ thu phóng của canvas (kẹp giữa min và max).\n *\n * @param value Tỷ lệ (0.4 = 40%, 1.0 = 100%, 1.5 = 150%)\n * @param persistKey Khóa localStorage để lưu lại (bỏ trống thì lấy từ config)\n */\n setZoom(value: number, persistKey?: string): void {\n const min = this.config?.zoomMin ?? 0.4;\n const max = this.config?.zoomMax ?? 1.5;\n const clamped = Math.min(max, Math.max(min, Math.round(value * 100) / 100));\n this.zoomLevel.set(clamped);\n\n const storageKey = persistKey ?? this.config?.storageKey;\n if (storageKey && typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(storageKey, String(clamped));\n } catch {\n // ignore localStorage access error\n }\n }\n\n this.version.update((v) => v + 1);\n }\n\n /** Phóng to thêm một bước (mặc định 0.05 tức 5%) */\n zoomIn(step?: number, persistKey?: string): void {\n const s = step ?? this.config?.zoomStep ?? 0.05;\n this.setZoom(this.zoomLevel() + s, persistKey);\n }\n\n /** Thu nhỏ bớt một bước (mặc định 0.05 tức 5%) */\n zoomOut(step?: number, persistKey?: string): void {\n const s = step ?? this.config?.zoomStep ?? 0.05;\n this.setZoom(this.zoomLevel() - s, persistKey);\n }\n\n /** Đặt lại tỷ lệ thu phóng gốc 100% (1.0) */\n resetZoom(persistKey?: string): void {\n this.setZoom(1.0, persistKey);\n }\n\n /**\n * Tự động tính toán và đặt tỷ lệ thu phóng để canvas vừa vặn với chiều rộng container.\n *\n * @param containerWidth Chiều rộng container đo được (px)\n * @param stageWidth Chiều rộng chuẩn của canvas (mặc định 1668px)\n * @param padding Khoảng cách lề hai bên (mặc định 48px)\n * @param persistKey Khóa localStorage\n * @returns Tỷ lệ thu phóng vừa tính\n */\n fitToScreen(containerWidth: number, stageWidth?: number, padding = 48, persistKey?: string): number {\n const targetWidth = stageWidth ?? this.config?.stageWidth ?? 1668;\n const min = this.config?.zoomMin ?? 0.4;\n const max = 1.25;\n const ratio = Math.min(max, Math.max(min, Math.round(((containerWidth - padding) / targetWidth) * 100) / 100));\n this.setZoom(ratio, persistKey);\n return ratio;\n }\n\n /** Kiểm tra tính năng thu phóng có được cấu hình bật không */\n isZoomConfigured(): boolean {\n return Boolean(this.config?.enableZoom);\n }\n\n /**\n * Cổng DUY NHẤT cho canvas của thư viện. Nơi dùng KHÔNG gọi tới đây.\n *\n * Mọi thứ canvas cần đều là `private` để không lọt ra API công khai; gom vào một getter theo đúng\n * khuôn `FunctionsControl` của bộ quy ước, thay vì để rải rác hàm public mà người ngoài tưởng\n * mình phải gọi (người dùng chốt 28/08/2026).\n */\n get FunctionsControl() {\n return {\n maxContainerDepth: () => this.maxContainerDepth(),\n containerPadding: () => this.containerPadding(),\n isZoomEnabled: () => this.isZoomConfigured(),\n zoom: () => this.zoomLevel(),\n setZoom: (v: number, key?: string) => this.setZoom(v, key),\n zoomIn: (step?: number, key?: string) => this.zoomIn(step, key),\n zoomOut: (step?: number, key?: string) => this.zoomOut(step, key),\n resetZoom: (key?: string) => this.resetZoom(key),\n fitToScreen: (cW: number, sW?: number, pad?: number, key?: string) => this.fitToScreen(cW, sW, pad, key),\n gridsterOptions: (depth: number, cb?: () => void) => this.buildGridsterOptions(depth, cb),\n attachNode: (node: T_gridLayout_node, depth: number, host: ViewContainerRef) => this.attachNode(node, depth, host),\n detachNode: (nodeId: string) => this.detachNode(nodeId),\n };\n }\n\n private applyInputs(ref: ComponentRef<unknown>, node: T_gridLayout_node, depth: number): void {\n ref.setInput('data', node.data);\n ref.setInput('node', node);\n ref.setInput('isEditMode', this.editMode());\n ref.setInput('depth', depth);\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n OnDestroy,\n TemplateRef,\n ViewContainerRef,\n computed,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n viewChild,\n viewChildren,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';\nimport { GridsterComponent, GridsterModule } from 'gridster18';\nimport { TranslateModule } from '@ngx-translate/core';\nimport { emptyRootNode } from '../defines/gridster-config.define';\nimport { LibsUiGridLayoutService } from '../grid-layout.service';\nimport {\n T_gridLayout_actionEvent,\n T_gridLayout_addEvent,\n T_gridLayout_changeEvent,\n T_gridLayout_dropEvent,\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_newNode,\n T_gridLayout_node,\n T_gridLayout_toolbarContext,\n T_gridLayout_zoomPreset,\n} from '../interfaces/grid-layout.interface';\nimport { calculateDropGhost, parseDropPayload } from '../defines/collision.define';\n\n/**\n * Mặt phẳng kéo thả. Đệ quy: khối có `children` thì ruột nó lại là một mặt phẳng nữa.\n *\n * Nơi dùng KHÔNG dựng component này trực tiếp cho từng khối — chỉ đặt MỘT thẻ ở gốc và truyền\n * `nodeComponentType` qua `LibsUiGridLayoutService.init()`. Thư viện tự gắn component cho mọi khối.\n */\n@Component({\n selector: 'libs_ui-services-grid_layout-canvas',\n standalone: true,\n imports: [GridsterModule, LibsUiComponentsButtonsButtonComponent, NgTemplateOutlet, TranslateModule],\n templateUrl: './grid-layout-canvas.component.html',\n styleUrl: './grid-layout-canvas.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class LibsUiGridLayoutCanvasComponent implements AfterViewInit, OnDestroy {\n /**\n * @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền khi vẽ ruột container.\n *\n * Nơi dùng KHÔNG truyền: mặt phẳng gốc đọc cây từ service (đã đưa vào qua `init()`), truyền thêm\n * ở đây là khai hai lần cùng một thứ (người dùng chốt 28/08/2026).\n */\n readonly node = input<T_gridLayout_node>();\n /** @internal Chỉ mặt phẳng LỒNG dùng — thư viện tự truyền. */\n readonly depth = input<number>(0);\n\n /**\n * Ẩn hẳn thanh công cụ mặc định (thêm-vào-trong · gộp/tách · xoá) của MỌI khối.\n *\n * Dùng khi sản phẩm gom các hành động đó vào chỗ khác — vd một nút ⋮ nằm trong chính nội dung\n * khối. Ẩn rồi thì `outRemoveNode` · `outAddBlockInside` · `outToggleType` không còn nguồn phát\n * từ thư viện; nơi dùng tự gọi `removeBlock` · `addBlock` · `toggleType` của service.\n */\n readonly hiddenToolbar = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /**\n * Template tự vẽ thanh công cụ, thay cho bộ nút mặc định.\n *\n * Nhận context `{ $implicit: node, isContainer, canAddInside, canToggleType }` để nơi dùng vẽ đúng\n * nút cho từng khối, rồi gọi ngược qua `outRemoveNode` · `outAddBlockInside` · `outToggleType`\n * bằng chính các hàm trong context. Truyền cả `hiddenToolbar` và `templateToolbar` thì\n * `hiddenToolbar` thắng — không vẽ gì.\n */\n readonly templateToolbar = input<TemplateRef<T_gridLayout_toolbarContext> | undefined>(undefined);\n\n /**\n * Bố cục vừa đổi do NGƯỜI DÙNG kéo hoặc đổi kích thước khối.\n *\n * Nơi dùng tự gọi `addBlock` · `removeBlock` · `compact` thì KHÔNG bắn — họ vừa gọi thì đã biết,\n * bắn ngược lại là thừa (người dùng chốt 28/08/2026).\n */\n readonly outChange = output<T_gridLayout_changeEvent>();\n /**\n * Người dùng bấm nút XOÁ trên một khối. Thư viện CHƯA xoá — gọi `event.confirm()` để xoá thật.\n * Cần hỏi trước thì hỏi xong mới gọi; không cho phép thì đừng gọi.\n */\n readonly outRemoveNode = output<T_gridLayout_actionEvent>();\n /**\n * Người dùng bấm nút THÊM trên một container. Thư viện KHÔNG tự thêm — nó không biết bạn có\n * những loại khối nào. Mở menu chọn loại rồi gọi `event.confirm(item)` với khối bạn muốn thêm.\n */\n readonly outAddBlockInside = output<T_gridLayout_addEvent>();\n /** Người dùng bấm nút GỘP/TÁCH. Thư viện chưa làm gì — gọi `event.confirm()` để thực hiện. */\n readonly outToggleType = output<T_gridLayout_actionEvent>();\n\n /** Bật tính năng thu phóng (zoom) canvas. Chỉ áp dụng cho canvas gốc (depth 0). */\n readonly enableZoom = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /** Tỷ lệ thu phóng hiện tại (hỗ trợ two-way binding [(zoom)]=\"myZoom\"). */\n readonly zoom = model<number | undefined>(undefined);\n\n /** Giới hạn thu phóng tối thiểu. Mặc định 0.4 (40%). */\n readonly zoomMin = input<number>(0.4);\n\n /** Giới hạn thu phóng tối đa. Mặc định 1.5 (150%). */\n readonly zoomMax = input<number>(1.5);\n\n /** Bước nhảy thu phóng mỗi lần bấm +/- hoặc lăn chuột. Mặc định 0.05 (5%). */\n readonly zoomStep = input<number>(0.05);\n\n /** Chiều rộng chuẩn của canvas stage tính bằng px. Mặc định 1668. */\n readonly stageWidth = input<number>(1668);\n\n /** Chiều cao tối thiểu của canvas stage tính bằng px. Mặc định 937. */\n readonly stageMinHeight = input<number>(937);\n\n /** Khóa lưu tỷ lệ thu phóng vào localStorage. Mặc định 'ocb_bi_canvas_zoom'. */\n readonly storageKey = input<string | undefined>('ocb_bi_canvas_zoom');\n\n /** Hiển thị thanh dock điều khiển thu phóng nổi ở góc dưới phải. Mặc định true. */\n readonly showZoomDock = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Tự động vừa màn hình khi tải trang lần đầu nếu khung nhìn nhỏ hơn stageWidth. Mặc định true. */\n readonly autoFitOnLoad = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Phát ra khi tỷ lệ thu phóng thay đổi. */\n readonly outZoomChange = output<number>();\n\n /** Bật tính năng kéo thả thẻ từ bên ngoài vào canvas (mặc định true) */\n readonly enableExternalDrop = input<boolean, boolean | undefined>(true, { transform: (value) => value ?? true });\n\n /** Luôn hiển thị đường kẻ lưới 24 cột */\n readonly showGridLines = input<boolean, boolean | undefined>(false, { transform: (value) => value ?? false });\n\n /** Mã id của khối đang được chọn */\n readonly selectedNodeId = model<string | null | undefined>(undefined);\n\n /** Phát ra khi thả một thẻ mới từ bên ngoài vào canvas */\n readonly outDropNode = output<T_gridLayout_dropEvent>();\n\n /** Phát ra khi người dùng click chọn một khối */\n readonly outSelectNode = output<T_gridLayout_node>();\n\n /** Phát ra khi người dùng bấm nút cấu hình trên thanh công cụ của khối */\n readonly outConfigNode = output<T_gridLayout_actionEvent>();\n\n private readonly gridsterRef = viewChild(GridsterComponent);\n private readonly scrollAreaRef = viewChild<ElementRef<HTMLElement>>('scrollArea');\n private readonly zoomDockRef = viewChild<ElementRef<HTMLElement>>('zoomDock');\n /** mỗi ô một chỗ gắn riêng — cùng thứ tự với `children()` */\n private readonly itemHosts = viewChildren('itemHost', { read: ViewContainerRef });\n\n /** Khung xem trước vị trí thả thẻ từ bên ngoài (snapped ghost preview) */\n protected readonly dropGhost = signal<T_gridLayout_dropGhost | undefined>(undefined);\n\n private activeHoveredEl?: HTMLElement;\n private rootGridsterEl?: HTMLElement;\n\n /** Menu chọn preset thu phóng đang mở hay đóng */\n protected readonly isMenuOpen = signal<boolean>(false);\n\n /** Các mốc thu phóng định sẵn */\n protected readonly zoomPresets: Array<T_gridLayout_zoomPreset> = [\n { label: 'i18n_zoom_preset_overview', value: 0.5 },\n { label: 'i18n_zoom_preset_small_laptop', value: 0.67 },\n { label: 'i18n_zoom_preset_laptop_1080p', value: 0.75 },\n { label: 'i18n_zoom_preset_screen_1080p', value: 0.85 },\n { label: 'i18n_zoom_preset_standard', value: 0.9 },\n { label: 'i18n_zoom_preset_original_size', value: 1 },\n { label: 'i18n_zoom_preset_large_screen', value: 1.1 },\n { label: 'i18n_zoom_preset_high_dpi_2k', value: 1.25 },\n ];\n\n /** Sáu chấm của tay cầm kéo — chỉ để `@for` dựng đủ 6 thẻ, giá trị không dùng tới. */\n protected readonly dragBarDots = [0, 1, 2, 3, 4, 5];\n\n private readonly service = inject(LibsUiGridLayoutService);\n\n /** Chế độ thu phóng có đang hoạt động trên canvas này không (chỉ root canvas depth 0) */\n protected readonly isZoomActive = computed(() => {\n return this.depth() === 0 && (this.enableZoom() || this.service.FunctionsControl.isZoomEnabled());\n });\n\n protected readonly currentZoom = computed(() => this.service.Zoom());\n protected readonly zoomPercent = computed(() => Math.round(this.currentZoom() * 100));\n\n /**\n * Node THẬT của mặt phẳng này.\n *\n * 🔴 Mặt phẳng GỐC (depth 0) đọc cây từ SERVICE, không dùng input.\n * Nơi dùng thường sửa cây TẠI CHỖ (`treeService.compact(tree)`) rồi gọi `refresh()`, nên signal\n * `root()` của họ giữ nguyên tham chiếu và input `node` không hề đổi — `@for` không dựng lại\n * `gridster-item`, lưới đứng im dù dữ liệu đã khác (đo 28/08/2026: bấm \"Sắp gọn\" không tác dụng).\n * `refresh()` của service thay tham chiếu cây, nên đọc từ đó mới thấy thay đổi.\n *\n * Mặt phẳng LỒNG vẫn dùng input: nó nhận node con từ mặt phẳng cha, vốn đã là object mới.\n */\n protected readonly currentNode = computed(() => {\n this.service.Version();\n\n if (this.depth() > 0) {\n return this.node() ?? emptyRootNode();\n }\n\n return this.service.Root() ?? emptyRootNode();\n });\n\n protected readonly children = computed(() => this.currentNode().children ?? []);\n\n /**\n * Bối cảnh cho `templateToolbar`, dựng sẵn theo từng khối.\n *\n * Dựng ở `computed` chứ không gọi hàm trên template: gọi hàm trong template chạy lại mỗi vòng\n * dò thay đổi (rule `fe-coding-convention-templates` mục 6).\n */\n protected readonly toolbarContexts = computed<Array<T_gridLayout_toolbarContext>>(() =>\n this.children().map((item) => ({\n $implicit: item,\n isContainer: this.isContainer(item),\n canAddInside: this.canAddInside(item),\n canToggleType: this.canToggleType(item),\n remove: () => this.outRemoveNode.emit({ nodeId: item.id, node: item, confirm: () => this.service.removeBlock(item.id) }),\n addInside: () => this.emitAddInside(item),\n toggleType: () => this.emitToggleType(item),\n }))\n );\n\n protected readonly isNestedCanvas = computed(() => this.depth() > 0);\n\n /** trần lồng container — khối đã chạm trần thì không cho chuyển thành container */\n protected readonly maxContainerDepth = computed(() => this.service.FunctionsControl.maxContainerDepth());\n\n /**\n * Lề trong của container, px.\n *\n * 🔴 Đặt trên VỎ container, không đặt vào lưới con. Lưới con giữ nguyên `margin: 2` như cũ; lề\n * này chỉ co ruột lại khỏi biên vỏ, nhờ đó tay cầm đổi kích thước của khối con luôn nằm trong tầm\n * chuột (người dùng chốt 28/08/2026).\n */\n protected readonly containerPadding = computed(() => `${this.service.FunctionsControl.containerPadding()}px`);\n\n /** Dải kéo chỉ hiện ở chế độ sửa — chế độ xem không kéo được nên hiện dải là gây nhầm. */\n protected readonly isEditMode = computed(() => this.service.IsEditMode());\n\n protected readonly gridOptions = computed(() => {\n // Đọc `Version` để `init()` lại (đổi chế độ, bật/tắt chồng khối) sinh ra options MỚI —\n // gridster chỉ áp dụng cấu hình khi tham chiếu `options` đổi.\n this.service.Version();\n\n return this.service.FunctionsControl.gridsterOptions(this.depth(), () => this.outChange.emit({ root: this.currentNode() }));\n });\n\n constructor() {\n // Gắn component của nơi dùng vào từng ô, và gắn LẠI mỗi khi cây đổi.\n // Dùng effect vì `itemHosts()` chỉ có giá trị sau khi Angular dựng xong @for.\n effect(() => {\n const hosts = this.itemHosts();\n const items = this.children();\n\n items.forEach((item, i) => {\n const host = hosts[i];\n\n if (!host) {\n return;\n }\n\n // Khối có con là CONTAINER: ruột nó do mặt phẳng lồng vẽ, không gắn component nội dung.\n if ((item.children?.length ?? 0) > 0) {\n return;\n }\n\n this.service.FunctionsControl.attachNode(item, this.depth() + 1, host);\n });\n });\n\n // Đồng bộ nếu model zoom bên ngoài thay đổi\n effect(() => {\n const z = this.zoom();\n if (z !== undefined && Math.abs(z - this.service.Zoom()) > 0.001) {\n this.service.FunctionsControl.setZoom(z, this.storageKey());\n }\n });\n }\n\n ngAfterViewInit(): void {\n if (!this.isZoomActive() || !this.autoFitOnLoad()) {\n return;\n }\n\n const key = this.storageKey();\n let hasSaved = false;\n if (key && typeof localStorage !== 'undefined') {\n try {\n hasSaved = Boolean(localStorage.getItem(key));\n } catch {\n // ignore localStorage access error\n }\n }\n\n if (!hasSaved) {\n setTimeout(() => {\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n if (scrollEl && scrollEl.clientWidth > 0 && scrollEl.clientWidth < this.stageWidth() + 64) {\n this.handlerFitScreen();\n }\n }, 50);\n }\n }\n\n ngOnDestroy(): void {\n this.cleanupDragGrid();\n for (const item of this.children()) {\n this.service.FunctionsControl.detachNode(item.id);\n }\n }\n\n /** Vẽ lại lưới — gọi khi khung ngoài đổi kích thước hoặc cây vừa đổi diện rộng. */\n get FunctionControl() {\n return {\n veLaiLuoi: () => this.gridsterRef()?.optionsChanged(),\n zoomIn: () => this.handlerZoomIn(),\n zoomOut: () => this.handlerZoomOut(),\n resetZoom: () => this.handlerResetZoom(),\n fitToScreen: () => this.handlerFitScreen(),\n setZoom: (val: number) => {\n this.service.FunctionsControl.setZoom(val, this.storageKey());\n this.syncZoomOut();\n },\n // Vùng cuộn của mặt phẳng — nơi dùng cần nó để tự cuộn tới một khối, hoặc đo toạ độ khi kéo.\n // Không mở ở đây thì nơi dùng phải dò bằng tên lớp CSS nội bộ, và tên đó đổi lúc nào không hay.\n scrollArea: (): HTMLElement | undefined => this.scrollAreaRef()?.nativeElement,\n };\n }\n\n protected handlerZoomIn(): void {\n this.service.FunctionsControl.zoomIn(this.zoomStep(), this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerZoomOut(): void {\n this.service.FunctionsControl.zoomOut(this.zoomStep(), this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerResetZoom(): void {\n this.service.FunctionsControl.resetZoom(this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerFitScreen(): void {\n this.isMenuOpen.set(false);\n const scrollEl = this.scrollAreaRef()?.nativeElement;\n const containerWidth = scrollEl?.clientWidth || (typeof window !== 'undefined' ? window.innerWidth - 300 : 1200);\n this.service.FunctionsControl.fitToScreen(containerWidth, this.stageWidth(), 48, this.storageKey());\n this.syncZoomOut();\n }\n\n protected handlerToggleMenu(): void {\n this.isMenuOpen.update((open) => !open);\n }\n\n protected handlerSelectPreset(value: number): void {\n this.isMenuOpen.set(false);\n this.service.FunctionsControl.setZoom(value, this.storageKey());\n this.syncZoomOut();\n }\n\n protected isCurrentPreset(value: number): boolean {\n return Math.abs(this.currentZoom() - value) < 0.01;\n }\n\n private syncZoomOut(): void {\n const val = this.service.Zoom();\n this.outZoomChange.emit(val);\n if (this.zoom() !== val) {\n this.zoom.set(val);\n }\n }\n\n protected handlerWheel(event: WheelEvent): void {\n if (!this.isZoomActive()) {\n return;\n }\n\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n if (event.deltaY < 0) {\n this.handlerZoomIn();\n } else if (event.deltaY > 0) {\n this.handlerZoomOut();\n }\n }\n }\n\n @HostListener('document:keydown', ['$event'])\n protected handlerDocumentKeyDown(event: KeyboardEvent): void {\n if (!this.isZoomActive()) {\n return;\n }\n\n if (event.ctrlKey || event.metaKey) {\n if (event.key === '=' || event.key === '+') {\n event.preventDefault();\n this.handlerZoomIn();\n } else if (event.key === '-' || event.key === '_') {\n event.preventDefault();\n this.handlerZoomOut();\n } else if (event.key === '0') {\n event.preventDefault();\n this.handlerResetZoom();\n }\n }\n }\n\n @HostListener('document:click', ['$event'])\n protected handlerDocumentClick(event: MouseEvent): void {\n if (!this.isMenuOpen()) {\n return;\n }\n\n const dockEl = this.zoomDockRef()?.nativeElement;\n if (dockEl && !dockEl.contains(event.target as Node)) {\n this.isMenuOpen.set(false);\n }\n }\n\n protected handlerTrackNode(_index: number, item: T_gridLayout_node): string {\n return item.id;\n }\n\n /**\n * 🔴 Chặn `mousedown` nổi lên lưới CHA khi thao tác trong lưới con.\n * Không chặn thì cả hai lưới cùng nhận một cú bấm: kéo khối con là nhấc luôn container.\n */\n /**\n * Chặn `mousedown` của khối trong lưới LỒNG nổi lên lưới cha.\n *\n * Chỉ chặn ở lưới lồng: lưới cấp trang không có cha nào để chặn, và chặn ở đó sẽ nuốt luôn thao\n * tác của chính nó.\n */\n /**\n * 🔴 Ba handler dưới đây PHẢI `stopPropagation`.\n * Nút nằm trong vùng mang `dragHandleClass`, không chặn thì cú bấm bị gridster hiểu là bắt đầu kéo\n * và `delayStart: 160` nuốt luôn `click` — người dùng thấy như nút chết.\n */\n protected handlerRemove(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.outRemoveNode.emit({ nodeId: node.id, node, confirm: () => this.service.removeBlock(node.id) });\n }\n\n protected handlerAddInside(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitAddInside(node);\n }\n\n protected handlerToggleType(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitToggleType(node);\n }\n\n /**\n * Chặn cú bấm trong thanh công cụ nổi lên gridster.\n *\n * Chỉ `stopPropagation`, KHÔNG `preventDefault`: nút bên trong template của nơi dùng vẫn cần\n * hành vi mặc định của mình (mở dropdown, focus…).\n */\n protected handlerStopEvent(event: Event): void {\n event.stopPropagation();\n }\n\n /** Phát `outAddBlockInside` — dùng chung cho nút mặc định và `templateToolbar`. */\n private emitAddInside(node: T_gridLayout_node): void {\n this.outAddBlockInside.emit({\n nodeId: node.id,\n node,\n confirm: (item: T_gridLayout_newNode) => this.service.addBlock(item, node.id),\n });\n }\n\n /** Phát `outToggleType` — dùng chung cho nút mặc định và `templateToolbar`. */\n private emitToggleType(node: T_gridLayout_node): void {\n this.outToggleType.emit({\n nodeId: node.id,\n node,\n // Gộp hay tách suy ra từ chính khối: đang là container thì tách, không thì gộp.\n confirm: () => (this.isContainer(node) ? this.service.toSingle(node.id) : this.service.toContainer(node.id)),\n });\n }\n\n /** khối này có phải container không (có khối con) */\n protected isContainer(item: T_gridLayout_node): boolean {\n return (item.children?.length ?? 0) > 0;\n }\n\n /** container đã chạm trần lồng thì không cho thêm khối vào trong nữa */\n protected canAddInside(item: T_gridLayout_node): boolean {\n return this.isContainer(item) && this.depth() < this.maxContainerDepth();\n }\n\n /** khối đơn ở cấp chưa chạm trần mới được chuyển thành container */\n protected canToggleType(item: T_gridLayout_node): boolean {\n if (this.isContainer(item)) {\n return true;\n }\n\n return this.depth() < this.maxContainerDepth();\n }\n\n protected handlerBlockParentDrag(event: Event): void {\n if (!this.isNestedCanvas()) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerMouseDownTrongLuoi(event: Event): void {\n if (this.depth() === 0) {\n return;\n }\n\n event.stopPropagation();\n }\n\n protected handlerSelectNode(node: T_gridLayout_node, event?: MouseEvent): void {\n if (event) {\n const target = event.target as HTMLElement;\n if (target.closest('.libs-ui-grid-layout-toolbar') || target.closest('button')) {\n return;\n }\n }\n this.selectedNodeId.set(node.id);\n this.outSelectNode.emit(node);\n }\n\n protected handlerConfig(event: Event, node: T_gridLayout_node): void {\n event.stopPropagation();\n const actionEvent: T_gridLayout_actionEvent = {\n nodeId: node.id,\n node,\n confirm: () => true,\n };\n this.outConfigNode.emit(actionEvent);\n }\n\n protected handlerDragOver(event: DragEvent): void {\n if (!this.enableExternalDrop() || this.depth() > 0) {\n return;\n }\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n const container = this.scrollAreaRef()?.nativeElement;\n const root = this.service.Root();\n const payload = parseDropPayload<T_gridLayout_externalDragPayload>(\n this.service.getDragPayload() as T_gridLayout_externalDragPayload | undefined,\n event.dataTransfer,\n );\n\n if (!container || !root || !payload) {\n return;\n }\n\n const rootGridster = container.querySelector('gridster') as HTMLElement | null;\n if (rootGridster) {\n if (!rootGridster.classList.contains('display-grid')) {\n rootGridster.classList.add('display-grid');\n }\n this.rootGridsterEl = rootGridster;\n }\n\n const ghost = calculateDropGhost(event, container, root, payload, this.service.totalColumns);\n\n if (ghost?.isInsideGroup && ghost.hoveredGridster) {\n if (this.activeHoveredEl !== ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n ghost.hoveredGridster.classList.add('display-grid');\n this.activeHoveredEl = ghost.hoveredGridster;\n }\n } else {\n this.cleanupHoveredGroup();\n }\n\n this.dropGhost.set(ghost);\n }\n\n protected handlerDragLeave(event: DragEvent): void {\n if (this.depth() > 0) {\n return;\n }\n if (event.relatedTarget) {\n const container = this.scrollAreaRef()?.nativeElement;\n if (container && container.contains(event.relatedTarget as Node)) {\n return;\n }\n }\n this.dropGhost.set(undefined);\n this.cleanupDragGrid();\n }\n\n protected handlerDrop(event: DragEvent): void {\n if (!this.enableExternalDrop() || this.depth() > 0) {\n return;\n }\n event.preventDefault();\n const ghost = this.dropGhost();\n const payload = parseDropPayload<T_gridLayout_externalDragPayload>(\n this.service.getDragPayload() as T_gridLayout_externalDragPayload | undefined,\n event.dataTransfer,\n );\n\n this.dropGhost.set(undefined);\n this.cleanupDragGrid();\n this.service.clearDragPayload();\n\n if (!ghost || !payload) {\n return;\n }\n\n const targetParentId = ghost.isInsideGroup ? ghost.targetParentId : undefined;\n const isInside = Boolean(targetParentId);\n\n let itemToAdd: T_gridLayout_newNode;\n const payloadAny = payload as Record<string, unknown>;\n if (typeof payloadAny['resolveNode'] === 'function') {\n const resolved = (payloadAny['resolveNode'] as (inside: boolean) => T_gridLayout_newNode | undefined)(isInside);\n itemToAdd = resolved ?? {\n cols: ghost.cols,\n rows: ghost.rows,\n data: payload.data ?? (payload.type ? { type: payload.type, title: payload.title } : undefined),\n };\n } else {\n const newNodeData = payload.data ?? (payload.type ? { type: payload.type, title: payload.title } : undefined);\n itemToAdd = {\n cols: ghost.cols,\n rows: ghost.rows,\n data: newNodeData,\n };\n }\n\n const addedNode = this.service.insertBlockWithCollision(\n itemToAdd,\n ghost.col,\n ghost.row,\n targetParentId,\n );\n\n if (addedNode) {\n this.selectedNodeId.set(addedNode.id);\n this.outDropNode.emit({\n node: addedNode,\n parentId: targetParentId,\n col: ghost.col,\n row: ghost.row,\n cols: ghost.cols,\n rows: ghost.rows,\n rawEvent: event,\n payload,\n });\n const root = this.service.Root();\n if (root) {\n this.outChange.emit({\n root,\n nodeId: addedNode.id,\n });\n }\n }\n }\n\n private cleanupHoveredGroup(): void {\n if (this.activeHoveredEl) {\n this.activeHoveredEl.classList.remove('display-grid');\n this.activeHoveredEl = undefined;\n }\n }\n\n private cleanupDragGrid(): void {\n this.cleanupHoveredGroup();\n if (this.rootGridsterEl && !this.showGridLines()) {\n this.rootGridsterEl.classList.remove('display-grid');\n this.rootGridsterEl = undefined;\n }\n const container = this.scrollAreaRef()?.nativeElement;\n if (container && !this.showGridLines()) {\n container.querySelectorAll('gridster.display-grid').forEach((el) => {\n el.classList.remove('display-grid');\n });\n }\n }\n}\n","@if (isZoomActive()) {\n <!-- Khu vực cuộn chứa canvas stage thu phóng -->\n <div\n #scrollArea\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0 overflow-auto p-6 flex justify-center items-start\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\"\n (wheel)=\"handlerWheel($event)\"\n (dragover)=\"handlerDragOver($event)\"\n (dragleave)=\"handlerDragLeave($event)\"\n (drop)=\"handlerDrop($event)\">\n <div\n #canvasStage\n id=\"bi-canvas-stage\"\n class=\"libs-ui-grid-layout-stage relative flex flex-col transition-[zoom] duration-150 origin-top shrink-0 bg-white/80 border border-slate-200/80 rounded-2xl shadow-sm p-4\"\n [style.zoom]=\"currentZoom()\"\n [style.width.px]=\"stageWidth()\"\n [style.min-width.px]=\"stageWidth()\"\n [style.min-height.px]=\"stageMinHeight()\">\n <!-- Snapped Drop Ghost Preview -->\n @if (dropGhost(); as ghost) {\n <div\n class=\"pointer-events-none absolute z-30 flex flex-col items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-blue-500 bg-blue-500/15 p-1 shadow-sm transition-all duration-75 ease-out backdrop-blur-[0.5px] select-none\"\n [style.left.px]=\"ghost.pixelLeft\"\n [style.top.px]=\"ghost.pixelTop\"\n [style.width.px]=\"ghost.pixelWidth\"\n [style.height.px]=\"ghost.pixelHeight\">\n <div class=\"inline-flex max-w-[95%] items-center gap-1 truncate rounded-md bg-blue-600 px-2 py-0.5 text-[11px] font-semibold text-white shadow-xs\">\n @if (ghost.cardIconClass) {\n <i [class]=\"ghost.cardIconClass + ' text-xs'\"></i>\n } @else if (ghost.cardIconText) {\n <span class=\"text-[10px] font-bold\">{{ ghost.cardIconText }}</span>\n } @else {\n <span class=\"text-xs font-bold\">{{ ghost.isInsideGroup ? '↳' : '+' }}</span>\n }\n <span class=\"truncate\">{{ ghost.cardTitle }}</span>\n <span class=\"text-[9px] font-mono opacity-75\">({{ ghost.cols }}c)</span>\n </div>\n\n @if (ghost.pixelHeight >= 80) {\n <div class=\"mt-1 flex max-w-[95%] items-center gap-1.5 truncate rounded border border-blue-100 bg-white/95 px-2 py-0.5 text-[10px] font-medium text-blue-700 shadow-xs\">\n @if (ghost.isInsideGroup) {\n <span class=\"truncate font-bold text-blue-900\">↳ {{ ghost.groupTitle }}</span>\n <span class=\"text-blue-300\">•</span>\n }\n <span>Cột {{ ghost.col + 1 }}-{{ ghost.col + ghost.cols }}</span>\n </div>\n }\n </div>\n }\n <gridster class=\"h-full w-full\" [class.display-grid]=\"showGridLines()\" [options]=\"gridOptions()\">\n @for (item of children(); track item.id; let itemIndex = $index) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n [class.libs-ui-grid-layout-selected]=\"selectedNodeId() === item.id\"\n (click)=\"handlerSelectNode(item, $event)\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n @if (isEditMode()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item)\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">{{ 'i18n_container_block' | translate }}</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode() && !hiddenToolbar()) {\n @if (templateToolbar()) {\n <!-- Nơi dùng tự vẽ thanh công cụ: nhận khối + các hàm phát event qua context.\n\n 🔴 Khối bọc tự chặn `mousedown`/`click` nổi lên gridster. Thanh công cụ nằm trong\n vùng mang `dragHandleClass`; không chặn thì cú bấm bị hiểu là bắt đầu kéo và\n `delayStart: 160` nuốt luôn `click` — nút trong template ngoài bấm không ăn\n (đo 09/09/2026: bấm bằng `.click()` của DOM thì mở, bấm chuột thật thì không).\n Chặn ở ĐÂY để nơi dùng không phải biết bẫy này. -->\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n role=\"toolbar\"\n tabindex=\"0\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\"\n (mousedown)=\"handlerStopEvent($event)\"\n (keydown)=\"handlerStopEvent($event)\"\n (click)=\"handlerStopEvent($event)\">\n <ng-container\n *ngTemplateOutlet=\"templateToolbar()!; context: toolbarContexts()[itemIndex]\" />\n </div>\n } @else {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-dim-badge\">\n {{ item.rows }} hàng × {{ item.cols }} cột\n </span>\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-setting'\"\n [popover]=\"{ config: { content: 'Cấu hình thẻ', zIndex: 1300 } }\"\n (outClick)=\"handlerConfig($event, item)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px. -->\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n [hiddenToolbar]=\"hiddenToolbar()\"\n [templateToolbar]=\"templateToolbar()\"\n [selectedNodeId]=\"selectedNodeId()\"\n (outSelectNode)=\"outSelectNode.emit($event)\"\n (outConfigNode)=\"outConfigNode.emit($event)\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n }\n </div>\n </gridster-item>\n }\n </gridster>\n </div>\n </div>\n\n <!-- Thanh dock điều khiển thu phóng nổi ở góc dưới phải -->\n @if (showZoomDock()) {\n <div\n #zoomDock\n id=\"canvas-zoom-dock\"\n role=\"toolbar\"\n tabindex=\"0\"\n class=\"absolute bottom-4 right-6 z-30 flex items-center bg-white/95 backdrop-blur-md rounded-full shadow-lg border border-slate-300/80 p-1 space-x-1 select-none\"\n (mousedown)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation()\">\n <!-- Thu nhỏ (-) -->\n <button\n type=\"button\"\n class=\"w-7 h-7 flex items-center justify-center rounded-full text-slate-600 hover:text-slate-900 hover:bg-slate-100 disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer\"\n [disabled]=\"currentZoom() <= zoomMin()\"\n [title]=\"'i18n_zoom_out' | translate\"\n (click)=\"handlerZoomOut()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n\n <!-- Tỷ lệ % và menu preset -->\n <div class=\"relative\">\n <button\n type=\"button\"\n class=\"h-7 px-2 flex items-center gap-1 rounded-full text-xs font-semibold text-slate-700 hover:bg-slate-100 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_options' | translate\"\n (click)=\"handlerToggleMenu()\">\n <span>{{ zoomPercent() }}%</span>\n <svg class=\"w-3 h-3 text-slate-400 transition-transform duration-150\" [class.rotate-180]=\"isMenuOpen()\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"/></svg>\n </button>\n\n <!-- Menu dropdown các mốc thu phóng -->\n @if (isMenuOpen()) {\n <div class=\"absolute bottom-full mb-2 right-0 w-64 bg-white rounded-xl shadow-xl border border-slate-200 py-1.5 z-40 text-xs select-none\">\n <div class=\"px-3 py-1 text-[11px] font-semibold text-slate-400 uppercase tracking-wider\">\n {{ 'i18n_zoom_canvas_width' | translate: { width: stageWidth() } }}\n </div>\n <button\n type=\"button\"\n class=\"w-full px-3 py-2 text-left flex items-center justify-between hover:bg-slate-50 transition-colors cursor-pointer\"\n (click)=\"handlerFitScreen()\">\n <span class=\"flex items-center gap-2 text-slate-700 font-medium\">\n <svg class=\"w-3.5 h-3.5 text-slate-500\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>\n {{ 'i18n_zoom_fit_screen' | translate }}\n </span>\n <span class=\"text-[10px] bg-blue-50 text-blue-600 px-1.5 py-0.5 rounded font-medium\">{{ 'i18n_auto' | translate }}</span>\n </button>\n <div class=\"h-px bg-slate-100 my-1\"></div>\n @for (preset of zoomPresets; track preset.value) {\n <button\n type=\"button\"\n class=\"w-full px-3 py-1.5 text-left flex items-center justify-between hover:bg-slate-50 transition-colors cursor-pointer\"\n [class.text-blue-600]=\"isCurrentPreset(preset.value)\"\n [class.font-semibold]=\"isCurrentPreset(preset.value)\"\n [class.bg-blue-50]=\"isCurrentPreset(preset.value)\"\n (click)=\"handlerSelectPreset(preset.value)\">\n <span class=\"text-slate-700\" [class.text-blue-600]=\"isCurrentPreset(preset.value)\">\n {{ preset.label | translate }}\n </span>\n @if (isCurrentPreset(preset.value)) {\n <svg class=\"w-3.5 h-3.5 text-blue-600\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>\n }\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Phóng to (+) -->\n <button\n type=\"button\"\n class=\"w-7 h-7 flex items-center justify-center rounded-full text-slate-600 hover:text-slate-900 hover:bg-slate-100 disabled:opacity-30 disabled:hover:bg-transparent transition-colors cursor-pointer\"\n [disabled]=\"currentZoom() >= zoomMax()\"\n [title]=\"'i18n_zoom_in' | translate\"\n (click)=\"handlerZoomIn()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>\n </button>\n\n <!-- Phân cách -->\n <div class=\"h-4 w-px bg-slate-200\"></div>\n\n <!-- Nút Vừa màn hình nhanh -->\n <button\n type=\"button\"\n class=\"h-7 px-2.5 flex items-center gap-1 rounded-full text-xs text-slate-600 hover:text-slate-900 hover:bg-slate-100 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_fit_screen_tooltip' | translate\"\n (click)=\"handlerFitScreen()\">\n <svg class=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><polyline points=\"15 3 21 3 21 9\"/><polyline points=\"9 21 3 21 3 15\"/><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"/><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"/></svg>\n <span class=\"font-medium\">{{ 'i18n_zoom_fit_screen' | translate }}</span>\n </button>\n\n <!-- Nút Đặt lại 100% (chỉ hiện khi khác 100%) -->\n @if (zoomPercent() !== 100) {\n <button\n type=\"button\"\n class=\"h-7 px-2 flex items-center gap-1 rounded-full text-xs font-semibold text-blue-600 hover:bg-blue-50 transition-colors cursor-pointer\"\n [title]=\"'i18n_zoom_reset_tooltip' | translate: { width: stageWidth(), height: stageMinHeight() }\"\n (click)=\"handlerResetZoom()\">\n <svg class=\"w-3 h-3\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>\n <span>100%</span>\n </button>\n }\n </div>\n }\n} @else {\n <!-- 🔴 `relative` là BẮT BUỘC, CẤM bỏ.\n gridster đổi vị trí chuột thành ô lưới bằng `e.clientY + (el.scrollTop - el.offsetTop)` — công\n thức đó chỉ đúng khi `offsetParent` của <gridster> CHÍNH LÀ khối cuộn này. Thiếu `relative` thì\n `offsetParent` nhảy lên khối bao ngoài: `offsetTop` trả 16 trong khi lệch thật là 65 → gridster\n tính ô sai 49px, ô chờ đặt hiện lệch khỏi con trỏ nên kéo thả không đổi được vị trí, và kéo mép\n cũng tính sai điểm dừng. -->\n <div\n #scrollArea\n class=\"libs-ui-grid-layout-scroll-area relative h-full min-h-0 w-full min-w-0\"\n [class.overflow-y-auto]=\"!isNestedCanvas()\"\n (mousedown)=\"handlerMouseDownTrongLuoi($event)\"\n (dragover)=\"handlerDragOver($event)\"\n (dragleave)=\"handlerDragLeave($event)\"\n (drop)=\"handlerDrop($event)\">\n <!-- Snapped Drop Ghost Preview -->\n @if (dropGhost(); as ghost) {\n <div\n class=\"pointer-events-none absolute z-30 flex flex-col items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-blue-500 bg-blue-500/15 p-1 shadow-sm transition-all duration-75 ease-out backdrop-blur-[0.5px] select-none\"\n [style.left.px]=\"ghost.pixelLeft\"\n [style.top.px]=\"ghost.pixelTop\"\n [style.width.px]=\"ghost.pixelWidth\"\n [style.height.px]=\"ghost.pixelHeight\">\n <div class=\"inline-flex max-w-[95%] items-center gap-1 truncate rounded-md bg-blue-600 px-2 py-0.5 text-[11px] font-semibold text-white shadow-xs\">\n @if (ghost.cardIconClass) {\n <i [class]=\"ghost.cardIconClass + ' text-xs'\"></i>\n } @else if (ghost.cardIconText) {\n <span class=\"text-[10px] font-bold\">{{ ghost.cardIconText }}</span>\n } @else {\n <span class=\"text-xs font-bold\">{{ ghost.isInsideGroup ? '↳' : '+' }}</span>\n }\n <span class=\"truncate\">{{ ghost.cardTitle }}</span>\n <span class=\"text-[9px] font-mono opacity-75\">({{ ghost.cols }}c)</span>\n </div>\n\n @if (ghost.pixelHeight >= 80) {\n <div class=\"mt-1 flex max-w-[95%] items-center gap-1.5 truncate rounded border border-blue-100 bg-white/95 px-2 py-0.5 text-[10px] font-medium text-blue-700 shadow-xs\">\n @if (ghost.isInsideGroup) {\n <span class=\"truncate font-bold text-blue-900\">↳ {{ ghost.groupTitle }}</span>\n <span class=\"text-blue-300\">•</span>\n }\n <span>Cột {{ ghost.col + 1 }}-{{ ghost.col + ghost.cols }}</span>\n </div>\n }\n </div>\n }\n <gridster class=\"h-full w-full\" [class.display-grid]=\"showGridLines()\" [options]=\"gridOptions()\">\n @for (item of children(); track item.id; let itemIndex = $index) {\n <!-- 🔴 Chặn `mousedown` tại ĐÂY cho lưới lồng — CẤM bỏ và CẤM chuyển sang chỗ khác.\n `ignoreContentClass` một mình KHÔNG đủ: `delayStart: 160` làm MỖI lưới lên lịch\n `dragStart` bằng `setTimeout` ngay tại `mousedown`, còn `stopPropagation` mà lib gọi bên\n trong `dragStart` chạy sau 160ms nên quá muộn — lưới CHA đã kịp nhận (đo 28/08/2026: kéo\n dải khối con, chuỗi class duyệt lên ĐÚNG mà container vẫn nhảy 0,0 → 0,1).\n Gắn ở `gridster-item` là đúng biên: lưới con nghe trên chính phần tử này nên đã nhận xong,\n lưới cha ở ngoài bị chặn. -->\n <gridster-item\n [item]=\"item\"\n [class.libs-ui-grid-layout-selected]=\"selectedNodeId() === item.id\"\n (click)=\"handlerSelectNode(item, $event)\"\n (mousedown)=\"handlerBlockParentDrag($event)\">\n <!-- 🔴 Vỏ này mang `dragHandleClass` — CẤM bỏ.\n `ignoreContent: true` bắt gridster CHỈ cho kéo khi chỗ bấm nằm dưới một phần tử có\n `dragHandleClass`. Không có vỏ này thì component của nơi dùng (thư viện không kiểm soát\n được class của nó) sẽ không có tay cầm nào, và KHÔNG khối nào kéo được — đo 28/08/2026:\n kéo 320px, toạ độ khối giữ nguyên x=3,y=0.\n Tên class theo cấp: lưới trang và lưới lồng dùng hai tên KHÁC nhau, nếu không lưới cha\n cũng nhận ra tay cầm của khối con và nhấc luôn container. -->\n <!-- 🔴 Vỏ KHÔNG mang `dragHandleClass` — CẤM thêm lại.\n Kéo chỉ được phép bắt đầu từ DẢI XANH (người dùng chốt 28/08/2026: \"phải hover vào vùng\n màu xanh thì mới kéo thả được cho đồng nhất\"). Cho cả vỏ làm tay cầm thì bấm đâu cũng\n kéo, và khối con nằm trong container sẽ nhấc luôn container vì lưới cha duyệt lên gặp\n tay cầm của vỏ container trước.\n Vỏ khối con vẫn giữ class CHẶN để lưới cha dừng đúng ở biên. -->\n <div\n class=\"libs-ui-grid-layout-block-shell group relative h-full w-full min-w-0\"\n [class.libs-ui-grid-layout-block-parent-drag]=\"isNestedCanvas()\">\n <!-- Dải kéo: hiện khi rê chuột vào khối, ba chấm là dấu hiệu kéo quen thuộc.\n Người dùng cần một chỗ bám RÕ RÀNG thay vì đoán xem bấm đâu thì kéo được\n (chốt 28/08/2026, theo đúng dải đang dùng ở màn Customer 360 của mobio-web). -->\n @if (isEditMode()) {\n <!-- 🔴 Dải PHẢI mang tay cầm ĐÚNG CẤP của nó. Dải nhận chuột (`pointer-events: auto`),\n nên nếu không mang tay cầm thì `checkDragHandleClass` duyệt lên gặp tay cầm của\n container và nhấc container thay vì khối con (đo 28/08/2026: kéo dải khối con,\n container nhảy 0,0 → 0,1 còn khối con đứng im).\n 🔴 Dải CHỈ mang tay cầm, CẤM mang thêm class chặn: `checkDragHandleClass` xét hai\n class đó trên CÙNG một node nên để chung là kéo hỏng (đo 28/08/2026: bấm dải khối\n con kéo 140px, khối đứng im). Việc chặn lưới cha do VỎ KHỐI lo. -->\n <div\n class=\"libs-ui-grid-layout-drag-bar\"\n [class.libs-ui-grid-layout-drag-bar-child]=\"isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle]=\"!isNestedCanvas()\"\n [class.libs-ui-grid-layout-drag-handle-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-drag-bar-dots\">\n @for (dot of dragBarDots; track dot) {\n <span class=\"libs-ui-grid-layout-drag-bar-dot\"></span>\n }\n </span>\n </div>\n }\n\n <!-- Khung chứa component của nơi dùng.\n 🔴 PHẢI có khung thật (không phải `ng-container` trống): nó lo hộ nơi dùng phần lấp đầy\n ô và viền báo chế độ sửa. Không có khung thì mỗi component nội dung lại phải tự viết\n `:host { width/height: 100% }` + viền đứt — đó là việc của thư viện, không phải của\n người dùng (người dùng chốt 28/08/2026).\n Mỗi khối một ViewContainerRef riêng nên component nằm đúng ô của nó. -->\n <div\n class=\"libs-ui-grid-layout-content-frame\"\n [class.libs-ui-grid-layout-content-frame-edit]=\"isEditMode() && !isContainer(item)\"\n [class.libs-ui-grid-layout-content-frame-empty]=\"isContainer(item)\">\n <ng-container #itemHost />\n </div>\n\n <!-- Dấu hiệu CONTAINER: nhãn góc trên-phải + viền đứt bao ruột. Không có dấu hiệu thì\n người dùng không biết khối nào chứa được khối khác (chốt 28/08/2026, theo đúng cách\n màn Customer 360 của mobio-web đang làm). -->\n @if (isEditMode() && isContainer(item)) {\n <div class=\"libs-ui-grid-layout-container-label\">{{ 'i18n_container_block' | translate }}</div>\n <div class=\"libs-ui-grid-layout-container-border\"></div>\n }\n\n <!-- Thanh công cụ: hiện khi rê chuột vào khối.\n 🔴 Dùng `libs_ui-components-buttons-button` — CẤM tự dựng thẻ `<button>`.\n Component này đã có sẵn kiểu nút, cỡ nút và bong bóng chú thích theo đúng bộ giao diện\n của sản phẩm; tự dựng là mỗi nơi một kiểu và mất luôn tooltip. -->\n @if (isEditMode() && !hiddenToolbar()) {\n @if (templateToolbar()) {\n <!-- Nơi dùng tự vẽ thanh công cụ: nhận khối + các hàm phát event qua context.\n\n 🔴 Khối bọc tự chặn `mousedown`/`click` nổi lên gridster. Thanh công cụ nằm trong\n vùng mang `dragHandleClass`; không chặn thì cú bấm bị hiểu là bắt đầu kéo và\n `delayStart: 160` nuốt luôn `click` — nút trong template ngoài bấm không ăn\n (đo 09/09/2026: bấm bằng `.click()` của DOM thì mở, bấm chuột thật thì không).\n Chặn ở ĐÂY để nơi dùng không phải biết bẫy này. -->\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n role=\"toolbar\"\n tabindex=\"0\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\"\n (mousedown)=\"handlerStopEvent($event)\"\n (keydown)=\"handlerStopEvent($event)\"\n (click)=\"handlerStopEvent($event)\">\n <ng-container\n *ngTemplateOutlet=\"templateToolbar()!; context: toolbarContexts()[itemIndex]\" />\n </div>\n } @else {\n <div\n class=\"libs-ui-grid-layout-toolbar\"\n [class.libs-ui-grid-layout-toolbar-child]=\"isNestedCanvas()\">\n <span class=\"libs-ui-grid-layout-dim-badge\">\n {{ item.rows }} hàng × {{ item.cols }} cột\n </span>\n @if (canAddInside(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-add'\"\n [popover]=\"{ config: { content: 'Thêm khối vào trong', zIndex: 1300 } }\"\n (outClick)=\"handlerAddInside($event, item)\" />\n }\n @if (canToggleType(item)) {\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"isContainer(item) ? 'libs-ui-icon-split-cell' : 'libs-ui-icon-merge-cell'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Đưa về khối đơn' : 'Chuyển thành khối ghép', zIndex: 1300 } }\"\n (outClick)=\"handlerToggleType($event, item)\" />\n }\n <libs_ui-components-buttons-button\n [type]=\"'button-third'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-setting'\"\n [popover]=\"{ config: { content: 'Cấu hình thẻ', zIndex: 1300 } }\"\n (outClick)=\"handlerConfig($event, item)\" />\n <libs_ui-components-buttons-button\n [type]=\"'button-third-hover-danger'\"\n [iconOnlyType]=\"true\"\n [sizeButton]=\"'smaller'\"\n [classIconLeft]=\"'libs-ui-icon-remove'\"\n [popover]=\"{ config: { content: isContainer(item) ? 'Xoá cả khối ghép' : 'Xoá khối', zIndex: 1300 } }\"\n (outClick)=\"handlerRemove($event, item)\" />\n </div>\n }\n }\n\n @if (item.children && item.children.length > 0) {\n <!-- Khối có con → ruột nó lại là một mặt phẳng nữa. Đệ quy ở đây, nơi dùng không phải lo.\n Lề đặt ở ĐÂY (vỏ container), không đặt vào lưới con — lưới con giữ nguyên khe 2px. -->\n <libs_ui-services-grid_layout-canvas\n class=\"block h-full w-full\"\n [style.padding]=\"containerPadding()\"\n [node]=\"item\"\n [depth]=\"depth() + 1\"\n [hiddenToolbar]=\"hiddenToolbar()\"\n [templateToolbar]=\"templateToolbar()\"\n [selectedNodeId]=\"selectedNodeId()\"\n (outSelectNode)=\"outSelectNode.emit($event)\"\n (outConfigNode)=\"outConfigNode.emit($event)\"\n (outChange)=\"outChange.emit($event)\"\n (outRemoveNode)=\"outRemoveNode.emit($event)\"\n (outAddBlockInside)=\"outAddBlockInside.emit($event)\"\n (outToggleType)=\"outToggleType.emit($event)\" />\n }\n </div>\n </gridster-item>\n }\n </gridster>\n </div>\n}\n","import {\n T_gridLayout_dropGhost,\n T_gridLayout_externalDragPayload,\n T_gridLayout_node,\n} from './interfaces/grid-layout.interface';\nimport { calculateDropGhost } from './defines/collision.define';\n\n/** Lớp CSS bật ô li của một lưới trong lúc người dùng đang kéo khối vào. */\nconst LOP_HIEN_O_LI = 'display-grid';\n\n/**\n * Giữ trạng thái một lượt kéo khối từ palette bên ngoài vào mặt phẳng.\n *\n * Việc nó lo: bật ô li của lưới đang được kéo tới (lưới gốc, và lưới của container khi con trỏ đi\n * vào trong), tắt đúng lúc, và trả về ghost để nơi dùng vẽ khung xem trước.\n *\n * 🔴 Tự bật/tắt ô li bằng tay ở nơi dùng là chỗ rất dễ sót: kéo ra khỏi container rồi mà quên tắt\n * thì ô li của nó nằm lại trên màn, kéo sang lưới khác lại chồng thêm một lớp nữa.\n */\nexport class LibsUiGridLayoutDragController {\n private payload?: T_gridLayout_externalDragPayload;\n private hoveredElement?: HTMLElement;\n private rootGridsterElement?: HTMLElement;\n\n /** Payload của khối đang được kéo; `undefined` khi không có lượt kéo nào. */\n get ActivePayload(): T_gridLayout_externalDragPayload | undefined {\n return this.payload;\n }\n\n /** Gọi ở `dragstart` của thẻ trong palette. */\n onDragStart(payload: T_gridLayout_externalDragPayload): void {\n this.payload = payload;\n }\n\n /** Gọi ở `dragend` — dọn sạch mọi ô li đang bật. */\n onDragEnd(container?: HTMLElement): void {\n this.payload = undefined;\n this.cleanupAll(container);\n }\n\n /** Tắt ô li của container đang hover. */\n cleanupHoveredGroup(): void {\n if (!this.hoveredElement) {\n return;\n }\n this.hoveredElement.classList.remove(LOP_HIEN_O_LI);\n this.hoveredElement = undefined;\n }\n\n /** Tắt ô li của lưới gốc, và quét sạch lớp còn sót trong khung chứa. */\n cleanupRootGrid(container?: HTMLElement): void {\n if (this.rootGridsterElement) {\n this.rootGridsterElement.classList.remove(LOP_HIEN_O_LI);\n this.rootGridsterElement = undefined;\n }\n container?.querySelectorAll(`gridster.${LOP_HIEN_O_LI}`).forEach((el) => el.classList.remove(LOP_HIEN_O_LI));\n }\n\n /** Tắt toàn bộ ô li đang bật. */\n cleanupAll(container?: HTMLElement): void {\n this.cleanupHoveredGroup();\n this.cleanupRootGrid(container);\n }\n\n /**\n * Gọi ở `dragover` của khung chứa mặt phẳng. Trả ghost để nơi dùng vẽ khung xem trước, đồng thời\n * tự bật ô li của lưới đang được kéo tới.\n */\n onDragOver(\n event: DragEvent,\n container: HTMLElement | undefined,\n root: T_gridLayout_node | undefined,\n totalCols?: number\n ): T_gridLayout_dropGhost | undefined {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n if (!container || !root || !this.payload) {\n return undefined;\n }\n this.showRootGrid(container);\n\n const ghost = calculateDropGhost(event, container, root, this.payload, totalCols);\n\n if (!ghost?.isInsideGroup || !ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n\n return ghost;\n }\n\n if (this.hoveredElement !== ghost.hoveredGridster) {\n this.cleanupHoveredGroup();\n ghost.hoveredGridster.classList.add(LOP_HIEN_O_LI);\n this.hoveredElement = ghost.hoveredGridster;\n }\n\n return ghost;\n }\n\n /** Bật ô li của lưới CẤP TRANG trong suốt lượt kéo, tắt lưới cũ nếu khung chứa đã đổi. */\n private showRootGrid(container: HTMLElement): void {\n const rootGridster = (container.querySelector('gridster') as HTMLElement | null) ?? undefined;\n\n if (!rootGridster) {\n return;\n }\n\n if (this.rootGridsterElement && this.rootGridsterElement !== rootGridster) {\n this.rootGridsterElement.classList.remove(LOP_HIEN_O_LI);\n }\n rootGridster.classList.add(LOP_HIEN_O_LI);\n this.rootGridsterElement = rootGridster;\n }\n}\n","// Bề mặt CÔNG KHAI — chỉ những gì nơi dùng thật sự cần.\n//\n// `LibsUiGridLayoutTreeService` CỐ Ý không xuất: mọi thao tác trên cây đã có mặt trên\n// `LibsUiGridLayoutService` với chữ ký gọn hơn (không phải truyền `root` — thư viện đang giữ nó).\n// Cấu hình gridster cũng không xuất: nó đã được vá theo hàng chục lỗi đo trên sản phẩm thật, để nơi\n// dùng sửa lại là mở đường cho chính những lỗi đó quay về.\nexport * from './grid-layout.service';\nexport * from './canvas/grid-layout-canvas.component';\nexport * from './interfaces/grid-layout.interface';\nexport * from './defines/collision.define';\nexport * from './drag-controller';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;AAGA;;;;;AAKG;AACI,MAAM,oBAAoB,GAAG,OAAuB;;;;IAIzD,QAAQ,EAAE,QAAQ,CAAC,aAAa;;;;;;;;IAShC,WAAW,EAAE,WAAW,CAAC,IAAI;IAC7B,WAAW,EAAE,WAAW,CAAC,eAAe;;;;;;AAOxC,IAAA,SAAS,EAAE,IAAI;;AAEf,IAAA,cAAc,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;AACvE,IAAA,eAAe,EAAE,IAAI;AACrB,IAAA,IAAI,EAAE,IAAI;AACV,IAAA,iBAAiB,EAAE,IAAI;AAEvB,IAAA,SAAS,EAAE;AACT,QAAA,OAAO,EAAE,IAAI;;;AAGb,QAAA,UAAU,EAAE,CAAC;;;;AAIb,QAAA,kBAAkB,EAAE,uCAAuC;AAC3D,QAAA,aAAa,EAAE,IAAI;AACnB,QAAA,eAAe,EAAE,iCAAiC;AACnD,KAAA;AAED,IAAA,SAAS,EAAE;AACT,QAAA,OAAO,EAAE,IAAI;;AAEb,QAAA,OAAO,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE;AACxF,KAAA;AAED,IAAA,MAAM,EAAE,EAAE;AACV,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,iBAAiB,EAAE,EAAE;AACrB,IAAA,OAAO,EAAE,EAAE;AACX,IAAA,OAAO,EAAE,EAAE;AACX,IAAA,OAAO,EAAE,CAAC;;;;;AAMV,IAAA,OAAO,EAAE,IAAI;AACb,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,WAAW,EAAE,EAAE;AACf,IAAA,WAAW,EAAE,KAAK;;;;AAKlB,IAAA,aAAa,EAAE,IAAI;AAEnB,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,cAAc,EAAE,EAAE;AAClB,IAAA,eAAe,EAAE,CAAC;AAClB,IAAA,eAAe,EAAE,CAAC;AAClB,IAAA,WAAW,EAAE,CAAC;IACd,gBAAgB,EAAE,CAAC,CAAC;AACrB,CAAA,CAAC,CAAC;AAEH;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG,OAAuB;AAC3D,IAAA,GAAG,oBAAoB,EAAE;;;;AAKzB,IAAA,WAAW,EAAE,KAAK;;AAGlB,IAAA,MAAM,EAAE,CAAC;;;;AAIT,IAAA,WAAW,EAAE,KAAK;AAClB,IAAA,iBAAiB,EAAE,CAAC;;AAGpB,IAAA,cAAc,EAAE,EAAE;AAClB,IAAA,OAAO,EAAE,CAAC;AACV,IAAA,WAAW,EAAE,CAAC;AACd,IAAA,eAAe,EAAE,CAAC;AAClB,IAAA,eAAe,EAAE,CAAC;;;;AAKlB,IAAA,SAAS,EAAE;QACT,GAAG,oBAAoB,EAAE,CAAC,SAAS;AACnC,QAAA,eAAe,EAAE,uCAAuC;AACzD,KAAA;;;;AAKD,IAAA,eAAe,EAAE,KAAK;;;;AAKtB,IAAA,uBAAuB,EAAE,IAAI;AAC7B,IAAA,qBAAqB,EAAE,IAAI;AAC5B,CAAA,CAAC,CAAC;AAEH;;;AAGG;AACI,MAAM,aAAa,GAAG,OAA0B,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;;AClInH;;;AAGG;AACU,MAAA,YAAY,GAAG,CAC1B,QAAkC,EAClC,CAAS,EACT,CAAS,EACT,IAAY,EACZ,IAAY,EACZ,SAAkB,KACP;AACX,IAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE;QAC5B,IAAI,SAAS,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS,EAAE;YACvC,SAAS;SACV;QACD,MAAM,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAErE,QAAA,IAAI,QAAQ,IAAI,QAAQ,EAAE;AACxB,YAAA,OAAO,KAAK,CAAC;SACd;KACF;AAED,IAAA,OAAO,IAAI,CAAC;AACd,EAAE;AAEF;;;AAGG;AACU,MAAA,2BAA2B,GAAG,CACzC,QAAkC,EAClC,MAAc,EACd,MAAc,EACd,SAAiB,EACjB,SAAiB,EACjB,SAAS,GAAG,EAAE,KACkB;AAChC,IAAA,IAAI,aAAqE,CAAC;AAE1E,IAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE;QAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;AACvC,QAAA,MAAM,MAAM,GAAG,SAAS,GAAG,SAAS,IAAI,SAAS,CAAC;AAClD,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,YAAY,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAE1F,IAAI,CAAC,MAAM,EAAE;YACX,SAAS;SACV;AAED,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;AAC/H,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAE9C,QAAA,IAAI,KAAK,IAAI,KAAK,EAAE;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAEvE,IAAI,CAAC,aAAa,IAAI,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE;AAC/C,gBAAA,aAAa,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;aACxD;SACF;KACF;IAED,IAAI,aAAa,EAAE;AACjB,QAAA,OAAO,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC;KAC3D;AAED,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAEvC,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAC9C,EAAE;AAEF;;AAEG;AACH,MAAM,cAAc,GAAG,CAAC,CAAoB,EAAE,CAAoB,KAAa;AAC7E,IAAA,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAE/D,IAAA,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;QAClC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAEnB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;;AAIG;MACU,0BAA0B,GAAG,CACxC,QAAkC,EAClC,OAA0B,KAClB;AACR,IAAA,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;AAE5B,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,QAAA,MAAM,QAAQ,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAC1F,QAAA,MAAM,QAAQ,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1F,QAAA,IAAI,QAAQ,IAAI,QAAQ,EAAE;YACxB,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;SACnC;KACF;AAED,IAAA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,OAAO,EAAE;QACd,OAAO,GAAG,KAAK,CAAC;AAChB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACrC,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACzC,gBAAA,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;aACzD;SACF;KACF;AAED,IAAA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACzB,EAAE;AAEc,SAAA,gBAAgB,CAAI,aAA4B,EAAE,YAAiC,EAAA;IACjG,IAAI,aAAa,EAAE;AACjB,QAAA,OAAO,aAAa,CAAC;KACtB;IACD,IAAI,YAAY,EAAE;AAChB,QAAA,IAAI;YACF,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YAErD,IAAI,GAAG,EAAE;AACP,gBAAA,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;aAC7B;SACF;AAAC,QAAA,MAAM;AACN,YAAA,OAAO,SAAS,CAAC;SAClB;KACF;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,CAAC;AAOY,MAAA,gBAAgB,GAAG,CAC9B,QAAmB,EACnB,eAA4B,EAC5B,IAAuB,KACO;IAC9B,MAAM,YAAY,GAAG,eAAe,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;AAE/D,IAAA,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE;QACzB,MAAM,UAAU,IAAI,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,UAAU,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAuB,CAAC;AAEjH,QAAA,IAAI,UAAU,IAAI,UAAU,KAAK,YAAY,EAAE;YAC7C,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC,GAAG,EAAE,CAAC;AAC1G,YAAA,MAAM,GAAG,GAAG,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,YAAA,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE;AACpC,gBAAA,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;aACrE;SACF;KACF;AAED,IAAA,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE;QACzB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,eAAe,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC/F,IAAI,CAAC,MAAM,EAAE;YACX,SAAS;SACV;QACD,MAAM,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC,GAAG,EAAE,CAAC;QAC1G,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACtC,QAAA,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAChC,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE;AACpC,gBAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAG,MAAM,CAAC,aAAa,CAAC,UAAU,CAAwB,IAAK,MAAsB,EAAE,CAAC;aAChI;SACF;KACF;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,EAAE;AAEF;;AAEG;AACU,MAAA,kBAAkB,GAAG,CAChC,KAAgB,EAChB,eAA4B,EAC5B,IAAuB,EACvB,OAAyC,EACzC,SAAS,GAAG,EAAE,KACwB;IACtC,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,CAAC,eAAe,EAAE;AACvD,QAAA,OAAO,SAAS,CAAC;KAClB;AAED,IAAA,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;AACzC,IAAA,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;AACxC,IAAA,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;IACtC,MAAM,UAAU,GAAG,OAAkC,CAAC;AACtD,IAAA,IAAI,WAAW,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;UAC9C,OAAO,CAAC,IAAI;AACd,WAAG,OAAO,UAAU,CAAC,aAAa,CAAC,KAAK,QAAQ,GAAI,UAAU,CAAC,aAAa,CAAY,IAAI,SAAS,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACzH,IAAA,IAAI,WAAW,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;UAC9C,OAAO,CAAC,IAAI;WACX,OAAO,UAAU,CAAC,aAAa,CAAC,KAAK,QAAQ,GAAI,UAAU,CAAC,aAAa,CAAY,GAAG,CAAC,CAAC,CAAC;IAEhG,IAAI,OAAO,UAAU,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE;AACnD,QAAA,IAAI;YACF,MAAM,MAAM,GAAI,UAAU,CAAC,aAAa,CAA2D,CAAC,KAAK,CAAC,CAAC;YAC3G,IAAI,MAAM,EAAE;AACV,gBAAA,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;AAAE,oBAAA,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC;iBAAE;AACnE,gBAAA,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;AAAE,oBAAA,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC;iBAAE;aACpE;SACF;AAAC,QAAA,MAAM;;SAEP;KACF;IAED,MAAM,OAAO,GAAI,eAAe,CAAC,aAAa,CAAC,kBAAkB,CAAwB,IAAI,eAAe,CAAC;AAC7G,IAAA,MAAM,SAAS,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAElD,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,UAAU,CAAuB,CAAC;AAC7E,IAAA,MAAM,UAAU,GAAG,YAAY,IAAI,OAAO,CAAC;AAC3C,IAAA,MAAM,YAAY,GAAG,UAAU,CAAC,qBAAqB,EAAE,CAAC;IACxD,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,IAAI,UAAU,CAAC,WAAW,IAAI,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,KAAK,IAAI,aAAa,GAAG,CAAC;AACnD,UAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,KAAK,GAAG,aAAa,CAAC,CAAC;UAC9D,CAAC,CAAC;AAEN,IAAA,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,iBAAiB,KAAK,UAAU;AAC/D,UAAE,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;UACxD,EAAE,CAAC;IACP,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;AAElE,IAAA,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;AAC5D,IAAA,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC;IAE3D,IAAI,OAAO,EAAE;AACX,QAAA,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;AAC7C,QAAA,MAAM,iBAAiB,GAAG,aAAa,CAAC,qBAAqB,EAAE,CAAC;AAChE,QAAA,MAAM,cAAc,GAAG,CAAC,iBAAiB,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;AACxE,QAAA,MAAM,aAAa,GAAG,CAAC,iBAAiB,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC;QAErE,IAAI,SAAS,GAAG,WAAW,CAAC;QAC5B,IAAI,SAAS,GAAG,WAAW,CAAC;QAC5B,IAAI,OAAO,UAAU,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE;AACnD,YAAA,IAAI;gBACF,MAAM,YAAY,GAAI,UAAU,CAAC,aAAa,CAA2D,CAAC,IAAI,CAAC,CAAC;gBAChH,IAAI,YAAY,EAAE;AAChB,oBAAA,IAAI,OAAO,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE;AAAE,wBAAA,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC;qBAAE;AAC7E,oBAAA,IAAI,OAAO,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE;AAAE,wBAAA,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC;qBAAE;iBAC9E;aACF;AAAC,YAAA,MAAM;;aAEP;SACF;QACD,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAE3C,QAAA,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,KAAK,iBAAiB,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;QACxF,MAAM,OAAO,GAAG,CAAC,UAAU,GAAG,CAAC,IAAI,SAAS,CAAC;QAC7C,MAAM,OAAO,GAAG,EAAE,CAAC;AACnB,QAAA,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,iBAAiB,CAAC,IAAI,IAAI,IAAI,GAAG,aAAa,CAAC,UAAU,CAAC;AACxF,QAAA,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,iBAAiB,CAAC,GAAG,IAAI,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC;QACtF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,2BAA2B,CACtC,SAAS,CAAC,QAAQ,IAAI,EAAE,EACxB,MAAM,EACN,MAAM,EACN,SAAS,EACT,SAAS,EACT,SAAS,CACV,CAAC;QAEF,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG;AACb,YAAA,IAAI,EAAE,SAAS;AACf,YAAA,IAAI,EAAE,SAAS;AACf,YAAA,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC,GAAG,GAAG,OAAO;AAC9C,YAAA,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC,GAAG,GAAG,OAAO;AAC5C,YAAA,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC;AACjD,YAAA,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,GAAG,CAAC,CAAC;AAClD,YAAA,aAAa,EAAE,IAAI;YACnB,cAAc,EAAE,SAAS,CAAC,EAAE;AAC5B,YAAA,UAAU,EAAE,WAAW;YACvB,SAAS;YACT,aAAa;YACb,YAAY;AACZ,YAAA,eAAe,EAAE,aAA4B;SAC9C,CAAC;KACH;IAED,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,MAAM,aAAa,GAAG,aAAa,IAAI,UAAU,CAAC,WAAW,IAAI,IAAI,CAAC;AACtE,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,aAAa,GAAG,MAAM,IAAI,SAAS,CAAC,CAAC;AACnE,IAAA,MAAM,iBAAiB,GAAG,CAAC,YAAY,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC;AACtE,IAAA,MAAM,gBAAgB,GAAG,CAAC,YAAY,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC;IACnE,MAAM,IAAI,GAAG,WAAW,GAAG,iBAAiB,GAAG,UAAU,CAAC,UAAU,GAAG,MAAM,CAAC;IAC9E,MAAM,IAAI,GAAG,WAAW,GAAG,gBAAgB,GAAG,UAAU,CAAC,SAAS,GAAG,MAAM,CAAC;IAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AACpF,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;IAEpD,OAAO;QACL,GAAG;QACH,GAAG;AACH,QAAA,IAAI,EAAE,QAAQ;AACd,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,SAAS,EAAE,iBAAiB,GAAG,MAAM,GAAG,GAAG,GAAG,OAAO;AACrD,QAAA,QAAQ,EAAE,gBAAgB,GAAG,MAAM,GAAG,GAAG,GAAG,OAAO;AACnD,QAAA,UAAU,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM;AACvC,QAAA,WAAW,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM;AAC3C,QAAA,aAAa,EAAE,KAAK;QACpB,SAAS;QACT,aAAa;QACb,YAAY;QACZ,eAAe,EAAG,YAA4B,IAAI,SAAS;KAC5D,CAAC;AACJ,EAAE;AAGF;MACa,iBAAiB,GAAG,CAAC,IAAuB,EAAE,EAAU,KAAmC;AACtG,IAAA,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;AAClB,QAAA,OAAO,IAAI,CAAC;KACb;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAE3C,IAAI,KAAK,EAAE;AACT,YAAA,OAAO,KAAK,CAAC;SACd;KACF;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,EAAE;AAEF;MACa,mBAAmB,GAAG,CAAC,IAAuB,EAAE,EAAU,KAAmC;IACxG,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;AACvC,QAAA,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE;AACnB,YAAA,OAAO,IAAI,CAAC;SACb;QAED,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAE7C,IAAI,KAAK,EAAE;AACT,YAAA,OAAO,KAAK,CAAC;SACd;KACF;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,EAAE;AAEF;;;;;AAKG;AACU,MAAA,qBAAqB,GAAG,CACnC,IAAuB,EACvB,KAA6B,EAC7B,OAA6B,KAClB;AACX,IAAA,MAAM,SAAS,GAAsB;AACnC,QAAA,GAAG,OAAO;AACV,QAAA,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,IAAI,EAAE;QACxB,CAAC,EAAE,KAAK,CAAC,GAAG;QACZ,CAAC,EAAE,KAAK,CAAC,GAAG;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC;IAEF,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,cAAc,EAAE;QAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QAEjE,IAAI,CAAC,UAAU,EAAE;AACf,YAAA,OAAO,KAAK,CAAC;SACd;QACD,UAAU,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;AAChD,QAAA,0BAA0B,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAE3D,QAAA,OAAO,IAAI,CAAC;KACb;IAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;AACpC,IAAA,0BAA0B,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAErD,IAAA,OAAO,IAAI,CAAC;AACd,EAAE;AAGF;MACa,eAAe,GAAG,CAAC,IAAuB,KAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE;AAEtG;MACa,kBAAkB,GAAG,CAAC,IAAmC,EAAE,MAAc,KAAa;AACjG,IAAA,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE;AACnB,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;AAC7D,EAAE;AAEF;;;;;;AAMG;AACU,MAAA,iBAAiB,GAAG,CAAC,IAAmC,EAAE,IAAuB,KAC5F,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;AAE9D;AACa,MAAA,gBAAgB,GAAG,CAAC,IAAmC,EAAE,IAAuB,KAC3F,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;;AC3a5D;;;;;;;AAOG;MAEU,2BAA2B,CAAA;IACtC,QAAQ,CAAC,IAAuB,EAAE,EAAU,EAAA;AAC1C,QAAA,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;AAClB,YAAA,OAAO,IAAI,CAAC;SACb;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAEvC,IAAI,KAAK,EAAE;AACT,gBAAA,OAAO,KAAK,CAAC;aACd;SACF;AAED,QAAA,OAAO,SAAS,CAAC;KAClB;IAED,UAAU,CAAC,IAAuB,EAAE,EAAU,EAAA;QAC5C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;AACvC,YAAA,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE;AACnB,gBAAA,OAAO,IAAI,CAAC;aACb;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAEzC,IAAI,KAAK,EAAE;AACT,gBAAA,OAAO,KAAK,CAAC;aACd;SACF;AAED,QAAA,OAAO,SAAS,CAAC;KAClB;AAED;;;;AAIG;AACH,IAAA,QAAQ,CAAC,IAAuB,EAAE,QAAgB,EAAE,IAA0B,EAAA;QAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE7C,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;;;;AAIxC,QAAA,MAAM,IAAI,GAAsB,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;AAE/G,QAAA,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;AAG3B,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;AAEG;AACH,IAAA,mBAAmB,CACjB,IAAuB,EACvB,QAA4B,EAC5B,IAA0B,EAC1B,SAAS,GAAG,CAAC,EACb,SAAS,GAAG,CAAC,EAAA;AAEb,QAAA,MAAM,YAAY,GAAG,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;QAErE,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,OAAO,SAAS,CAAC;SAClB;QAED,YAAY,CAAC,QAAQ,GAAG,YAAY,CAAC,QAAQ,IAAI,EAAE,CAAC;AACpD,QAAA,MAAM,IAAI,GAAsB;AAC9B,YAAA,GAAG,IAAI;AACP,YAAA,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE;AACrB,YAAA,CAAC,EAAE,SAAS;AACZ,YAAA,CAAC,EAAE,SAAS;SACb,CAAC;AAEF,QAAA,0BAA0B,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAExD,QAAA,OAAO,IAAI,CAAC;KACb;;IAGD,UAAU,CAAC,IAAuB,EAAE,EAAU,EAAA;AAC5C,QAAA,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;AAClB,YAAA,OAAO,KAAK,CAAC;SACd;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAEzC,QAAA,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE;AACrB,YAAA,OAAO,KAAK,CAAC;SACd;QAED,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAEnE,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;;;AAMG;AACH,IAAA,WAAW,CAAC,IAAuB,EAAE,EAAU,EAAE,QAAgB,EAAA;QAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAErC,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE;AAC7C,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AAE7F,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;AAIG;IACH,QAAQ,CAAC,IAAuB,EAAE,EAAU,EAAA;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAErC,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE;AAC/C,YAAA,OAAO,KAAK,CAAC;SACd;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAEzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;YACvC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;SAChE;AAED,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;AAEnB,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;;;;;AAQG;IACH,0BAA0B,CAAC,IAAuB,EAAE,QAAgB,EAAA;QAClE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;KAC5C;AAED;;;;;;AAMG;IACH,OAAO,CAAC,IAAuB,EAAE,QAAgB,EAAA;AAC/C,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;KAClC;IAEO,WAAW,CAAC,IAAuB,EAAE,QAAgB,EAAA;AAC3D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;AAE/B,QAAA,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;YACrB,OAAO;SACR;AAED,QAAA,MAAM,cAAc,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,YAAY,GAAG,CAAC,CAAC;AAErB,QAAA,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE;AACjC,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAE5C,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,KAAK,GAAG,QAAQ,EAAE;gBAC/C,UAAU,IAAI,YAAY,CAAC;gBAC3B,QAAQ,GAAG,CAAC,CAAC;gBACb,YAAY,GAAG,CAAC,CAAC;aAClB;AAED,YAAA,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC;AAClB,YAAA,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC;AACpB,YAAA,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,QAAQ,IAAI,KAAK,CAAC;YAClB,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAEjD,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE;AACpC,gBAAA,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;aAClC;SACF;KACF;AAEO,IAAA,WAAW,CAAC,IAAuB,EAAE,cAAsB,EAAE,QAAgB,EAAA;AACnF,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;AAE/B,QAAA,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;AACrB,YAAA,OAAO,CAAC,CAAC;SACV;QAED,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,MAAM,MAAM,GAA6B,EAAE,CAAC;AAE5C,QAAA,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE;AAC5B,YAAA,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;AAEtD,YAAA,IAAI,WAAW,IAAI,cAAc,IAAI,QAAQ,EAAE;gBAC7C,UAAU,IAAI,CAAC,CAAC;gBAEhB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,EAAE,EAAE;oBACvC,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;AAC/D,oBAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACnB;gBAED,SAAS;aACV;YAED,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,GAAG,CAAC,GAAG,cAAc,EAAE,QAAQ,CAAC,CAAC;AACnG,YAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACpB;AAED,QAAA,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC;AAEvB,QAAA,OAAO,UAAU,CAAC;KACnB;AAEO,IAAA,WAAW,CAAC,QAAkC,EAAA;AACpD,QAAA,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;KAChF;wGA7OU,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAA3B,2BAA2B,EAAA,CAAA,CAAA;;4FAA3B,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBADvC,UAAU;;;ACEX;;;;;;;;;;AAUG;MAEU,uBAAuB,CAAA;;;;AAIjB,IAAA,WAAW,GAAG,IAAI,2BAA2B,EAAE,CAAC;;AAEhD,IAAA,YAAY,GAAG,IAAI,GAAG,EAAwB,CAAC;AAChE;;;;;AAKG;AACc,IAAA,qBAAqB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEnE,IAAA,WAAA,GAAA;;;;AAIE,QAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;KACpD;AAEO,IAAA,MAAM,CAAuB;AACpB,IAAA,aAAa,GAAG,IAAI,GAAG,EAAiC,CAAC;AAEzD,IAAA,QAAQ,GAAG,MAAM,CAAgC,SAAS,CAAC,CAAC;AAC5D,IAAA,QAAQ,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;;AAElC,IAAA,OAAO,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;AAC5B,IAAA,SAAS,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;AAE/C;;;;;;AAMG;AACM,IAAA,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;AAClC,IAAA,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;;AAExC,IAAA,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;AACpC,IAAA,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;AAE5C;AAC8F;IACtF,iBAAiB,GAAA;AACvB,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,iBAAiB,IAAI,CAAC,CAAC;KAC5C;AAED;AAC6E;IACrE,gBAAgB,GAAA;AACtB,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,gBAAgB,IAAI,EAAE,CAAC;KAC5C;;AAGD,IAAA,IAAI,CAAC,MAA2B,EAAA;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;AACf,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;;;;;AAKrB,QAAA,IAAI,CAAC,WAAW,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACnF,QAAA,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;;;;;AAKtC,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;AAE9C,QAAA,IAAI,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,UAAU,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;AAC5D,YAAA,IAAI;gBACF,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBACtD,IAAI,KAAK,EAAE;AACT,oBAAA,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,oBAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;AAClC,oBAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC;AAClC,oBAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE;wBACpD,WAAW,GAAG,MAAM,CAAC;qBACtB;iBACF;aACF;AAAC,YAAA,MAAM;;aAEP;SACF;AACD,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAEhC,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KACnC;AAED,IAAA,WAAW,CAAC,KAAc,EAAA;AACxB,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;;;AAIzB,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KACnC;AAED;;;;;AAKG;AACH,IAAA,eAAe,CAAC,KAAc,EAAA;AAC5B,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,OAAO;SACR;AAED,QAAA,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AAEtD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;;;;;;AAOD,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;;;QAG/B,IAAI,CAAC,OAAO,EAAE,CAAC;KAChB;AAED;;;;;AAKG;IACK,oBAAoB,CAAC,KAAa,EAAE,kBAA+B,EAAA;AACzE,QAAA,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,GAAG,oBAAoB,EAAE,GAAG,sBAAsB,EAAE,CAAC;AAC7E,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3B,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,gDAAmC;AACjE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,UAAU,KAAK,MAAM,CAAC,YAAY,IAAI,KAAK,CAAC,CAAC;QAEhE,OAAO;AACL,YAAA,GAAG,IAAI;AACP,YAAA,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;AACvB,YAAA,IAAI,MAAM,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;YAChG,IAAI,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;YAChF,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;YACnF,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC;;YAE7F,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;YAChF,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC;YAC1F,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;YACxG,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC;YAC/F,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACjH,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC;YAChF,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,GAAG,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;YAC5F,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,GAAG,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;;;;;YAM5F,SAAS,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE;YAClD,SAAS,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE;;AAGlD,YAAA,eAAe,EAAE,UAAU;;;;;;YAM3B,IAAI,UAAU,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAE1G,YAAA,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC;AAE3C,YAAA,kBAAkB,EAAE,CAAC,IAAkB,KAAI;;;;;;gBAMzC,IAAI,UAAU,EAAE;AACd,oBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;iBAC5B;AAED,gBAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClC,kBAAkB,IAAI,CAAC;aACxB;SACF,CAAC;KACH;AAED;;;;;;;;;;;;;AAaG;IACK,sBAAsB,CAAC,IAAoB,EAAE,KAAa,EAAA;QAChE,IAAI,IAAI,CAAC,MAAM,EAAE,qBAAqB,KAAK,KAAK,EAAE;AAChD,YAAA,OAAO,EAAE,CAAC;SACX;AACD,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC;AAC9C,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC;QAElC,OAAO;AACL,YAAA,kBAAkB,EAAE,CAAC,IAAI,EAAE,aAAa,KAAI;AAC1C,gBAAA,aAAa,GAAG,IAAI,EAAE,aAAa,CAAC,CAAC;AACrC,gBAAA,MAAM,EAAE,GAAI,aAAkD,EAAE,EAAE,CAAC;gBAEnE,EAAE,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,qBAAqB,CAAC,MAAqB,CAAC,CAAC,CAAC;aACzG;YACD,IAAI,KAAK,GAAG,CAAC;AACX,kBAAE,EAAE,YAAY,EAAE,CAAC,QAAoC,KAAK,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE;kBACtG,EAAE,CAAC;SACR,CAAC;KACH;;AAGO,IAAA,qBAAqB,CAAC,MAAmB,EAAA;QAC/C,MAAM,WAAW,GAAG,MAA6F,CAAC;QAElH,WAAW,CAAC,kBAAkB,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC;KAC1D;AAED;;;;;AAKG;IACK,kBAAkB,CACxB,QAAoC,EACpC,GAAoD,EAAA;AAEpD,QAAA,GAAG,GAAG,QAAQ,CAAC,CAAC;QAChB,MAAM,QAAQ,GAAG,QAAoG,CAAC;AACtH,QAAA,MAAM,EAAE,GAAG,QAAQ,EAAE,EAAE,CAAC;QAExB,IAAI,CAAC,EAAE,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;YAChD,OAAO;SACR;AACA,QAAA,EAAkD,CAAC,kBAAkB,GAAG,QAAQ,CAAC;AAElF,QAAA,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,MAAM,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC;AAE7E,QAAA,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACpB,QAAA,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KACzC;AAED;;;;;;AAMG;AACK,IAAA,UAAU,CAAC,IAAuB,EAAE,KAAa,EAAE,IAAsB,EAAA;AAC/E,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3B,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEjD,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAExC,OAAO;SACR;;;AAID,QAAA,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,MAAM,CAAC,kBAAkB,IAAI,IAAI,CAAC,CAAC;QAE9E,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;;;;AAKD,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;AAE9C,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,aAAa,KAAI;YAC3D,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;AAGlC,YAAA,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE;gBAChE,OAAO;aACR;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;YAEhD,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AACvC,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;KACrC;AAED;AAC0C;AAClC,IAAA,UAAU,CAAC,MAAc,EAAA;;;QAG/B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;AAC7C,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE3C,IAAI,CAAC,GAAG,EAAE;YACR,OAAO;SACR;QAED,GAAG,CAAC,OAAO,EAAE,CAAC;AACd,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACnC;IAEO,OAAO,GAAA;QACb,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE;YAC5C,GAAG,CAAC,WAAW,EAAE,CAAC;SACnB;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE;YAC7C,GAAG,CAAC,OAAO,EAAE,CAAC;SACf;AAED,QAAA,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,qBAAqB,EAAE;YACjD,QAAQ,CAAC,UAAU,EAAE,CAAC;SACvB;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;AAC1B,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;AAC3B,QAAA,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;AACnC,QAAA,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;KACzB;;;;;AAOD;;;;;;;;;;;;AAYG;AACH,IAAA,OAAO,CAAC,KAAgC,EAAA;QACtC,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE5C,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAElC,OAAO;SACR;AAED,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;SAC9C;AAED,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KACnC;;AAGD;;;;;;AAMG;AACK,IAAA,aAAa,CAAC,IAAuB,EAAA;AAC3C,QAAA,MAAM,IAAI,GAAsB,EAAE,GAAG,IAAI,EAAE,CAAC;;QAG5C,OAAO,IAAI,CAAC,kBAAkB,CAAC;QAE/B,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;QAEzC,OAAO;AACL,YAAA,GAAG,IAAI;AACP,YAAA,IAAI,IAAI,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;AACxD,YAAA,IAAI,QAAQ,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;SACtF,CAAC;KACH;AAEO,IAAA,gBAAgB,CAAC,IAAuB,EAAA;AAC9C,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;AAC1B,YAAA,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;SACpB;QAED,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;KAC1F;AAED;;;;;;;;;;AAUG;AACK,IAAA,mBAAmB,CAAC,IAAuB,EAAA;AACjD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAC3B,QAAA,MAAM,UAAU,GAAG,MAAM,EAAE,IAAI,KAAkC,MAAA,yCAAK,MAAM,EAAE,YAAY,IAAI,KAAK,CAAC,CAAC;QAErG,IAAI,CAAC,UAAU,EAAE;YACf,OAAO;SACR;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;AACd,QAAA,MAAM,IAAI,GAAG,CAAC,IAAuB,KAAU;YAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;AACvC,gBAAA,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE;oBAClC,KAAK,IAAI,CAAC,CAAC;AACX,oBAAA,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;iBAC1B;gBAED,IAAI,CAAC,KAAK,CAAC,CAAC;aACb;AACH,SAAC,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,CAAC;KAEZ;;AAGO,IAAA,eAAe,CAAC,IAAkB,EAAA;AACxC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,QAAA,MAAM,IAAI,GAAG,CAAC,IAAuB,KAAU;YAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE;AACvC,gBAAA,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;gBACrD,IAAI,CAAC,KAAK,CAAC,CAAC;aACb;AACH,SAAC,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,CAAC;;;QAIX,MAAM,IAAI,GAAG,IAAoC,CAAC;AAElD,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE;YAEhC,OAAO;SACR;AAED,QAAA,IAAI,CAAC,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC;KAChC;;;;;AAOD;;;;;;AAMG;IACH,QAAQ,CAAC,IAA0B,EAAE,QAAiB,EAAA;AACpD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC;QAE5F,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;SAChB;AAED,QAAA,OAAO,KAAK,CAAC;KACd;AAED;;AAEG;IACH,wBAAwB,CACtB,IAA0B,EAC1B,SAAS,GAAG,CAAC,EACb,SAAS,GAAG,CAAC,EACb,QAAiB,EAAA;AAEjB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI;cACd,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC;cAC3F,SAAS,CAAC;QAEd,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;SAChB;AAED,QAAA,OAAO,KAAK,CAAC;KACd;AAEgB,IAAA,iBAAiB,GAAG,MAAM,CAAsB,SAAS,CAAC,CAAC;;AAG5E,IAAA,cAAc,CAAC,OAAgB,EAAA;AAC7B,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KACrC;;IAGD,cAAc,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;KACjC;;IAGD,gBAAgB,GAAA;AACd,QAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;KACvC;;AAGD,IAAA,WAAW,CAAC,EAAU,EAAA;AACpB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;QAElE,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,OAAO,EAAE,CAAC;SAChB;AAED,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;;;AAMG;AACH,IAAA,IAAI,YAAY,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,oBAAoB,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;KAClE;AAED;;;;AAIG;IACH,WAAW,CAAC,EAAU,EAAE,IAAsC,EAAA;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAEhC,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;AAC3B,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;AACtB,YAAA,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE;AAC1C,gBAAA,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;aACrD;SACF;AAED,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;AAC3B,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;SACvB;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;AAEf,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;;;;AAKG;IACH,cAAc,CAAC,EAAU,EAAE,aAA0C,EAAA;AACnE,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC7B,QAAA,MAAM,IAAI,GAAG,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;AAE5D,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE;AAClB,YAAA,OAAO,SAAS,CAAC;SAClB;QACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC7C,QAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1D,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;AACjC,QAAA,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;QAErB,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE;YAC3C,OAAO,GAAG,CAAC,CAAC;YACZ,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;SAC9B;QAED,OAAO,IAAI,CAAC,QAAQ,CAClB;AACE,YAAA,CAAC,EAAE,OAAO;AACV,YAAA,CAAC,EAAE,OAAO;YACV,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;AACf,YAAA,IAAI,EAAE,aAAa,GAAG,aAAa,CAAC,UAAU,CAAC,GAAG,UAAU;YAC5D,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;AAC5C,SAAA,EACD,QAAQ,GAAG,MAAM,EAAE,EAAE,GAAG,SAAS,CAClC,CAAC;KACH;;AAGD,IAAA,WAAW,CAAC,EAAU,EAAA;AACpB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC;QAEtF,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,OAAO,EAAE,CAAC;SAChB;AAED,QAAA,OAAO,IAAI,CAAC;KACb;;AAGD,IAAA,QAAQ,CAAC,EAAU,EAAA;AACjB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;QAEhE,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,OAAO,EAAE,CAAC;SAChB;AAED,QAAA,OAAO,IAAI,CAAC;KACb;;IAGD,OAAO,GAAA;AACL,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,EAAE,CAAC;KAChB;AAED;;;;;;;AAOG;IACH,YAAY,GAAA;AACV,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAE7B,QAAA,OAAO,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;KACpD;;AAGD,IAAA,SAAS,CAAC,EAAU,EAAA;AAClB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAE7B,QAAA,OAAO,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;KAC/D;;AAGD,IAAA,eAAe,CAAC,EAAU,EAAA;AACxB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAE7B,QAAA,OAAO,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;KACjE;AAED;;;;;AAKG;IACH,OAAO,CAAC,KAAa,EAAE,UAAmB,EAAA;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAC5E,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE5B,MAAM,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;AACzD,QAAA,IAAI,UAAU,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;AACrD,YAAA,IAAI;gBACF,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;aACnD;AAAC,YAAA,MAAM;;aAEP;SACF;AAED,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;KACnC;;IAGD,MAAM,CAAC,IAAa,EAAE,UAAmB,EAAA;QACvC,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;AAChD,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;KAChD;;IAGD,OAAO,CAAC,IAAa,EAAE,UAAmB,EAAA;QACxC,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI,CAAC;AAChD,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;KAChD;;AAGD,IAAA,SAAS,CAAC,UAAmB,EAAA;AAC3B,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;KAC/B;AAED;;;;;;;;AAQG;IACH,WAAW,CAAC,cAAsB,EAAE,UAAmB,EAAE,OAAO,GAAG,EAAE,EAAE,UAAmB,EAAA;QACxF,MAAM,WAAW,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,IAAI,IAAI,CAAC;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC;AACjB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,GAAG,OAAO,IAAI,WAAW,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAC/G,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAChC,QAAA,OAAO,KAAK,CAAC;KACd;;IAGD,gBAAgB,GAAA;QACd,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KACzC;AAED;;;;;;AAMG;AACH,IAAA,IAAI,gBAAgB,GAAA;QAClB,OAAO;AACL,YAAA,iBAAiB,EAAE,MAAM,IAAI,CAAC,iBAAiB,EAAE;AACjD,YAAA,gBAAgB,EAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE;AAC/C,YAAA,aAAa,EAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE;AAC5C,YAAA,IAAI,EAAE,MAAM,IAAI,CAAC,SAAS,EAAE;AAC5B,YAAA,OAAO,EAAE,CAAC,CAAS,EAAE,GAAY,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC;AAC1D,YAAA,MAAM,EAAE,CAAC,IAAa,EAAE,GAAY,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;AAC/D,YAAA,OAAO,EAAE,CAAC,IAAa,EAAE,GAAY,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;YACjE,SAAS,EAAE,CAAC,GAAY,KAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAChD,WAAW,EAAE,CAAC,EAAU,EAAE,EAAW,EAAE,GAAY,EAAE,GAAY,KAAK,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC;AACxG,YAAA,eAAe,EAAE,CAAC,KAAa,EAAE,EAAe,KAAK,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,EAAE,CAAC;AACzF,YAAA,UAAU,EAAE,CAAC,IAAuB,EAAE,KAAa,EAAE,IAAsB,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC;YAClH,UAAU,EAAE,CAAC,MAAc,KAAK,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;SACxD,CAAC;KACH;AAEO,IAAA,WAAW,CAAC,GAA0B,EAAE,IAAuB,EAAE,KAAa,EAAA;QACpF,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAChC,QAAA,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3B,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC5C,QAAA,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;KAC9B;wGAzxBU,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAvB,uBAAuB,EAAA,CAAA,CAAA;;4FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBADnC,UAAU;;;ACaX;;;;;AAKG;MASU,+BAA+B,CAAA;AAC1C;;;;;AAKG;IACM,IAAI,GAAG,KAAK,EAAqB,CAAC;;AAElC,IAAA,KAAK,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;AAElC;;;;;;AAMG;AACM,IAAA,aAAa,GAAG,KAAK,CAA+B,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;AAE9G;;;;;;;AAOG;AACM,IAAA,eAAe,GAAG,KAAK,CAAuD,SAAS,CAAC,CAAC;AAElG;;;;;AAKG;IACM,SAAS,GAAG,MAAM,EAA4B,CAAC;AACxD;;;AAGG;IACM,aAAa,GAAG,MAAM,EAA4B,CAAC;AAC5D;;;AAGG;IACM,iBAAiB,GAAG,MAAM,EAAyB,CAAC;;IAEpD,aAAa,GAAG,MAAM,EAA4B,CAAC;;AAGnD,IAAA,UAAU,GAAG,KAAK,CAA+B,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;;AAGlG,IAAA,IAAI,GAAG,KAAK,CAAqB,SAAS,CAAC,CAAC;;AAG5C,IAAA,OAAO,GAAG,KAAK,CAAS,GAAG,CAAC,CAAC;;AAG7B,IAAA,OAAO,GAAG,KAAK,CAAS,GAAG,CAAC,CAAC;;AAG7B,IAAA,QAAQ,GAAG,KAAK,CAAS,IAAI,CAAC,CAAC;;AAG/B,IAAA,UAAU,GAAG,KAAK,CAAS,IAAI,CAAC,CAAC;;AAGjC,IAAA,cAAc,GAAG,KAAK,CAAS,GAAG,CAAC,CAAC;;AAGpC,IAAA,UAAU,GAAG,KAAK,CAAqB,oBAAoB,CAAC,CAAC;;AAG7D,IAAA,YAAY,GAAG,KAAK,CAA+B,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;;AAGlG,IAAA,aAAa,GAAG,KAAK,CAA+B,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;;IAGnG,aAAa,GAAG,MAAM,EAAU,CAAC;;AAGjC,IAAA,kBAAkB,GAAG,KAAK,CAA+B,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;;AAGxG,IAAA,aAAa,GAAG,KAAK,CAA+B,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;;AAGrG,IAAA,cAAc,GAAG,KAAK,CAA4B,SAAS,CAAC,CAAC;;IAG7D,WAAW,GAAG,MAAM,EAA0B,CAAC;;IAG/C,aAAa,GAAG,MAAM,EAAqB,CAAC;;IAG5C,aAAa,GAAG,MAAM,EAA4B,CAAC;AAE3C,IAAA,WAAW,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC;AAC3C,IAAA,aAAa,GAAG,SAAS,CAA0B,YAAY,CAAC,CAAC;AACjE,IAAA,WAAW,GAAG,SAAS,CAA0B,UAAU,CAAC,CAAC;;IAE7D,SAAS,GAAG,YAAY,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;;AAG/D,IAAA,SAAS,GAAG,MAAM,CAAqC,SAAS,CAAC,CAAC;AAE7E,IAAA,eAAe,CAAe;AAC9B,IAAA,cAAc,CAAe;;AAGlB,IAAA,UAAU,GAAG,MAAM,CAAU,KAAK,CAAC,CAAC;;AAGpC,IAAA,WAAW,GAAmC;AAC/D,QAAA,EAAE,KAAK,EAAE,2BAA2B,EAAE,KAAK,EAAE,GAAG,EAAE;AAClD,QAAA,EAAE,KAAK,EAAE,+BAA+B,EAAE,KAAK,EAAE,IAAI,EAAE;AACvD,QAAA,EAAE,KAAK,EAAE,+BAA+B,EAAE,KAAK,EAAE,IAAI,EAAE;AACvD,QAAA,EAAE,KAAK,EAAE,+BAA+B,EAAE,KAAK,EAAE,IAAI,EAAE;AACvD,QAAA,EAAE,KAAK,EAAE,2BAA2B,EAAE,KAAK,EAAE,GAAG,EAAE;AAClD,QAAA,EAAE,KAAK,EAAE,gCAAgC,EAAE,KAAK,EAAE,CAAC,EAAE;AACrD,QAAA,EAAE,KAAK,EAAE,+BAA+B,EAAE,KAAK,EAAE,GAAG,EAAE;AACtD,QAAA,EAAE,KAAK,EAAE,8BAA8B,EAAE,KAAK,EAAE,IAAI,EAAE;KACvD,CAAC;;AAGiB,IAAA,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEnC,IAAA,OAAO,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;;AAGxC,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAK;QAC9C,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC;AACpG,KAAC,CAAC,CAAC;AAEgB,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAClD,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;AAEtF;;;;;;;;;;AAUG;AACgB,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AAC7C,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;AAEvB,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;AACpB,YAAA,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;SACvC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;AAChD,KAAC,CAAC,CAAC;AAEgB,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAEhF;;;;;AAKG;AACgB,IAAA,eAAe,GAAG,QAAQ,CAAqC,MAChF,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM;AAC7B,QAAA,SAAS,EAAE,IAAI;AACf,QAAA,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACnC,QAAA,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;AACrC,QAAA,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;AACvC,QAAA,MAAM,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QACxH,SAAS,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QACzC,UAAU,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;KAC5C,CAAC,CAAC,CACJ,CAAC;AAEiB,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;;AAGlD,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAEzG;;;;;;AAMG;AACgB,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAG,EAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAA,EAAA,CAAI,CAAC,CAAC;;AAG3F,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;AAEvD,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;;;AAG7C,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;AAEvB,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;AAC9H,KAAC,CAAC,CAAC;AAEH,IAAA,WAAA,GAAA;;;QAGE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;AAC/B,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAE9B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,KAAI;AACxB,gBAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAEtB,IAAI,CAAC,IAAI,EAAE;oBACT,OAAO;iBACR;;AAGD,gBAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE;oBACpC,OAAO;iBACR;AAED,gBAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AACzE,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;;QAGH,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE;AAChE,gBAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;aAC7D;AACH,SAAC,CAAC,CAAC;KACJ;IAED,eAAe,GAAA;AACb,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;YACjD,OAAO;SACR;AAED,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAC9B,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,QAAA,IAAI,GAAG,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;AAC9C,YAAA,IAAI;gBACF,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;aAC/C;AAAC,YAAA,MAAM;;aAEP;SACF;QAED,IAAI,CAAC,QAAQ,EAAE;YACb,UAAU,CAAC,MAAK;gBACd,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,aAAa,CAAC;AACrD,gBAAA,IAAI,QAAQ,IAAI,QAAQ,CAAC,WAAW,GAAG,CAAC,IAAI,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE;oBACzF,IAAI,CAAC,gBAAgB,EAAE,CAAC;iBACzB;aACF,EAAE,EAAE,CAAC,CAAC;SACR;KACF;IAED,WAAW,GAAA;QACT,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YAClC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACnD;KACF;;AAGD,IAAA,IAAI,eAAe,GAAA;QACjB,OAAO;YACL,SAAS,EAAE,MAAM,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE;AACrD,YAAA,MAAM,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE;AAClC,YAAA,OAAO,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE;AACpC,YAAA,SAAS,EAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE;AACxC,YAAA,WAAW,EAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE;AAC1C,YAAA,OAAO,EAAE,CAAC,GAAW,KAAI;AACvB,gBAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;gBAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;aACpB;;;YAGD,UAAU,EAAE,MAA+B,IAAI,CAAC,aAAa,EAAE,EAAE,aAAa;SAC/E,CAAC;KACH;IAES,aAAa,GAAA;AACrB,QAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,EAAE,CAAC;KACpB;IAES,cAAc,GAAA;AACtB,QAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,WAAW,EAAE,CAAC;KACpB;IAES,gBAAgB,GAAA;AACxB,QAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC,WAAW,EAAE,CAAC;KACpB;IAES,gBAAgB,GAAA;AACxB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,aAAa,CAAC;QACrD,MAAM,cAAc,GAAG,QAAQ,EAAE,WAAW,KAAK,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,UAAU,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;QACjH,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACpG,IAAI,CAAC,WAAW,EAAE,CAAC;KACpB;IAES,iBAAiB,GAAA;AACzB,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;KACzC;AAES,IAAA,mBAAmB,CAAC,KAAa,EAAA;AACzC,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC3B,QAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,WAAW,EAAE,CAAC;KACpB;AAES,IAAA,eAAe,CAAC,KAAa,EAAA;AACrC,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;KACpD;IAEO,WAAW,GAAA;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;AAChC,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7B,QAAA,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE;AACvB,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACpB;KACF;AAES,IAAA,YAAY,CAAC,KAAiB,EAAA;AACtC,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;YACxB,OAAO;SACR;QAED,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;YAClC,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,YAAA,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;gBACpB,IAAI,CAAC,aAAa,EAAE,CAAC;aACtB;AAAM,iBAAA,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC3B,IAAI,CAAC,cAAc,EAAE,CAAC;aACvB;SACF;KACF;AAGS,IAAA,sBAAsB,CAAC,KAAoB,EAAA;AACnD,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;YACxB,OAAO;SACR;QAED,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;AAClC,YAAA,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE;gBAC1C,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,EAAE,CAAC;aACtB;AAAM,iBAAA,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE;gBACjD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,cAAc,EAAE,CAAC;aACvB;AAAM,iBAAA,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE;gBAC5B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,gBAAgB,EAAE,CAAC;aACzB;SACF;KACF;AAGS,IAAA,oBAAoB,CAAC,KAAiB,EAAA;AAC9C,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACtB,OAAO;SACR;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC;AACjD,QAAA,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE;AACpD,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAC5B;KACF;IAES,gBAAgB,CAAC,MAAc,EAAE,IAAuB,EAAA;QAChE,OAAO,IAAI,CAAC,EAAE,CAAC;KAChB;AAED;;;AAGG;AACH;;;;;AAKG;AACH;;;;AAIG;IACO,aAAa,CAAC,KAAY,EAAE,IAAuB,EAAA;QAC3D,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KACtG;IAES,gBAAgB,CAAC,KAAY,EAAE,IAAuB,EAAA;QAC9D,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;KAC1B;IAES,iBAAiB,CAAC,KAAY,EAAE,IAAuB,EAAA;QAC/D,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;KAC3B;AAED;;;;;AAKG;AACO,IAAA,gBAAgB,CAAC,KAAY,EAAA;QACrC,KAAK,CAAC,eAAe,EAAE,CAAC;KACzB;;AAGO,IAAA,aAAa,CAAC,IAAuB,EAAA;AAC3C,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAC1B,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,IAAI;AACJ,YAAA,OAAO,EAAE,CAAC,IAA0B,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC9E,SAAA,CAAC,CAAC;KACJ;;AAGO,IAAA,cAAc,CAAC,IAAuB,EAAA;AAC5C,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YACtB,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,IAAI;;AAEJ,YAAA,OAAO,EAAE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7G,SAAA,CAAC,CAAC;KACJ;;AAGS,IAAA,WAAW,CAAC,IAAuB,EAAA;QAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;KACzC;;AAGS,IAAA,YAAY,CAAC,IAAuB,EAAA;AAC5C,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;KAC1E;;AAGS,IAAA,aAAa,CAAC,IAAuB,EAAA;AAC7C,QAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;AAC1B,YAAA,OAAO,IAAI,CAAC;SACb;QAED,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;KAChD;AAES,IAAA,sBAAsB,CAAC,KAAY,EAAA;AAC3C,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE;YAC1B,OAAO;SACR;QAED,KAAK,CAAC,eAAe,EAAE,CAAC;KACzB;AAES,IAAA,yBAAyB,CAAC,KAAY,EAAA;AAC9C,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;YACtB,OAAO;SACR;QAED,KAAK,CAAC,eAAe,EAAE,CAAC;KACzB;IAES,iBAAiB,CAAC,IAAuB,EAAE,KAAkB,EAAA;QACrE,IAAI,KAAK,EAAE;AACT,YAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;AAC3C,YAAA,IAAI,MAAM,CAAC,OAAO,CAAC,8BAA8B,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAC9E,OAAO;aACR;SACF;QACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjC,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC/B;IAES,aAAa,CAAC,KAAY,EAAE,IAAuB,EAAA;QAC3D,KAAK,CAAC,eAAe,EAAE,CAAC;AACxB,QAAA,MAAM,WAAW,GAA6B;YAC5C,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,IAAI;AACJ,YAAA,OAAO,EAAE,MAAM,IAAI;SACpB,CAAC;AACF,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;KACtC;AAES,IAAA,eAAe,CAAC,KAAgB,EAAA;AACxC,QAAA,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;YAClD,OAAO;SACR;QACD,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,YAAA,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC;SACxC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,aAAa,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;AACjC,QAAA,MAAM,OAAO,GAAG,gBAAgB,CAC9B,IAAI,CAAC,OAAO,CAAC,cAAc,EAAkD,EAC7E,KAAK,CAAC,YAAY,CACnB,CAAC;QAEF,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;YACnC,OAAO;SACR;QAED,MAAM,YAAY,GAAG,SAAS,CAAC,aAAa,CAAC,UAAU,CAAuB,CAAC;QAC/E,IAAI,YAAY,EAAE;YAChB,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE;AACpD,gBAAA,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;aAC5C;AACD,YAAA,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;SACpC;AAED,QAAA,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAE7F,IAAI,KAAK,EAAE,aAAa,IAAI,KAAK,CAAC,eAAe,EAAE;YACjD,IAAI,IAAI,CAAC,eAAe,KAAK,KAAK,CAAC,eAAe,EAAE;gBAClD,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,KAAK,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AACpD,gBAAA,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;aAC9C;SACF;aAAM;YACL,IAAI,CAAC,mBAAmB,EAAE,CAAC;SAC5B;AAED,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KAC3B;AAES,IAAA,gBAAgB,CAAC,KAAgB,EAAA;AACzC,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;YACpB,OAAO;SACR;AACD,QAAA,IAAI,KAAK,CAAC,aAAa,EAAE;YACvB,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,aAAa,CAAC;YACtD,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAqB,CAAC,EAAE;gBAChE,OAAO;aACR;SACF;AACD,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;KACxB;AAES,IAAA,WAAW,CAAC,KAAgB,EAAA;AACpC,QAAA,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;YAClD,OAAO;SACR;QACD,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;AAC/B,QAAA,MAAM,OAAO,GAAG,gBAAgB,CAC9B,IAAI,CAAC,OAAO,CAAC,cAAc,EAAkD,EAC7E,KAAK,CAAC,YAAY,CACnB,CAAC;AAEF,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;AACvB,QAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;AAEhC,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE;YACtB,OAAO;SACR;AAED,QAAA,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,cAAc,GAAG,SAAS,CAAC;AAC9E,QAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAEzC,QAAA,IAAI,SAA+B,CAAC;QACpC,MAAM,UAAU,GAAG,OAAkC,CAAC;QACtD,IAAI,OAAO,UAAU,CAAC,aAAa,CAAC,KAAK,UAAU,EAAE;YACnD,MAAM,QAAQ,GAAI,UAAU,CAAC,aAAa,CAA2D,CAAC,QAAQ,CAAC,CAAC;YAChH,SAAS,GAAG,QAAQ,IAAI;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;AAChB,gBAAA,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC;aAChG,CAAC;SACH;aAAM;AACL,YAAA,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC;AAC9G,YAAA,SAAS,GAAG;gBACV,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;AAChB,gBAAA,IAAI,EAAE,WAAW;aAClB,CAAC;SACH;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,CACrD,SAAS,EACT,KAAK,CAAC,GAAG,EACT,KAAK,CAAC,GAAG,EACT,cAAc,CACf,CAAC;QAEF,IAAI,SAAS,EAAE;YACb,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AACtC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;AACpB,gBAAA,IAAI,EAAE,SAAS;AACf,gBAAA,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;AAChB,gBAAA,QAAQ,EAAE,KAAK;gBACf,OAAO;AACR,aAAA,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,IAAI,EAAE;AACR,gBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBAClB,IAAI;oBACJ,MAAM,EAAE,SAAS,CAAC,EAAE;AACrB,iBAAA,CAAC,CAAC;aACJ;SACF;KACF;IAEO,mBAAmB,GAAA;AACzB,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACtD,YAAA,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;SAClC;KACF;IAEO,eAAe,GAAA;QACrB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;YAChD,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACrD,YAAA,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;SACjC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,aAAa,CAAC;QACtD,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;YACtC,SAAS,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,KAAI;AACjE,gBAAA,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACtC,aAAC,CAAC,CAAC;SACJ;KACF;wGAxoBU,+BAA+B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA/B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,+BAA+B,EAqGD,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qCAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,kBAAA,EAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,aAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,aAAA,EAAA,eAAA,EAAA,IAAA,EAAA,YAAA,EAAA,aAAA,EAAA,eAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,WAAA,EAAA,aAAA,EAAA,aAAA,EAAA,eAAA,EAAA,aAAA,EAAA,eAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,kBAAA,EAAA,gCAAA,EAAA,gBAAA,EAAA,8BAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,aAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,iBAAiB,EAII,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,eAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,YAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,aAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,UAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,SAAA,EAAA,CAAA,UAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EAAA,gBAAgB,6CC9JhF,0nrCAqhBA,EAAA,MAAA,EAAA,CAAA,oqLAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDhea,+BAA+B,EAAA,QAAA,EAAA,qCAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,MAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,eAAA,EAAA,oBAAA,EAAA,eAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,EAAA,eAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,YAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,aAAA,EAAA,eAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EALhC,cAAc,EAAE,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,sCAAsC,EAAE,QAAA,EAAA,mCAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,cAAA,EAAA,YAAA,EAAA,OAAA,EAAA,SAAA,EAAA,WAAA,EAAA,WAAA,EAAA,cAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,4BAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,yBAAA,EAAA,+BAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,mCAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,iBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,mJAAE,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAKxF,+BAA+B,EAAA,UAAA,EAAA,CAAA;kBAR3C,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,qCAAqC,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA,CAAC,cAAc,EAAE,sCAAsC,EAAE,gBAAgB,EAAE,eAAe,CAAC,EAGnF,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,0nrCAAA,EAAA,MAAA,EAAA,CAAA,oqLAAA,CAAA,EAAA,CAAA;wDAgWrC,sBAAsB,EAAA,CAAA;sBAD/B,YAAY;uBAAC,kBAAkB,EAAE,CAAC,QAAQ,CAAC,CAAA;gBAqBlC,oBAAoB,EAAA,CAAA;sBAD7B,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC,CAAA;;;AE/Z5C;AACA,MAAM,aAAa,GAAG,cAAc,CAAC;AAErC;;;;;;;;AAQG;MACU,8BAA8B,CAAA;AACjC,IAAA,OAAO,CAAoC;AAC3C,IAAA,cAAc,CAAe;AAC7B,IAAA,mBAAmB,CAAe;;AAG1C,IAAA,IAAI,aAAa,GAAA;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;KACrB;;AAGD,IAAA,WAAW,CAAC,OAAyC,EAAA;AACnD,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;KACxB;;AAGD,IAAA,SAAS,CAAC,SAAuB,EAAA;AAC/B,QAAA,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;AACzB,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;KAC5B;;IAGD,mBAAmB,GAAA;AACjB,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACxB,OAAO;SACR;QACD,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AACpD,QAAA,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;KACjC;;AAGD,IAAA,eAAe,CAAC,SAAuB,EAAA;AACrC,QAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE;YAC5B,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AACzD,YAAA,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;SACtC;QACD,SAAS,EAAE,gBAAgB,CAAC,CAAY,SAAA,EAAA,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;KAC9G;;AAGD,IAAA,UAAU,CAAC,SAAuB,EAAA;QAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;AAC3B,QAAA,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;KACjC;AAED;;;AAGG;AACH,IAAA,UAAU,CACR,KAAgB,EAChB,SAAkC,EAClC,IAAmC,EACnC,SAAkB,EAAA;QAElB,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,QAAA,IAAI,KAAK,CAAC,YAAY,EAAE;AACtB,YAAA,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC;SACxC;QACD,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACxC,YAAA,OAAO,SAAS,CAAC;SAClB;AACD,QAAA,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAE7B,QAAA,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElF,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE;YACnD,IAAI,CAAC,mBAAmB,EAAE,CAAC;AAE3B,YAAA,OAAO,KAAK,CAAC;SACd;QAED,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC,eAAe,EAAE;YACjD,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AACnD,YAAA,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,eAAe,CAAC;SAC7C;AAED,QAAA,OAAO,KAAK,CAAC;KACd;;AAGO,IAAA,YAAY,CAAC,SAAsB,EAAA;QACzC,MAAM,YAAY,GAAI,SAAS,CAAC,aAAa,CAAC,UAAU,CAAwB,IAAI,SAAS,CAAC;QAE9F,IAAI,CAAC,YAAY,EAAE;YACjB,OAAO;SACR;QAED,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,mBAAmB,KAAK,YAAY,EAAE;YACzE,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;SAC1D;AACD,QAAA,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,mBAAmB,GAAG,YAAY,CAAC;KACzC;AACF;;AClHD;AACA;AACA;AACA;AACA;AACA;;ACLA;;AAEG;;;;"}
|