open-grid 1.0.1 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"OpenGrid-v528T7RJ.js","sources":["../src/core/EventEmitter.ts","../src/core/DataLayer.ts","../src/core/VirtualScroll.ts","../src/core/ColumnLayout.ts","../src/core/FilterPanel.ts","../src/core/MathUtils.ts","../src/core/OGDecimal.ts","../src/core/FormulaEngine.ts","../src/core/MaskingEngine.ts","../src/core/renderers/CellRenderer.ts","../src/core/GridRenderer.ts","../src/core/RowManager.ts","../src/core/editors/DateEditor.ts","../src/core/editors/SelectEditor.ts","../src/core/editors/CellEditor.ts","../src/core/CellTypeRegistry.ts","../src/core/CellEditManager.ts","../src/core/FilterSelect.ts","../src/core/Pagination.ts","../src/core/DragVisuals.ts","../src/core/RowDragDrop.ts","../src/core/MergeEngine.ts","../src/core/ContextMenu.ts","../src/core/WorksheetManager.ts","../src/core/ExportManager.ts","../src/core/FooterManager.ts","../src/core/KeyboardManager.ts","../src/core/FindBarManager.ts","../src/core/GroupEngine.ts","../src/core/TreeEngine.ts","../src/core/GroupTreeManager.ts","../src/core/SortFilterManager.ts","../src/core/CellEventHandler.ts","../src/core/TriggerManager.ts","../src/core/CrossGridMapper.ts","../src/core/CrossGridRegistry.ts","../src/core/OverrideKernel.ts","../src/core/OpenGrid.ts"],"sourcesContent":["type Handler = (...args: any[]) => any;\n\ninterface ListenerEntry {\n handler: Handler;\n once: boolean;\n}\n\nexport class EventEmitter {\n private listeners: Map<string, ListenerEntry[]> = new Map();\n\n on(event: string, handler: Handler): this {\n const list = this.listeners.get(event) ?? [];\n list.push({ handler, once: false });\n this.listeners.set(event, list);\n return this;\n }\n\n once(event: string, handler: Handler): this {\n const list = this.listeners.get(event) ?? [];\n list.push({ handler, once: true });\n this.listeners.set(event, list);\n return this;\n }\n\n off(event: string, handler?: Handler): this {\n if (!handler) {\n this.listeners.delete(event);\n return this;\n }\n const list = this.listeners.get(event);\n if (list) {\n const filtered = list.filter(e => e.handler !== handler);\n if (filtered.length === 0) this.listeners.delete(event);\n else this.listeners.set(event, filtered);\n }\n return this;\n }\n\n emit(event: string, ...args: any[]): boolean {\n const list = this.listeners.get(event);\n if (!list || list.length === 0) return false;\n\n const remaining: ListenerEntry[] = [];\n for (const entry of list) {\n entry.handler(...args);\n if (!entry.once) remaining.push(entry);\n }\n\n if (remaining.length !== list.length) {\n if (remaining.length === 0) this.listeners.delete(event);\n else this.listeners.set(event, remaining);\n }\n return true;\n }\n\n removeAllListeners(event?: string): this {\n if (event) this.listeners.delete(event);\n else this.listeners.clear();\n return this;\n }\n\n listenerCount(event: string): number {\n return this.listeners.get(event)?.length ?? 0;\n }\n}\n","import type { SortItem, FilterItem } from './types.js';\n\ntype RowState = 'added' | 'edited' | 'removed' | 'none';\n\ninterface RowMeta {\n state: RowState;\n original?: any;\n rowId: string;\n}\n\nlet _rowIdSeq = 0;\nfunction nextRowId(): string {\n return `og-r-${++_rowIdSeq}`;\n}\n\nexport class DataLayer<T extends Record<string, any> = any> {\n private _data: T[] = [];\n private _original: T[] = [];\n private _meta: Map<string, RowMeta> = new Map();\n private _idField: string;\n\n // 정렬/필터 적용 후 표시되는 인덱스 목록\n private _displayIndexes: number[] = [];\n\n // rowId → _data 인덱스 역매핑\n private _idMap: Map<string, number> = new Map();\n\n // F3: 찾기 바 전용 크로스-필드 OR 필터\n private _findQuery: string = '';\n private _findFields: string[] = [];\n\n // Phase 2: strategy 슬롯 resolver(미설정 시 default 폴백 = 현행 로직).\n private _getStrategy: <F extends Function>(slot: string, fallback: F) => F =\n (_slot, fallback) => fallback;\n\n constructor(idField: string = '_ogRowId') {\n this._idField = idField;\n }\n\n /** Phase 2: OpenGrid 가 OverrideKernel.getStrategy 를 주입(슬롯 sortComparator/filterPredicate 도달용). */\n setStrategyResolver(resolver: <F extends Function>(slot: string, fallback: F) => F): void {\n this._getStrategy = resolver;\n }\n\n // ─── 데이터 설정 ──────────────────────────────────────\n setData(data: T[]): void {\n this._data = data.map(row => {\n const id = nextRowId();\n const item = { ...row, [this._idField]: id };\n this._meta.set(id, { state: 'none', rowId: id });\n return item as T;\n });\n this._original = this._data.map(r => ({ ...r }));\n this._rebuildIdMap();\n this._displayIndexes = this._data.map((_, i) => i);\n }\n\n getData(): T[] {\n return this._displayIndexes.map(i => this._data[i]!);\n }\n\n getOriginalData(): T[] {\n return [...this._original];\n }\n\n getAllData(): T[] {\n return [...this._data];\n }\n\n clearData(): void {\n this._data = [];\n this._original = [];\n this._meta.clear();\n this._idMap.clear();\n this._displayIndexes = [];\n }\n\n get rowCount(): number {\n return this._displayIndexes.length;\n }\n\n get totalRowCount(): number {\n return this._data.length;\n }\n\n // ─── 행 CRUD ──────────────────────────────────────────\n addRow(item: Partial<T>, position: 'first' | 'last' | number = 'last'): void {\n const id = nextRowId();\n const row = { ...item, [this._idField]: id } as T;\n this._meta.set(id, { state: 'added', rowId: id });\n\n if (position === 'last') {\n const idx = this._data.push(row) - 1;\n this._idMap.set(id, idx);\n this._displayIndexes.push(idx);\n } else if (position === 'first') {\n this._data.unshift(row);\n this._rebuildIdMap();\n this._displayIndexes.unshift(0);\n } else {\n const dispPos = Math.min(position, this._displayIndexes.length);\n const dataIdx = dispPos < this._displayIndexes.length\n ? this._displayIndexes[dispPos]!\n : this._data.length;\n this._data.splice(dataIdx, 0, row);\n this._rebuildIdMap();\n this._displayIndexes = this._data.map((_, i) => i);\n }\n }\n\n removeRow(rowIndex: number): T | undefined {\n const dataIdx = this._displayIndexes[rowIndex];\n if (dataIdx === undefined) return undefined;\n\n const row = this._data[dataIdx]!;\n const id = row[this._idField] as string;\n const meta = this._meta.get(id);\n\n if (meta?.state === 'added') {\n // 새로 추가된 행은 완전 삭제\n this._data.splice(dataIdx, 1);\n this._meta.delete(id);\n } else {\n // 기존 행은 soft delete\n this._meta.set(id, { ...meta!, state: 'removed' });\n }\n\n this._rebuildIdMap();\n this._displayIndexes = this._data\n .map((r, i) => ({ r, i }))\n .filter(({ r }) => this._meta.get(r[this._idField] as string)?.state !== 'removed')\n .map(({ i }) => i);\n\n return row;\n }\n\n moveRow(fromDisplayIdx: number, toDisplayIdx: number): void {\n const fromDataIdx = this._displayIndexes[fromDisplayIdx];\n const toDataIdx = this._displayIndexes[toDisplayIdx];\n if (fromDataIdx === undefined || toDataIdx === undefined) return;\n\n // _data 배열에서 실제 이동\n const [row] = this._data.splice(fromDataIdx, 1);\n const insertAt = fromDataIdx < toDataIdx ? toDataIdx - 1 : toDataIdx;\n this._data.splice(insertAt, 0, row!);\n\n this._rebuildIdMap();\n this._displayIndexes = this._data\n .map((r, i) => ({ r, i }))\n .filter(({ r }) => this._meta.get(r[this._idField] as string)?.state !== 'removed')\n .map(({ i }) => i);\n }\n\n updateCell(rowIndex: number, field: string, value: any): boolean {\n const dataIdx = this._displayIndexes[rowIndex];\n if (dataIdx === undefined) return false;\n\n const row = this._data[dataIdx]!;\n const id = row[this._idField] as string;\n const meta = this._meta.get(id);\n\n // original 백업\n if (meta?.state === 'none') {\n this._meta.set(id, {\n ...meta,\n state: 'edited',\n original: { ...this._original[dataIdx] }\n });\n }\n\n (this._data[dataIdx] as any)[field] = value;\n return true;\n }\n\n getRowByIndex(rowIndex: number): T | undefined {\n const dataIdx = this._displayIndexes[rowIndex];\n return dataIdx !== undefined ? this._data[dataIdx] : undefined;\n }\n\n getCellValue(rowIndex: number, field: string): any {\n return this.getRowByIndex(rowIndex)?.[field];\n }\n\n // ─── 변경 추적 ────────────────────────────────────────\n /** 수정된 행만 반환 (추가/삭제 제외) */\n getEditedRows(): T[] {\n return this._data.filter(r =>\n this._meta.get(r[this._idField] as string)?.state === 'edited'\n );\n }\n\n /** 수정된 행만 반환 (하위 호환용 — 신규 코드는 getEditedRows() 사용) */\n getChangedRows(): T[] { return this.getEditedRows(); }\n\n getAddedRows(): T[] {\n return this._data.filter(r =>\n this._meta.get(r[this._idField] as string)?.state === 'added'\n );\n }\n\n getRemovedRows(): T[] {\n return this._data.filter(r =>\n this._meta.get(r[this._idField] as string)?.state === 'removed'\n );\n }\n\n /**\n * 추가/수정/삭제 모든 변경사항을 한 번에 반환.\n * edited 행에는 _changedFields 배열도 포함.\n */\n getChanges(): { added: T[]; edited: T[]; removed: T[] } {\n const added: T[] = [];\n const edited: T[] = [];\n const removed: T[] = [];\n\n for (const row of this._data) {\n const id = row[this._idField] as string;\n const meta = this._meta.get(id);\n const state = meta?.state ?? 'none';\n if (state === 'added') { added.push({ ...row }); }\n else if (state === 'removed') { removed.push({ ...row }); }\n else if (state === 'edited') {\n const orig = meta!.original ?? {};\n const changedFields = Object.keys(row).filter(\n k => k !== this._idField && row[k] !== orig[k]\n );\n edited.push({ ...row, _changedFields: changedFields } as any);\n }\n }\n return { added, edited, removed };\n }\n\n /**\n * 수정된 컬럼 정보 반환 — 각 edited 행에 대해 { row, fields, diff } 반환.\n * diff: { field, oldValue, newValue }[]\n */\n getChangedColumns(): Array<{ row: T; fields: string[]; diff: Array<{ field: string; oldValue: any; newValue: any }> }> {\n return this._data\n .filter(r => this._meta.get(r[this._idField] as string)?.state === 'edited')\n .map(row => {\n const orig = this._meta.get(row[this._idField] as string)?.original ?? {};\n const diff: Array<{ field: string; oldValue: any; newValue: any }> = [];\n for (const key of Object.keys(row)) {\n if (key === this._idField) continue;\n if (row[key] !== orig[key]) {\n diff.push({ field: key, oldValue: orig[key], newValue: row[key] });\n }\n }\n return { row: { ...row }, fields: diff.map(d => d.field), diff };\n });\n }\n\n /** rowIndex 행의 원본(수정 전) 데이터 반환. 추가된 행은 undefined. */\n getOriginalRow(rowIndex: number): T | undefined {\n const dataIdx = this._displayIndexes[rowIndex];\n if (dataIdx === undefined) return undefined;\n const row = this._data[dataIdx]!;\n const meta = this._meta.get(row[this._idField] as string);\n if (!meta || meta.state === 'added') return undefined;\n if (meta.state === 'edited' && meta.original) return { ...meta.original } as T;\n return { ...this._original[dataIdx] } as T;\n }\n\n getRowsWithState(stateField: string): T[] {\n return this._data.map(r => {\n const state = this._meta.get(r[this._idField] as string)?.state ?? 'none';\n return { ...r, [stateField]: state };\n });\n }\n\n getRowState(rowIndex: number): RowState {\n const row = this.getRowByIndex(rowIndex);\n if (!row) return 'none';\n return this._meta.get(row[this._idField] as string)?.state ?? 'none';\n }\n\n // ─── 정렬 ─────────────────────────────────────────────\n applySort(sortList: SortItem[]): void {\n const notRemoved = (i: number) =>\n this._meta.get((this._data[i] as any)?.[this._idField])?.state !== 'removed';\n\n if (sortList.length === 0) {\n this._displayIndexes = this._data.map((_, i) => i).filter(notRemoved);\n return;\n }\n\n // Schwartzian transform: 키를 미리 추출하여 sort comparator 비용 절감\n const keyed = this._displayIndexes\n .filter(notRemoved)\n .map(idx => {\n const row = this._data[idx]!;\n return {\n idx,\n keys: sortList.map(s => row[s.field]),\n };\n });\n\n // Phase 2 슬롯 #1: 단일키 비교자. default = 현행 인라인(number는 av-bv, 그 외 String, null 우선).\n // 멀티키 루프가 단일키 비교를 래핑. dir 부호 적용은 호출자(루프) 책임이므로 슬롯은 비교만.\n // ⚠️ 핫패스(행쌍당) — 슬롯 fn 예외는 호출자 책임(try/catch 비감쌈).\n const cmpStrategy = this._getStrategy(\n 'sortComparator',\n (a: any, b: any, _field: string, _dir: 'asc' | 'desc'): number => {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n const sa = String(a), sb = String(b);\n return sa < sb ? -1 : sa > sb ? 1 : 0;\n },\n );\n\n keyed.sort((a, b) => {\n for (let si = 0; si < sortList.length; si++) {\n const dir = sortList[si]!.dir;\n const field = sortList[si]!.field;\n const av = a.keys[si];\n const bv = b.keys[si];\n const cmp = cmpStrategy(av, bv, field, dir);\n if (cmp !== 0) return dir === 'asc' ? cmp : -cmp;\n }\n return 0;\n });\n\n this._displayIndexes = keyed.map(k => k.idx);\n }\n\n // ─── 필터 ─────────────────────────────────────────────\n applyFilter(filters: Record<string, FilterItem[]>): void {\n const fields = Object.keys(filters);\n\n // Phase 2 슬롯 #2: 필터 술어. default = 모듈 matchFilter(operator switch).\n // ⚠️ 핫패스(셀당) — 슬롯 fn 예외는 호출자 책임.\n const predicate = this._getStrategy(\n 'filterPredicate',\n (value: any, fi: FilterItem, _field: string): boolean => matchFilter(value, fi),\n );\n\n this._displayIndexes = this._data\n .map((r, i) => ({ r, i }))\n .filter(({ r }) => {\n if (this._meta.get(r[this._idField] as string)?.state === 'removed') return false;\n // 컬럼별 AND 필터\n if (fields.length > 0) {\n if (!fields.every(field => {\n const val = r[field];\n return filters[field]!.every(fi => predicate(val, fi, field));\n })) return false;\n }\n // F3 찾기 바: 전체 컬럼 OR 검색\n if (this._findQuery && this._findFields.length > 0) {\n const q = this._findQuery;\n const matched = this._findFields.some(f => {\n const v = r[f];\n return v != null && String(v).toLowerCase().includes(q);\n });\n if (!matched) return false;\n }\n return true;\n })\n .map(({ i }) => i);\n }\n\n /** F3: 찾기 바 전체 컬럼 OR 검색 설정 */\n setFindFilter(query: string, fields: string[]): void {\n this._findQuery = query.toLowerCase();\n this._findFields = fields;\n }\n\n // ─── 내부 유틸 ────────────────────────────────────────\n private _rebuildIdMap(): void {\n this._idMap.clear();\n this._data.forEach((r, i) => {\n this._idMap.set(r[this._idField] as string, i);\n });\n }\n}\n\nfunction matchFilter(value: any, fi: FilterItem): boolean {\n const v = value;\n const fv = fi.value;\n switch (fi.operator) {\n case '=': return v == fv;\n case '!=': return v != fv;\n case '>': return v > fv;\n case '>=': return v >= fv;\n case '<': return v < fv;\n case '<=': return v <= fv;\n case 'contains': return String(v).includes(String(fv));\n case 'startsWith': return String(v).startsWith(String(fv));\n case 'endsWith': return String(v).endsWith(String(fv));\n default: return true;\n }\n}\n","export interface VirtualScrollOptions {\n rowHeight: number;\n overscan?: number;\n onRender: (startIndex: number, endIndex: number) => void;\n}\n\nexport interface VirtualScrollRange {\n startIndex: number;\n endIndex: number;\n offsetY: number;\n}\n\nexport class VirtualScroll {\n private container: HTMLElement;\n private rowHeight: number;\n private overscan: number;\n private _totalRows: number = 0;\n private _scrollTop: number = 0;\n private _viewportHeight: number = 0;\n private _rafId: number | null = null;\n private onRender: (startIndex: number, endIndex: number) => void;\n\n constructor(container: HTMLElement, options: VirtualScrollOptions) {\n this.container = container;\n this.rowHeight = options.rowHeight;\n this.overscan = options.overscan ?? 5;\n this.onRender = options.onRender;\n\n this.container.addEventListener('scroll', this._onScroll, { passive: true });\n }\n\n private _onScroll = (): void => {\n this._scrollTop = this.container.scrollTop;\n this._scheduleRender();\n };\n\n private _scheduleRender(): void {\n if (this._rafId !== null) return;\n this._rafId = requestAnimationFrame(() => {\n this._rafId = null;\n const range = this.getVisibleRange();\n this.onRender(range.startIndex, range.endIndex);\n });\n }\n\n getVisibleRange(): VirtualScrollRange {\n const visibleCount = Math.ceil(this._viewportHeight / this.rowHeight);\n const startIndex = Math.max(0, Math.floor(this._scrollTop / this.rowHeight) - this.overscan);\n const endIndex = Math.min(\n this._totalRows - 1,\n startIndex + visibleCount + this.overscan * 2\n );\n const offsetY = startIndex * this.rowHeight;\n return { startIndex, endIndex, offsetY };\n }\n\n setTotalRows(count: number): void {\n this._totalRows = count;\n this._updateSpacerHeight();\n this._scheduleRender();\n }\n\n setViewportHeight(height: number): void {\n this._viewportHeight = height;\n this._scheduleRender();\n }\n\n setRowHeight(height: number): void {\n this.rowHeight = height;\n this._updateSpacerHeight();\n this._scheduleRender();\n }\n\n scrollToRow(rowIndex: number): void {\n const targetTop = rowIndex * this.rowHeight;\n const targetBottom = targetTop + this.rowHeight;\n const viewBottom = this._scrollTop + this._viewportHeight;\n\n if (targetTop < this._scrollTop) {\n this._scrollTop = targetTop;\n this.container.scrollTop = targetTop;\n } else if (targetBottom > viewBottom) {\n const newTop = targetBottom - this._viewportHeight;\n this._scrollTop = newTop;\n this.container.scrollTop = newTop;\n }\n }\n\n getTotalHeight(): number {\n return this._totalRows * this.rowHeight;\n }\n\n private _updateSpacerHeight(): void {\n // spacer 엘리먼트가 있다면 높이 업데이트\n const spacer = this.container.querySelector<HTMLElement>('.og-spacer');\n if (spacer) spacer.style.height = `${this.getTotalHeight()}px`;\n }\n\n destroy(): void {\n this.container.removeEventListener('scroll', this._onScroll);\n if (this._rafId !== null) cancelAnimationFrame(this._rafId);\n }\n}\n","import type { ColumnDef } from './types.js';\n\nexport interface FlatColumn<T = any> extends ColumnDef<T> {\n _colIndex: number;\n _depth: number;\n _leaf: boolean;\n _colSpanCount?: number;\n _rowSpanCount?: number;\n}\n\nexport interface HeaderCell {\n column: FlatColumn;\n colIndex: number;\n depth: number;\n colSpan: number;\n rowSpan: number;\n}\n\nexport class ColumnLayout<T = any> {\n private _columns: ColumnDef<T>[];\n private _flatLeaves: FlatColumn<T>[] = [];\n private _maxDepth: number = 1;\n private _frozenCount: number = 0;\n\n constructor(columns: ColumnDef<T>[], frozenCount: number = 0) {\n this._columns = columns;\n this._frozenCount = frozenCount;\n this._process();\n }\n\n private _process(): void {\n const leaves: FlatColumn<T>[] = [];\n let colIndex = 0;\n\n const walk = (cols: ColumnDef<T>[], depth: number): void => {\n for (const col of cols) {\n if (col.children && col.children.length > 0) {\n walk(col.children, depth + 1);\n this._maxDepth = Math.max(this._maxDepth, depth + 1);\n } else {\n leaves.push({ ...col, _colIndex: colIndex++, _depth: depth, _leaf: true });\n }\n }\n };\n\n this._maxDepth = 1;\n walk(this._columns, 1);\n this._flatLeaves = leaves;\n }\n\n get leaves(): FlatColumn<T>[] {\n return this._flatLeaves;\n }\n\n get visibleLeaves(): FlatColumn<T>[] {\n return this._flatLeaves.filter(c => !c.hidden);\n }\n\n get headerDepth(): number {\n return this._maxDepth;\n }\n\n get frozenCount(): number {\n return this._frozenCount;\n }\n\n setFrozen(count: number): void {\n this._frozenCount = count;\n }\n\n setColumns(columns: ColumnDef<T>[]): void {\n this._columns = columns;\n this._process();\n }\n\n hideColumn(field: string | string[]): void {\n const fields = Array.isArray(field) ? field : [field];\n this._flatLeaves.forEach(c => {\n if (fields.includes(c.field)) c.hidden = true;\n });\n }\n\n showColumn(field: string | string[]): void {\n const fields = Array.isArray(field) ? field : [field];\n this._flatLeaves.forEach(c => {\n if (fields.includes(c.field)) c.hidden = false;\n });\n }\n\n addColumn(colDef: ColumnDef<T>, position: 'first' | 'last' | number = 'last'): void {\n if (position === 'last') {\n this._columns.push(colDef);\n } else if (position === 'first') {\n this._columns.unshift(colDef);\n } else {\n this._columns.splice(position, 0, colDef);\n }\n this._process();\n }\n\n removeColumn(field: string): void {\n const removeFromList = (cols: ColumnDef<T>[]): ColumnDef<T>[] => {\n return cols.filter(c => {\n if (c.field === field) return false;\n if (c.children) c.children = removeFromList(c.children);\n return true;\n });\n };\n this._columns = removeFromList(this._columns);\n this._process();\n }\n\n getColumnByField(field: string): FlatColumn<T> | undefined {\n return this._flatLeaves.find(c => c.field === field);\n }\n\n getColumnByIndex(index: number): FlatColumn<T> | undefined {\n return this._flatLeaves[index];\n }\n\n getColumnIndex(field: string): number {\n return this._flatLeaves.findIndex(c => c.field === field);\n }\n\n /** 헤더 렌더링용 셀 계산 */\n buildHeaderCells(): HeaderCell[][] {\n const rows: HeaderCell[][] = Array.from({ length: this._maxDepth }, () => []);\n let colIndex = 0;\n\n const walk = (cols: ColumnDef<T>[], depth: number): number => {\n let span = 0;\n for (const col of cols) {\n if (col.hidden) continue;\n if (col.children && col.children.length > 0) {\n const childSpan = walk(col.children, depth + 1);\n if (childSpan > 0) {\n rows[depth - 1]!.push({\n column: col as FlatColumn<T>,\n colIndex: colIndex,\n depth,\n colSpan: childSpan,\n rowSpan: 1\n });\n span += childSpan;\n }\n } else {\n rows[depth - 1]!.push({\n column: col as FlatColumn<T>,\n colIndex: colIndex++,\n depth,\n colSpan: 1,\n rowSpan: this._maxDepth - depth + 1\n });\n span++;\n }\n }\n return span;\n };\n\n walk(this._columns, 1);\n return rows;\n }\n\n /** 각 리프 컬럼의 계산된 너비 배열 반환 */\n computeWidths(totalWidth: number, defaultWidth: number = 100): number[] {\n const visible = this.visibleLeaves;\n const flexCols = visible.filter(c => c.flex);\n const fixedTotal = visible\n .filter(c => !c.flex && c.width)\n .reduce((sum, c) => sum + c.width!, 0);\n\n const flexTotal = flexCols.reduce((sum, c) => sum + (c.flex ?? 1), 0);\n const remaining = Math.max(0, totalWidth - fixedTotal);\n\n return visible.map(c => {\n if (c.flex) return Math.round((c.flex / flexTotal) * remaining);\n return c.width ?? defaultWidth;\n });\n }\n}\n","import type { FilterItem } from './types.js';\n\nexport type FilterApplyFn = (field: string, items: FilterItem[]) => void;\nexport type FilterClearFn = (field: string) => void;\n\n/**\n * 컬럼 헤더 필터 드롭다운 패널.\n * 단일 인스턴스를 재사용(열릴 때 위치 재계산).\n */\nexport class FilterPanel {\n private _el: HTMLElement;\n private _field = '';\n private _onApply: FilterApplyFn;\n private _onClear: FilterClearFn;\n private _outsideHandler: ((e: MouseEvent) => void) | null = null;\n\n constructor(container: HTMLElement, onApply: FilterApplyFn, onClear: FilterClearFn) {\n this._onApply = onApply;\n this._onClear = onClear;\n\n this._el = document.createElement('div');\n this._el.className = 'og-filter-panel';\n this._el.style.cssText = `\n position:absolute;z-index:1000;min-width:200px;max-width:280px;\n background:var(--og-row-bg,#fff);border:1px solid var(--og-border-color,#e0e0e0);\n border-radius:4px;box-shadow:0 4px 16px rgba(0,0,0,0.15);\n padding:10px;box-sizing:border-box;display:none;font-size:13px;\n `;\n container.appendChild(this._el);\n }\n\n open(field: string, anchorEl: HTMLElement, currentFilters: FilterItem[]): void {\n this._field = field;\n this._el.innerHTML = '';\n\n // 제목\n const title = document.createElement('div');\n title.textContent = '필터';\n title.style.cssText = `font-weight:600;margin-bottom:8px;color:var(--og-text-color,#333);`;\n this._el.appendChild(title);\n\n // 조건 선택\n const condRow = document.createElement('div');\n condRow.style.cssText = 'display:flex;gap:4px;margin-bottom:6px;';\n\n const condSel = document.createElement('select');\n condSel.style.cssText = `flex:1;padding:3px 4px;border:1px solid var(--og-border-color,#e0e0e0);border-radius:3px;font-size:12px;`;\n const conditions: Array<{ label: string; value: FilterItem['operator'] }> = [\n { label: '포함', value: 'contains' },\n { label: '같음', value: '=' },\n { label: '같지 않음', value: '!=' },\n { label: '시작', value: 'startsWith' },\n { label: '끝남', value: 'endsWith' },\n { label: '보다 큼', value: '>' },\n { label: '보다 작음', value: '<' },\n { label: '이상', value: '>=' },\n { label: '이하', value: '<=' },\n ];\n for (const c of conditions) {\n const opt = document.createElement('option');\n opt.value = c.value;\n opt.textContent = c.label;\n condSel.appendChild(opt);\n }\n if (currentFilters[0]) condSel.value = currentFilters[0].operator;\n condRow.appendChild(condSel);\n this._el.appendChild(condRow);\n\n // 값 입력\n const valueInput = document.createElement('input');\n valueInput.type = 'text';\n valueInput.placeholder = '필터 값 입력...';\n valueInput.value = currentFilters[0]?.value ?? '';\n valueInput.style.cssText = `\n width:100%;padding:4px 6px;border:1px solid var(--og-border-color,#e0e0e0);\n border-radius:3px;font-size:12px;box-sizing:border-box;margin-bottom:8px;\n outline:none;\n `;\n valueInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') applyBtn.click();\n else if (e.key === 'Escape') this.close();\n });\n this._el.appendChild(valueInput);\n\n // 버튼 행\n const btnRow = document.createElement('div');\n btnRow.style.cssText = 'display:flex;gap:6px;justify-content:flex-end;';\n\n const clearBtn = document.createElement('button');\n clearBtn.textContent = '초기화';\n clearBtn.style.cssText = `\n padding:3px 10px;border:1px solid var(--og-border-color,#e0e0e0);\n border-radius:3px;background:#fff;cursor:pointer;font-size:12px;color:#666;\n `;\n clearBtn.addEventListener('click', () => {\n this._onClear(this._field);\n this.close();\n });\n\n const applyBtn = document.createElement('button');\n applyBtn.textContent = '적용';\n applyBtn.style.cssText = `\n padding:3px 10px;border:1px solid var(--og-primary,#1976d2);\n border-radius:3px;background:var(--og-primary,#1976d2);\n color:#fff;cursor:pointer;font-size:12px;\n `;\n applyBtn.addEventListener('click', () => {\n const val = valueInput.value.trim();\n if (!val) {\n this._onClear(this._field);\n } else {\n this._onApply(this._field, [{ operator: condSel.value as FilterItem['operator'], value: val }]);\n }\n this.close();\n });\n\n btnRow.appendChild(clearBtn);\n btnRow.appendChild(applyBtn);\n this._el.appendChild(btnRow);\n\n // 위치 계산 (앵커 기준)\n const rect = anchorEl.getBoundingClientRect();\n const containerRect = this._el.parentElement!.getBoundingClientRect();\n this._el.style.top = `${rect.bottom - containerRect.top + 2}px`;\n this._el.style.left = `${Math.min(rect.left - containerRect.left, containerRect.width - 220)}px`;\n this._el.style.display = 'block';\n\n requestAnimationFrame(() => valueInput.focus());\n\n // 외부 클릭 시 닫기\n if (this._outsideHandler) document.removeEventListener('mousedown', this._outsideHandler);\n this._outsideHandler = (e: MouseEvent) => {\n if (!this._el.contains(e.target as Node) && e.target !== anchorEl) {\n this.close();\n }\n };\n setTimeout(() => document.addEventListener('mousedown', this._outsideHandler!), 0);\n }\n\n close(): void {\n this._el.style.display = 'none';\n if (this._outsideHandler) {\n document.removeEventListener('mousedown', this._outsideHandler);\n this._outsideHandler = null;\n }\n }\n\n get isOpen(): boolean {\n return this._el.style.display !== 'none';\n }\n\n destroy(): void {\n this.close();\n this._el.remove();\n }\n}\n","// ============================================================\n// MathUtils — 부동소수점 안전 연산 유틸리티\n// 레이어: Algorithm\n// 설계 근거(Why): JS IEEE 754 오차(0.1+0.2=0.30000000000000004) 방지.\n// epsilon_round(곱셈 스케일링)와 Kahan compensated summation 두 전략을 조합.\n// ============================================================\n\nconst DEFAULT_PREC = 10;\n\n/**\n * 소수점 precision 자리로 반올림 (epsilon round).\n * 0.1+0.2+... 누적 오차를 최종 표시 단계에서 제거한다.\n */\nexport function round(val: number, precision: number = DEFAULT_PREC): number {\n const factor = Math.pow(10, precision);\n return Math.round(val * factor) / factor;\n}\n\n/**\n * Kahan compensated summation — 대량 합산 시 부동소수점 오차 최소화.\n * 시간복잡도 O(n), 공간 O(1). 빈 배열 → 0 반환.\n */\nexport function kahanSum(arr: number[]): number {\n let sum = 0, c = 0;\n for (const y of arr) {\n const corrected = y - c;\n const t = sum + corrected;\n c = (t - sum) - corrected;\n sum = t;\n }\n return sum;\n}\n\n/**\n * 안전 사칙연산 — 두 수의 곱셈 스케일링으로 소수점 오차 방지.\n */\nexport function safeAdd(a: number, b: number, precision: number = DEFAULT_PREC): number {\n return round(a + b, precision);\n}\n\nexport function safeSub(a: number, b: number, precision: number = DEFAULT_PREC): number {\n return round(a - b, precision);\n}\n\nexport function safeMul(a: number, b: number, precision: number = DEFAULT_PREC): number {\n return round(a * b, precision);\n}\n\nexport function safeDiv(a: number, b: number, precision: number = DEFAULT_PREC): number {\n if (b === 0) throw new Error('safeDiv: division by zero');\n return round(a / b, precision);\n}\n\n/**\n * Kahan 합산 후 precision 반올림.\n * SUM/AVG footer 계산에 사용.\n */\nexport function kahanSumRounded(arr: number[], precision: number = DEFAULT_PREC): number {\n return round(kahanSum(arr), precision);\n}\n\n/**\n * Kahan AVG — 합산 후 count로 나누기.\n */\nexport function kahanAvg(arr: number[], precision: number = DEFAULT_PREC): number {\n if (arr.length === 0) return 0;\n return round(kahanSum(arr) / arr.length, precision);\n}\n","// ============================================================\n// OGDecimal — BigInt 기반 임의정밀도 소수 클래스\n// 레이어: Algorithm\n// 설계 근거(Why): JS IEEE 754는 소수점 17자리가 한계.\n// 음원 수익 배분 등 수백 자리 정밀도가 필요한 경우 BigInt를\n// coefficient + scale 구조로 표현해 오차 없는 연산을 보장한다.\n// 외부 라이브러리 없음 (ES2020+ BigInt 내장 사용).\n// 표현: value = coefficient / 10^scale\n// 예) 3.14 → {c: 314n, s: 2} / 0.001 → {c: 1n, s: 3}\n// ============================================================\n\nexport type OGDecimalLike = string | number | bigint | OGDecimal;\n\nexport class OGDecimal {\n private readonly _c: bigint; // coefficient (부호 포함 정수)\n private readonly _s: number; // scale = 소수점 아래 자릿수\n\n constructor(coefficient: bigint, scale: number) {\n this._c = coefficient;\n this._s = scale < 0 ? 0 : scale;\n }\n\n // ── 생성 ─────────────────────────────────────────────────\n\n static from(value: OGDecimalLike): OGDecimal {\n if (value instanceof OGDecimal) return value;\n if (typeof value === 'bigint') return new OGDecimal(value, 0);\n\n const str = String(value).trim();\n if (!str || str === 'null' || str === 'undefined' || str === 'NaN') {\n return new OGDecimal(0n, 0);\n }\n\n const isNeg = str.startsWith('-');\n const abs = isNeg ? str.slice(1) : str;\n const dot = abs.indexOf('.');\n\n let coeff: bigint;\n let scale: number;\n\n if (dot === -1) {\n coeff = BigInt(abs);\n scale = 0;\n } else {\n const frac = abs.slice(dot + 1);\n coeff = BigInt(abs.slice(0, dot) + frac);\n scale = frac.length;\n }\n\n return new OGDecimal(isNeg ? -coeff : coeff, scale);\n }\n\n static zero(): OGDecimal { return new OGDecimal(0n, 0); }\n static one(): OGDecimal { return new OGDecimal(1n, 0); }\n\n // ── 내부: 두 값의 스케일 정렬 ────────────────────────────\n\n private static _align(a: OGDecimal, b: OGDecimal): [bigint, bigint, number] {\n if (a._s === b._s) return [a._c, b._c, a._s];\n if (a._s > b._s) {\n return [a._c, b._c * (10n ** BigInt(a._s - b._s)), a._s];\n }\n return [a._c * (10n ** BigInt(b._s - a._s)), b._c, b._s];\n }\n\n // ── 사칙연산 ─────────────────────────────────────────────\n\n add(other: OGDecimalLike): OGDecimal {\n const [ac, bc, s] = OGDecimal._align(this, OGDecimal.from(other));\n return new OGDecimal(ac + bc, s);\n }\n\n sub(other: OGDecimalLike): OGDecimal {\n const [ac, bc, s] = OGDecimal._align(this, OGDecimal.from(other));\n return new OGDecimal(ac - bc, s);\n }\n\n mul(other: OGDecimalLike): OGDecimal {\n const o = OGDecimal.from(other);\n return new OGDecimal(this._c * o._c, this._s + o._s);\n }\n\n /**\n * 나눗셈. precision = 결과 소수점 자리수 (기본 20).\n * 수익 배분처럼 소수 수백 자리가 필요하면 precision을 높인다.\n */\n div(other: OGDecimalLike, precision = 20): OGDecimal {\n const o = OGDecimal.from(other);\n if (o._c === 0n) throw new Error('OGDecimal: division by zero');\n // 분자를 키워서 정수 나눗셈으로 정밀도 확보\n const scaledNumerator = this._c * (10n ** BigInt(precision + o._s));\n const result = scaledNumerator / o._c;\n return new OGDecimal(result, precision + this._s);\n }\n\n /** 나머지 (정수 나머지와 동일한 개념을 소수에 적용) */\n mod(other: OGDecimalLike): OGDecimal {\n const o = OGDecimal.from(other);\n const [ac, bc, s] = OGDecimal._align(this, o);\n return new OGDecimal(ac % bc, s);\n }\n\n /** 부호 반전 */\n neg(): OGDecimal { return new OGDecimal(-this._c, this._s); }\n\n /** 절댓값 */\n abs(): OGDecimal {\n return new OGDecimal(this._c < 0n ? -this._c : this._c, this._s);\n }\n\n // ── 비교 ─────────────────────────────────────────────────\n\n eq(other: OGDecimalLike): boolean {\n const [ac, bc] = OGDecimal._align(this, OGDecimal.from(other));\n return ac === bc;\n }\n gt(other: OGDecimalLike): boolean {\n const [ac, bc] = OGDecimal._align(this, OGDecimal.from(other));\n return ac > bc;\n }\n lt(other: OGDecimalLike): boolean {\n const [ac, bc] = OGDecimal._align(this, OGDecimal.from(other));\n return ac < bc;\n }\n gte(other: OGDecimalLike): boolean { return !this.lt(other); }\n lte(other: OGDecimalLike): boolean { return !this.gt(other); }\n isZero(): boolean { return this._c === 0n; }\n isNeg(): boolean { return this._c < 0n; }\n isPos(): boolean { return this._c > 0n; }\n\n // ── 출력 ─────────────────────────────────────────────────\n\n /**\n * 지정 소수점 자리수로 반올림(Half-up) 후 문자열 반환.\n * 음원 배분 등 정확한 자리수 표시에 사용.\n */\n toFixed(dp: number): string {\n let c = this._c;\n let s = this._s;\n\n if (s < dp) {\n c = c * (10n ** BigInt(dp - s));\n } else if (s > dp) {\n const diff = BigInt(s - dp);\n const divisor = 10n ** diff;\n const half = divisor / 2n;\n const isNeg = c < 0n;\n const abs_c = isNeg ? -c : c;\n const rem = abs_c % divisor;\n let rounded = abs_c / divisor;\n if (rem >= half) rounded += 1n;\n c = isNeg ? -rounded : rounded;\n }\n s = dp;\n\n const isNeg = c < 0n;\n const abs_c = isNeg ? -c : c;\n const digits = abs_c.toString().padStart(dp + 1, '0');\n const intPart = digits.slice(0, digits.length - dp) || '0';\n const fracPart = dp > 0 ? '.' + digits.slice(digits.length - dp) : '';\n return (isNeg ? '-' : '') + intPart + fracPart;\n }\n\n /** 정규화(후행 0 제거) 후 최소 표현 문자열 반환 */\n toString(): string {\n if (this._s === 0) return this._c.toString();\n // 후행 0 제거\n let c = this._c, s = this._s;\n while (s > 0 && c !== 0n && c % 10n === 0n) { c /= 10n; s--; }\n return new OGDecimal(c, s).toFixed(s);\n }\n\n /** number로 변환 (정밀도 손실 주의 — 표시 전용) */\n toNumber(): number { return parseFloat(this.toFixed(20)); }\n\n // ── 집계 정적 메서드 ─────────────────────────────────────\n\n /** 정확한 합산 (내부적으로 BigInt 정수 연산) */\n static sum(arr: OGDecimalLike[]): OGDecimal {\n return arr.reduce<OGDecimal>((acc, v) => acc.add(v), OGDecimal.zero());\n }\n\n /** 정확한 평균. precision = 나눗셈 소수점 자리수 */\n static avg(arr: OGDecimalLike[], precision = 20): OGDecimal {\n if (!arr.length) return OGDecimal.zero();\n return OGDecimal.sum(arr).div(arr.length, precision);\n }\n\n /** 배열 최솟값 */\n static min(arr: OGDecimalLike[]): OGDecimal {\n if (!arr.length) throw new Error('OGDecimal.min: empty array');\n return arr.map(OGDecimal.from).reduce((a, b) => a.lt(b) ? a : b);\n }\n\n /** 배열 최댓값 */\n static max(arr: OGDecimalLike[]): OGDecimal {\n if (!arr.length) throw new Error('OGDecimal.max: empty array');\n return arr.map(OGDecimal.from).reduce((a, b) => a.gt(b) ? a : b);\n }\n}\n","// ============================================================\n// FormulaEngine — 그리드 컬럼 수식 파서/실행기\n// 레이어: Algorithm (순수 파싱·연산 로직)\n// 설계 근거(Why): Excel처럼 컬럼에 문자열 수식을 지정하면\n// 행 데이터를 컨텍스트로 OGDecimal 정밀 연산을 수행한다.\n// 재귀 하강 파서(Recursive Descent) 사용 — 연산자 우선순위 자동 처리.\n// 문법:\n// expression = additive\n// additive = multiplicative (('+' | '-') multiplicative)*\n// multiplicative = unary (('*' | '/' | '%') unary)*\n// unary = '-' unary | primary\n// primary = '(' expression ')' | '[' field ']' | number\n// 예시:\n// \"[revenue] * 0.035\"\n// \"([price] - [cost]) / [price] * 100\"\n// \"[qty] * [unit_price] * (1 - [discount_rate] / 100)\"\n// ============================================================\n\nimport { OGDecimal, type OGDecimalLike } from './OGDecimal.js';\n\nexport type FormulaContext = Record<string, OGDecimalLike>;\n\n/**\n * 문자열 수식을 평가해 OGDecimal 결과를 반환한다.\n * @param expr - 수식 문자열 (예: \"[price] * [qty] * 0.035\")\n * @param ctx - 필드값 컨텍스트 (행 데이터)\n * @param divisionPrecision - 나눗셈 소수점 자리수 (기본 30)\n */\nexport function evaluateFormula(\n expr: string,\n ctx: FormulaContext,\n divisionPrecision = 30,\n): OGDecimal {\n return new _FormulaParser(expr, ctx, divisionPrecision).parse();\n}\n\n// ─── 내부: 재귀 하강 파서 ────────────────────────────────\n\nclass _FormulaParser {\n private _pos = 0;\n private readonly _src: string;\n\n constructor(\n src: string,\n private readonly _ctx: FormulaContext,\n private readonly _prec: number,\n ) {\n this._src = src.trim();\n }\n\n parse(): OGDecimal {\n const result = this._additive();\n this._skip();\n if (this._pos < this._src.length) {\n throw new SyntaxError(\n `FormulaEngine: 예상치 못한 토큰 '${this._src[this._pos]}' (위치 ${this._pos})`\n );\n }\n return result;\n }\n\n // ── expression layers ──────────────────────────────────\n\n private _additive(): OGDecimal {\n let left = this._multiplicative();\n this._skip();\n while (this._pos < this._src.length) {\n const ch = this._src[this._pos];\n if (ch !== '+' && ch !== '-') break;\n this._pos++;\n this._skip();\n const right = this._multiplicative();\n left = ch === '+' ? left.add(right) : left.sub(right);\n this._skip();\n }\n return left;\n }\n\n private _multiplicative(): OGDecimal {\n let left = this._unary();\n this._skip();\n while (this._pos < this._src.length) {\n const ch = this._src[this._pos];\n if (ch !== '*' && ch !== '/' && ch !== '%') break;\n this._pos++;\n this._skip();\n const right = this._unary();\n if (ch === '*') left = left.mul(right);\n else if (ch === '/') left = left.div(right, this._prec);\n else left = left.mod(right);\n this._skip();\n }\n return left;\n }\n\n private _unary(): OGDecimal {\n this._skip();\n if (this._src[this._pos] === '-') {\n this._pos++;\n return this._unary().neg();\n }\n return this._primary();\n }\n\n private _primary(): OGDecimal {\n this._skip();\n const ch = this._src[this._pos];\n\n if (ch === '(') {\n this._pos++;\n const val = this._additive();\n this._skip();\n if (this._src[this._pos] !== ')') {\n throw new SyntaxError('FormulaEngine: 닫는 괄호 ) 누락');\n }\n this._pos++;\n return val;\n }\n\n if (ch === '[') return this._fieldRef();\n\n return this._literal();\n }\n\n // ── 토큰 파싱 ─────────────────────────────────────────\n\n /** [fieldName] → 행 데이터에서 값 추출 */\n private _fieldRef(): OGDecimal {\n this._pos++; // skip '['\n const start = this._pos;\n while (this._pos < this._src.length && this._src[this._pos] !== ']') {\n this._pos++;\n }\n if (this._pos >= this._src.length) {\n throw new SyntaxError('FormulaEngine: 닫는 ] 누락');\n }\n const field = this._src.slice(start, this._pos);\n this._pos++; // skip ']'\n\n const val = this._ctx[field];\n if (val == null) {\n throw new ReferenceError(`FormulaEngine: 필드 '[${field}]'가 행 데이터에 없습니다`);\n }\n return OGDecimal.from(val);\n }\n\n /** 숫자 리터럴 파싱 (정수 / 소수 모두) */\n private _literal(): OGDecimal {\n const start = this._pos;\n while (this._pos < this._src.length && /[0-9.]/.test(this._src[this._pos])) {\n this._pos++;\n }\n const numStr = this._src.slice(start, this._pos);\n if (!numStr) {\n throw new SyntaxError(\n `FormulaEngine: 숫자 또는 [필드]를 기대했지만 '${this._src[this._pos] ?? 'EOF'}' 발견 (위치 ${start})`\n );\n }\n return OGDecimal.from(numStr);\n }\n\n /** 공백 스킵 */\n private _skip(): void {\n while (this._pos < this._src.length && /\\s/.test(this._src[this._pos])) {\n this._pos++;\n }\n }\n}\n","// ============================================================\n// F5: MaskingEngine — 컬럼 데이터 마스킹 처리\n// ============================================================\n//\n// 지원 타입 (MaskType):\n// ssn — 주민등록번호 930101-1******\n// phone — 전화번호 010-****-5678 / 02-****-5678\n// mobile — 휴대폰 (phone과 동일)\n// email — 이메일 ho***@example.com\n// credit — 신용카드 1234-****-****-5678\n// account — 계좌번호 123-*****-1234 (앞3 뒤4 노출)\n// password — 비밀번호 ******* (전체 마스킹)\n// name — 이름 홍*동 / 홍**\n// ip — IP 주소 192.168.***.***\n// partial — 부분 마스킹 visiblePrefix/visibleSuffix 자유 지정\n//\n// 사용법:\n// applyMask('01012345678', 'phone')\n// → '010-****-5678'\n//\n// applyMask('hong@example.com', { type: 'email', char: '#' })\n// → 'ho###@example.com'\n//\n// applyMask('1234567890', { type: 'partial', visiblePrefix: 2, visibleSuffix: 2 })\n// → '12******90'\n// ============================================================\n\n/** 지원 마스킹 타입 */\nexport type MaskType =\n | 'ssn' // 주민등록번호: 930101-1******\n | 'phone' // 전화번호: 010-****-5678\n | 'mobile' // 휴대폰 (phone과 동일)\n | 'email' // 이메일: ho***@example.com\n | 'credit' // 신용카드: 1234-****-****-5678\n | 'account' // 계좌번호: 123-*****-1234\n | 'password' // 비밀번호: ******* (전체)\n | 'name' // 이름: 홍*동\n | 'ip' // IP 주소: 192.168.***.***\n | 'partial'; // 부분 마스킹 (visiblePrefix/visibleSuffix 지정)\n\n/** 마스킹 상세 옵션 */\nexport interface MaskDef {\n type: MaskType;\n /** 마스킹 치환 문자 (기본: '*') */\n char?: string;\n /** partial/account: 앞 N자리 표시 */\n visiblePrefix?: number;\n /** partial/account: 뒤 N자리 표시 */\n visibleSuffix?: number;\n}\n\n/**\n * 원본 값에 마스킹을 적용해 표시용 문자열을 반환.\n *\n * @param value 원본 값 (null/undefined → 빈 문자열 그대로 반환)\n * @param maskDef 마스킹 타입 또는 상세 옵션\n * @returns 마스킹된 문자열\n *\n * @example\n * applyMask('930101-1234567', 'ssn') // '930101-1******'\n * applyMask('01012345678', 'phone') // '010-****-5678'\n * applyMask('hong@test.com', 'email') // 'ho***@test.com'\n */\nexport function applyMask(value: string, maskDef: MaskType | MaskDef): string {\n if (value == null || value === '') return value ?? '';\n const def: MaskDef = typeof maskDef === 'string' ? { type: maskDef } : maskDef;\n const char = def.char ?? '*';\n\n switch (def.type) {\n case 'ssn': return _maskSSN(value, char);\n case 'phone':\n case 'mobile': return _maskPhone(value, char);\n case 'email': return _maskEmail(value, char);\n case 'credit': return _maskCredit(value, char);\n case 'account': return _maskAccount(value, char, def.visiblePrefix ?? 3, def.visibleSuffix ?? 4);\n case 'password': return char.repeat(Math.max(value.length, 6));\n case 'name': return _maskName(value, char);\n case 'ip': return _maskIP(value, char);\n case 'partial': return _maskPartial(value, char, def.visiblePrefix ?? 0, def.visibleSuffix ?? 4);\n default: return value;\n }\n}\n\n// ─────────────────────────────────────────────────────────────\n// 개별 마스킹 함수\n// ─────────────────────────────────────────────────────────────\n\n/**\n * 주민등록번호 마스킹\n * 입력: '9301011234567' 또는 '930101-1234567'\n * 출력: '930101-1******' (앞 6자리 + 뒷 1자리 노출, 나머지 마스킹)\n */\nfunction _maskSSN(v: string, c: string): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length < 7) {\n // 7자리 미만이면 구분자 유지하며 뒷자리 마스킹\n const sep = v.includes('-') ? '-' : '';\n const frontEnd = v.indexOf('-') >= 0 ? v.indexOf('-') : 6;\n return v.slice(0, frontEnd) + sep + c.repeat(Math.max(1, v.length - frontEnd - sep.length));\n }\n const front = clean.slice(0, 6);\n const backFirst = clean[6]!;\n const maskLen = clean.length - 7;\n return `${front}-${backFirst}${c.repeat(maskLen)}`;\n}\n\n/**\n * 전화번호/휴대폰 마스킹\n * 입력: '01012345678' → '010-****-5678'\n * 입력: '0215551234' → '02-****-1234'\n * 입력: '0319991234' → '031-***-1234'\n */\nfunction _maskPhone(v: string, c: string): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length === 11) {\n // 010-xxxx-xxxx (11자리 휴대폰)\n return `${clean.slice(0, 3)}-${c.repeat(4)}-${clean.slice(7)}`;\n } else if (clean.length === 10) {\n if (clean.startsWith('02')) {\n // 서울 02-xxxx-xxxx\n return `${clean.slice(0, 2)}-${c.repeat(4)}-${clean.slice(6)}`;\n }\n // 지역번호 3자리 031-xxx-xxxx\n return `${clean.slice(0, 3)}-${c.repeat(3)}-${clean.slice(6)}`;\n } else if (clean.length === 9) {\n // 02-xxx-xxxx (구형 서울)\n return `${clean.slice(0, 2)}-${c.repeat(3)}-${clean.slice(5)}`;\n }\n // fallback: 앞 3자리 + 뒤 4자리 노출\n return _maskPartial(v, c, 3, 4);\n}\n\n/**\n * 이메일 마스킹\n * 입력: 'hong@example.com' → 'ho***@example.com'\n * 입력: 'a@b.com' → 'a***@b.com' (1자리도 앞 1자리 노출)\n */\nfunction _maskEmail(v: string, c: string): string {\n const atIdx = v.indexOf('@');\n if (atIdx < 0) return _maskPartial(v, c, 2, 0);\n const local = v.slice(0, atIdx);\n const domain = v.slice(atIdx); // '@' 포함\n const visLen = Math.min(2, local.length);\n const visible = local.slice(0, visLen);\n // 마스킹 최소 3자리 이상으로 표시 (원본 길이 무관)\n const maskLen = Math.max(local.length - visLen, 3);\n return `${visible}${c.repeat(maskLen)}${domain}`;\n}\n\n/**\n * 신용카드 마스킹\n * 입력: '4123456789012345' → '4123-****-****-2345'\n * 앞 4자리 + 뒤 4자리 노출, 중간 마스킹 (4자리씩 구분)\n */\nfunction _maskCredit(v: string, c: string): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length < 8) return v;\n const first4 = clean.slice(0, 4);\n const last4 = clean.slice(-4);\n const midLen = clean.length - 8;\n // 중간부가 없으면 8자리(****-****)로 패딩\n const mid = c.repeat(Math.max(midLen, 8));\n const parts: string[] = [first4];\n for (let i = 0; i < mid.length; i += 4) {\n const chunk = mid.slice(i, i + 4);\n if (chunk) parts.push(chunk);\n }\n parts.push(last4);\n return parts.join('-');\n}\n\n/**\n * 계좌번호 마스킹\n * 입력: '1234567890123' → '123-*******-0123' (기본 앞3 뒤4)\n * visiblePrefix/visibleSuffix로 조절 가능\n */\nfunction _maskAccount(v: string, c: string, prefixLen: number, suffixLen: number): string {\n const clean = v.replace(/[^0-9]/g, '');\n if (clean.length <= prefixLen + suffixLen) {\n return _maskPartial(clean, c, prefixLen, suffixLen);\n }\n const prefix = clean.slice(0, prefixLen);\n const suffix = clean.slice(-suffixLen);\n const midLen = clean.length - prefixLen - suffixLen;\n return `${prefix}-${c.repeat(midLen)}-${suffix}`;\n}\n\n/**\n * 이름 마스킹\n * 2자: 홍* (첫 글자만 노출)\n * 3자: 홍*동 (첫글자+끝글자, 중간 마스킹)\n * 4자+: 홍**동\n */\nfunction _maskName(v: string, c: string): string {\n const t = v.trim();\n if (t.length === 0) return v;\n if (t.length === 1) return c;\n if (t.length === 2) return `${t[0]}${c}`;\n // 3자 이상: 첫글자 + 중간 마스킹 + 끝글자\n return `${t[0]}${c.repeat(t.length - 2)}${t[t.length - 1]}`;\n}\n\n/**\n * IP 주소 마스킹\n * 입력: '192.168.1.100' → '192.168.***.***'\n * 앞 2옥텟 노출, 3·4 옥텟 마스킹\n */\nfunction _maskIP(v: string, c: string): string {\n const parts = v.split('.');\n if (parts.length !== 4) return _maskPartial(v, c, 3, 0);\n const maskOctet = (octet: string) => c.repeat(Math.max(octet.length, 3));\n return `${parts[0]}.${parts[1]}.${maskOctet(parts[2]!)}.${maskOctet(parts[3]!)}`;\n}\n\n/**\n * 부분 마스킹\n * 앞 visiblePrefix자리 + 중간 마스킹 + 뒤 visibleSuffix자리 노출\n * 예) applyMask('1234567890', { type:'partial', visiblePrefix:2, visibleSuffix:2 })\n * → '12******90'\n */\nfunction _maskPartial(v: string, c: string, prefixLen: number, suffixLen: number): string {\n if (v.length <= prefixLen + suffixLen) return v;\n const prefix = v.slice(0, prefixLen);\n const suffix = suffixLen > 0 ? v.slice(-suffixLen) : '';\n const midLen = v.length - prefixLen - suffixLen;\n return `${prefix}${c.repeat(midLen)}${suffix}`;\n}\n","import type { ColumnDef } from '../types.js';\nimport { round } from '../MathUtils.js';\nimport { OGDecimal } from '../OGDecimal.js';\nimport { evaluateFormula } from '../FormulaEngine.js';\nimport { applyMask } from '../MaskingEngine.js';\n\nexport interface RenderContext<T = any> {\n value: any;\n row: T;\n rowIndex: number;\n column: ColumnDef<T>;\n colIndex: number;\n isSelected: boolean;\n rowState: 'none' | 'added' | 'edited' | 'removed';\n}\n\nexport interface CellRenderer {\n render(ctx: RenderContext): HTMLElement;\n}\n\n// ─── Phase 2 슬롯 #3(렌더러측): displayFormatter ──────────\n/**\n * 모듈 함수 formatNumber/formatDate 는 host 참조가 없으므로(렌더러는 createRenderer 로\n * grid 컨텍스트 없이 생성됨) 모듈 레벨 resolver 로 displayFormatter 슬롯에 도달한다.\n * default = null → 기존 포맷 로직으로 폴백(출력 바이트 동일, 회귀 0).\n * OpenGrid 생성자에서 setDisplayFormatterResolver(_ovk.getStrategy) 주입.\n * 주의(멀티 인스턴스): 렌더러측 커스텀 displayFormatter 는 모듈 전역 — 동시 다중 그리드 시\n * 마지막 설치 그리드의 resolver 가 우선. 인스턴스 안전 경로는 OpenGrid.getDisplayValue 슬롯.\n */\nlet _displayFormatterResolver:\n | ((value: any, field: string, row: any) => string | null)\n | null = null;\n\nexport function setDisplayFormatterResolver(\n resolver: ((value: any, field: string, row: any) => string | null) | null,\n): void {\n _displayFormatterResolver = resolver;\n}\n\n// ─── 수식 평가 헬퍼 ───────────────────────────────────────\n/**\n * 컬럼에 formula가 있으면 OGDecimal로 평가해 표시값(string)을 반환.\n * formula가 없으면 null 반환 → 기존 ctx.value 사용.\n */\nexport function resolveFormula(ctx: RenderContext): string | null {\n const col = ctx.column;\n if (!col.formula) return null;\n const prec = col.formulaPrecision ?? 30;\n try {\n let result: any;\n if (typeof col.formula === 'function') {\n result = col.formula(ctx.row, OGDecimal);\n } else {\n result = evaluateFormula(col.formula, ctx.row as Record<string, any>, prec);\n }\n // OGDecimal → toFixed(precision) or toString\n if (result instanceof OGDecimal) {\n return col.precision != null ? result.toFixed(col.precision) : result.toString();\n }\n // string 반환된 경우 그대로 사용\n if (typeof result === 'string') return result;\n // number 등 → precision 적용\n return col.precision != null\n ? OGDecimal.from(result).toFixed(col.precision)\n : String(result);\n } catch (e) {\n console.warn('[OpenGrid] Formula error:', e);\n return '#ERR';\n }\n}\n\n// ─── 숫자 포맷 유틸 ───────────────────────────────────────\n/**\n * 숫자 포맷.\n * format 문자열:\n * '#,##0' 천단위 콤마, 정수\n * '#,##0.00' 천단위 콤마, 소수 2자리\n * '₩#,##0' 통화 접두 (₩1,234)\n * '$#,##0.00' 통화 접두 ($1,234.56)\n * '#,##0원' 통화 접미 (1,234원)\n * '$#,##0;($#,##0)' 양수;음수 패턴 — 음수를 괄호로 (회계식)\n * currency: ISO 통화코드('KRW'|'USD'|'EUR'…) 지정 시 Intl.NumberFormat 로케일 통화 포맷 우선.\n */\nexport function formatNumber(value: any, format?: string, precision?: number, currency?: string, field?: string, row?: any): string {\n // Phase 2 슬롯 #3(렌더러측): displayFormatter 가 등록되어 non-null 반환 시 그 값을 사용.\n // default(resolver null 또는 null 반환) → 아래 기존 로직(출력 동일). ⚠️ 핫패스 — 예외 비격리.\n if (_displayFormatterResolver) {\n const custom = _displayFormatterResolver(value, field ?? '', row);\n if (custom != null) return custom;\n }\n if (value == null || value === '') return '';\n let num = Number(value);\n if (isNaN(num)) return String(value);\n\n // F4: precision 지정 시 epsilon round 적용\n if (precision != null) num = round(num, precision);\n\n // ISO 통화코드 지정 시 → Intl 로케일 통화 포맷 (format 무시)\n if (currency) {\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency', currency,\n ...(precision != null ? { minimumFractionDigits: precision, maximumFractionDigits: precision } : {}),\n }).format(num);\n } catch { /* 잘못된 코드 → 아래 format 폴백 */ }\n }\n\n if (!format) {\n // precision 지정 시 소수점 자리 고정 표시\n return precision != null ? num.toFixed(precision) : String(num);\n }\n\n // 음수 전용 패턴: \"양수포맷;음수포맷\" (음수면 부호는 포맷이 표현 → 절댓값 사용)\n const semi = format.indexOf(';');\n const negFmt = semi >= 0 ? format.slice(semi + 1) : null;\n const useFmt = (num < 0 && negFmt != null) ? negFmt : (semi >= 0 ? format.slice(0, semi) : format);\n const abs = (num < 0 && negFmt != null) ? Math.abs(num) : num;\n\n // 숫자 토큰(#,0,.)과 접두/접미(통화기호 등) 분리\n const m = useFmt.match(/[#0][#0,]*(?:\\.[#0]+)?/);\n if (!m) return String(num); // 숫자 토큰 없음 → 기존 동작 유지\n const token = m[0];\n const prefix = useFmt.slice(0, m.index);\n const suffix = useFmt.slice(m.index! + token.length);\n\n const useGrouping = token.includes(',');\n const decimals = token.includes('.') ? token.split('.')[1]!.length : (precision ?? 0);\n const body = abs.toLocaleString('ko-KR', {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n useGrouping,\n });\n\n return prefix + body + suffix;\n}\n\n// ─── 날짜 포맷 유틸 ───────────────────────────────────────\nexport function formatDate(value: any, format = 'yyyy-MM-dd', field?: string, row?: any): string {\n // Phase 2 슬롯 #3(렌더러측): displayFormatter 우선. default → 기존 로직(출력 동일).\n if (_displayFormatterResolver) {\n const custom = _displayFormatterResolver(value, field ?? '', row);\n if (custom != null) return custom;\n }\n if (!value) return '';\n const d = value instanceof Date ? value : new Date(value);\n if (isNaN(d.getTime())) return String(value);\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return format\n .replace('yyyy', String(y))\n .replace('MM', m)\n .replace('dd', day);\n}\n\n// ─── F5: 마스킹 셀 렌더링 헬퍼 ──────────────────────────\n/**\n * 마스킹된 셀을 렌더링한다.\n * - 좌측: 마스킹 문자열 (monospace)\n * - 우측: 눈 아이콘 버튼 — 클릭 시 해당 셀만 원문 표시 (DOM 직접 교체)\n *\n * 재렌더 시 col._maskRevealedRows에 rowIndex가 있으면 원문이 유지된다.\n */\nfunction _renderMasked(original: string, col: ColumnDef, rowIndex: number): HTMLElement {\n const masked = applyMask(original, col.mask!);\n\n const wrap = document.createElement('span');\n wrap.style.cssText =\n 'display:flex;align-items:center;gap:3px;overflow:hidden;width:100%;box-sizing:border-box;';\n\n const text = document.createElement('span');\n text.style.cssText =\n 'flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;' +\n 'font-family:monospace;letter-spacing:0.4px;color:var(--og-mask-text,#888);';\n text.textContent = masked;\n\n // 눈 아이콘 — SVG (Bootstrap Icons eye)\n const eye = document.createElement('button');\n eye.title = '클릭하면 원문 표시';\n eye.setAttribute('aria-label', '마스킹 해제');\n eye.innerHTML =\n '<svg width=\"13\" height=\"13\" viewBox=\"0 0 16 16\" fill=\"currentColor\">' +\n '<path d=\"M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8z\"/>' +\n '<path d=\"M8 5.5A2.5 2.5 0 1 0 8 10.5 2.5 2.5 0 0 0 8 5.5zm0 4A1.5 1.5 0 1 1 8 6.5a1.5 1.5 0 0 1 0 3z\" fill=\"#fff\"/>' +\n '</svg>';\n eye.style.cssText =\n 'flex-shrink:0;background:none;border:none;cursor:pointer;' +\n 'color:#c0c0c0;padding:1px 2px;line-height:0;border-radius:3px;' +\n 'display:flex;align-items:center;';\n\n eye.addEventListener('mouseover', () => {\n eye.style.color = 'var(--og-primary,#1976d2)';\n eye.style.background = 'rgba(25,118,210,0.08)';\n });\n eye.addEventListener('mouseout', () => {\n eye.style.color = '#c0c0c0';\n eye.style.background = 'none';\n });\n\n eye.addEventListener('click', (e: MouseEvent) => {\n e.stopPropagation();\n // DOM 즉시 교체 — 재렌더 없이 원문 표시\n text.textContent = original;\n text.style.fontFamily = '';\n text.style.letterSpacing = '';\n text.style.color = '';\n eye.remove();\n // 재렌더 시에도 해제 유지: 컬럼 내부 상태에 기록\n ((col as any)._maskRevealedRows as Set<number> | undefined ??\n (((col as any)._maskRevealedRows = new Set<number>()) as Set<number>)).add(rowIndex);\n });\n\n wrap.appendChild(text);\n wrap.appendChild(eye);\n return wrap;\n}\n\n// ─── TextRenderer ────────────────────────────────────────\nexport class TextRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-text';\n // formula 우선 평가\n const formulaResult = resolveFormula(ctx);\n if (formulaResult !== null) {\n span.textContent = formulaResult;\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n return span;\n }\n const { value, column, rowIndex } = ctx;\n\n let displayText: string;\n if (column.valueMap && value != null && column.valueMap[value]) {\n displayText = column.valueMap[value]!;\n } else {\n displayText = value == null ? '' : String(value);\n }\n\n // F5: 마스킹 처리\n // 컬럼 전체 해제(_maskRevealed) 또는 해당 행 해제(_maskRevealedRows) 시 원문 표시\n if (column.mask) {\n const colRevealed = (column as any)._maskRevealed === true;\n const rowRevealed = ((column as any)._maskRevealedRows as Set<number> | undefined)?.has(rowIndex) === true;\n if (!colRevealed && !rowRevealed) {\n return _renderMasked(displayText, column, rowIndex);\n }\n }\n\n span.textContent = displayText;\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n return span;\n }\n}\n\n// ─── SelectRenderer ───────────────────────────────────────\nexport class SelectRenderer implements CellRenderer {\n private _opts: Array<{ label: string; value: any }>;\n private _fn: ((row: any, ri: number) => Array<{ label?: string; text?: string; value: any }>) | null;\n\n constructor(\n opts: Array<{ label?: string; text?: string; value: any }> = [],\n fn?: (row: any, ri: number) => Array<{ label?: string; text?: string; value: any }>\n ) {\n this._opts = opts.map(o =>\n typeof o === 'string' ? { label: o, value: o }\n : { label: (o as any).label ?? (o as any).text ?? String((o as any).value ?? ''), value: (o as any).value }\n );\n this._fn = fn ?? null;\n }\n\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-text';\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n const rawVal = ctx.value;\n if (rawVal == null || rawVal === '') return span;\n const vs = String(rawVal);\n const list = this._fn\n ? this._fn(ctx.row, ctx.rowIndex).map((o: any) =>\n typeof o === 'string' ? { label: o, value: o }\n : { label: o.label ?? o.text ?? String(o.value ?? ''), value: o.value })\n : this._opts;\n const found = list.find(o => String(o.value) === vs);\n span.textContent = found ? found.label : vs;\n return span;\n }\n}\n\n// ─── NumberRenderer ───────────────────────────────────────\nexport class NumberRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-number';\n // formula 우선 평가 (OGDecimal 고정밀도)\n const formulaResult = resolveFormula(ctx);\n if (formulaResult !== null) {\n span.textContent = formulaResult;\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;width:100%;text-align:right;';\n return span;\n }\n // format 미지정 시 기본 천단위 콤마 (#,##0). precision 있으면 F4 epsilon round 적용.\n // currency(ISO 통화코드) 지정 시 Intl 로케일 통화 포맷 우선.\n span.textContent = formatNumber(ctx.value, ctx.column.format ?? '#,##0', ctx.column.precision, ctx.column.currency, ctx.column.field, ctx.row);\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;width:100%;text-align:right;';\n return span;\n }\n}\n\n// ─── DateRenderer ─────────────────────────────────────────\nexport class DateRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const span = document.createElement('span');\n span.className = 'og-cell-date';\n span.textContent = formatDate(ctx.value, ctx.column.format, ctx.column.field, ctx.row);\n span.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n return span;\n }\n}\n\n// ─── CheckboxRenderer ─────────────────────────────────────\nexport class CheckboxRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.className = 'og-cell-checkbox';\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const chk = document.createElement('input');\n chk.type = 'checkbox';\n chk.checked = !!ctx.value;\n chk.disabled = true; // 클릭은 셀 이벤트로 처리 (_handleCellClick → writeCell)\n chk.style.cssText += 'cursor:pointer;pointer-events:none;';\n wrap.appendChild(chk);\n return wrap;\n }\n}\n\n// ─── ButtonRenderer ───────────────────────────────────────\nexport interface ButtonRendererDef {\n type: 'button';\n label?: string | ((value: any, row: any) => string);\n buttonClass?: string;\n style?: string;\n}\n\nexport class ButtonRenderer implements CellRenderer {\n constructor(private def?: ButtonRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const btn = document.createElement('button');\n btn.className = `og-cell-btn${this.def?.buttonClass ? ' ' + this.def.buttonClass : ''}`;\n const label = this.def?.label;\n if (typeof label === 'function') btn.textContent = label(ctx.value, ctx.row);\n else btn.textContent = label ?? String(ctx.value ?? 'btn');\n btn.style.cssText = `\n padding:2px 10px;border:1px solid var(--og-primary,#1976d2);\n border-radius:4px;background:var(--og-row-bg,#fff);color:var(--og-primary,#1976d2);\n cursor:pointer;font-size:12px;white-space:nowrap;transition:background 0.12s;\n ${this.def?.style ?? ''}\n `;\n btn.addEventListener('mouseover', () => btn.style.background = 'var(--og-primary-light,#e3f2fd)');\n btn.addEventListener('mouseout', () => btn.style.background = 'var(--og-row-bg,#fff)');\n wrap.appendChild(btn);\n return wrap;\n }\n}\n\n// ─── BadgeRenderer (상태/태그 표시용) ─────────────────────\nexport class BadgeRenderer implements CellRenderer {\n constructor(\n private colorMap?: Record<string, string>,\n private labelMap?: Record<string, string>,\n ) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;height:100%;';\n const badge = document.createElement('span');\n const val = ctx.value == null ? '' : String(ctx.value);\n // labelMap이 있으면 표시 텍스트 변환, 없으면 column.valueMap → 원값 순으로 사용\n const label = this.labelMap?.[val] ?? ctx.column.valueMap?.[val] ?? val;\n badge.textContent = label;\n const color = this.colorMap?.[val] ?? '#666';\n badge.style.cssText = `\n display:inline-block;padding:2px 8px;border-radius:12px;font-size:11px;\n background:${color}22;color:${color};border:1px solid ${color}66;\n white-space:nowrap;\n `;\n wrap.appendChild(badge);\n return wrap;\n }\n}\n\n// ─── LinkRenderer ─────────────────────────────────────────\nexport class LinkRenderer implements CellRenderer {\n constructor(\n private hrefFn?: (value: any, row: any) => string,\n private target?: string,\n ) {}\n\n render(ctx: RenderContext): HTMLElement {\n const a = document.createElement('a');\n a.className = 'og-cell-link';\n a.textContent = ctx.value == null ? '' : String(ctx.value);\n a.href = this.hrefFn ? this.hrefFn(ctx.value, ctx.row) : '#';\n if (this.target) a.target = this.target;\n a.style.cssText = 'color:var(--og-primary,#1976d2);text-decoration:underline;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;';\n if (!this.hrefFn) a.addEventListener('click', e => e.preventDefault());\n return a;\n }\n}\n\n// ─── TemplateRenderer (사용자 정의 HTML) ──────────────────\nexport class TemplateRenderer implements CellRenderer {\n constructor(private templateFn: (value: any, row: any, rowIndex: number) => string) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('div');\n wrap.className = 'og-cell-template';\n wrap.style.cssText = 'display:flex;align-items:center;height:100%;overflow:hidden;';\n wrap.innerHTML = this.templateFn(ctx.value, ctx.row, ctx.rowIndex);\n return wrap;\n }\n}\n\n// ─── ImageRenderer ────────────────────────────────────────\nexport interface ImageRendererDef {\n type: 'image';\n width?: number;\n height?: number;\n radius?: number;\n srcFn?: (value: any, row: any) => string;\n alt?: string | ((value: any, row: any) => string);\n}\n\nexport class ImageRenderer implements CellRenderer {\n constructor(private def?: ImageRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const img = document.createElement('img');\n const src = this.def?.srcFn ? this.def.srcFn(ctx.value, ctx.row) : String(ctx.value ?? '');\n img.src = src;\n const w = this.def?.width ?? 28;\n const h = this.def?.height ?? 28;\n const r = this.def?.radius ?? 4;\n img.style.cssText = `width:${w}px;height:${h}px;object-fit:cover;border-radius:${r}px;display:block;`;\n const alt = this.def?.alt;\n img.alt = typeof alt === 'function' ? alt(ctx.value, ctx.row) : (alt ?? '');\n img.onerror = () => { img.style.display = 'none'; };\n wrap.appendChild(img);\n return wrap;\n }\n}\n\n// ─── ProgressRenderer ─────────────────────────────────────\nexport interface ProgressRendererDef {\n type: 'progress';\n max?: number;\n color?: string;\n showLabel?: boolean;\n colorFn?: (value: number) => string;\n}\n\nexport class ProgressRenderer implements CellRenderer {\n constructor(private def?: ProgressRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;gap:5px;width:100%;padding:0 4px;box-sizing:border-box;';\n const max = this.def?.max ?? 100;\n const raw = Number(ctx.value) || 0;\n const pct = Math.min(100, Math.max(0, (raw / max) * 100));\n const color = this.def?.colorFn\n ? this.def.colorFn(raw)\n : (this.def?.color ?? 'var(--og-primary,#1976d2)');\n\n const track = document.createElement('div');\n track.className = 'og-progress-track';\n track.style.cssText = 'flex:1;height:10px;background:#e0e0e0;border-radius:5px;overflow:hidden;';\n const fill = document.createElement('div');\n fill.className = 'og-progress-fill';\n fill.style.cssText = `width:${pct}%;height:100%;background:${color};border-radius:5px;`;\n track.appendChild(fill);\n wrap.appendChild(track);\n\n if (this.def?.showLabel !== false) {\n const lbl = document.createElement('span');\n lbl.style.cssText = 'font-size:11px;color:#666;white-space:nowrap;min-width:28px;text-align:right;';\n lbl.textContent = `${Math.round(pct)}%`;\n wrap.appendChild(lbl);\n }\n return wrap;\n }\n}\n\n// ─── SparklineRenderer (인라인 미니 차트) ─────────────────\nexport interface SparklineRendererDef {\n type: 'sparkline';\n width?: number;\n height?: number;\n color?: string;\n chartType?: 'bar' | 'line' | 'area';\n}\n\nexport class SparklineRenderer implements CellRenderer {\n constructor(private def?: SparklineRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n\n const values: number[] = Array.isArray(ctx.value) ? ctx.value.map(Number) : [];\n if (!values.length) {\n wrap.textContent = '-';\n return wrap;\n }\n\n const W = this.def?.width ?? 80;\n const H = this.def?.height ?? 22;\n const color = this.def?.color ?? '#1976d2';\n const chartType = this.def?.chartType ?? 'bar';\n\n const canvas = document.createElement('canvas');\n canvas.width = W;\n canvas.height = H;\n canvas.style.cssText = 'display:block;';\n\n const c = canvas.getContext('2d');\n if (c) {\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = max - min || 1;\n const n = values.length;\n\n if (chartType === 'bar') {\n const bw = W / n;\n values.forEach((v, i) => {\n const bh = ((v - min) / range) * (H - 2);\n c.fillStyle = color;\n c.fillRect(i * bw + 1, H - bh - 1, bw - 2, bh);\n });\n } else {\n const pts = values.map((v, i) => ({\n x: (i / (n - 1 || 1)) * W,\n y: H - ((v - min) / range) * (H - 4) - 2,\n }));\n if (chartType === 'area') {\n c.fillStyle = color + '33';\n c.beginPath();\n c.moveTo(pts[0]!.x, H);\n pts.forEach(p => c.lineTo(p.x, p.y));\n c.lineTo(pts[pts.length - 1]!.x, H);\n c.closePath();\n c.fill();\n }\n c.strokeStyle = color;\n c.lineWidth = 1.5;\n c.beginPath();\n pts.forEach((p, i) => (i === 0 ? c.moveTo(p.x, p.y) : c.lineTo(p.x, p.y)));\n c.stroke();\n }\n }\n\n wrap.appendChild(canvas);\n return wrap;\n }\n}\n\n// ─── SwitchRenderer (토글 스위치 표시) ───────────────────\nexport class SwitchRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;';\n const on = !!ctx.value;\n const sw = document.createElement('span');\n sw.className = 'og-switch' + (on ? ' og-switch--on' : '');\n sw.style.cssText = `display:inline-block;width:34px;height:18px;border-radius:9px;\n background:${on ? 'var(--og-primary,#1976d2)' : '#bdbdbd'};\n position:relative;transition:background 0.2s;cursor:pointer;flex-shrink:0;pointer-events:none;`;\n const knob = document.createElement('span');\n knob.style.cssText = `position:absolute;top:2px;left:${on ? '16px' : '2px'};\n width:14px;height:14px;border-radius:50%;background:#fff;\n transition:left 0.2s;box-shadow:0 1px 3px rgba(0,0,0,0.3);`;\n sw.appendChild(knob);\n wrap.appendChild(sw);\n return wrap;\n }\n}\n\n// ─── RatingRenderer (별점 표시) ───────────────────────────\nexport interface RatingRendererDef {\n type: 'rating';\n max?: number;\n color?: string;\n}\n\nexport class RatingRenderer implements CellRenderer {\n constructor(private def?: RatingRendererDef) {}\n\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;gap:1px;height:100%;';\n const max = this.def?.max ?? 5;\n const val = Math.round(Number(ctx.value) || 0);\n const color = this.def?.color ?? '#ffa000';\n for (let i = 1; i <= max; i++) {\n const star = document.createElement('span');\n star.textContent = '★';\n star.style.cssText = `font-size:14px;color:${i <= val ? color : '#e0e0e0'};line-height:1;`;\n wrap.appendChild(star);\n }\n return wrap;\n }\n}\n\n// ─── RadioRenderer ────────────────────────────────────────\nexport class RadioRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;pointer-events:none;';\n const radio = document.createElement('input');\n radio.type = 'radio';\n radio.checked = !!ctx.value;\n radio.setAttribute('aria-checked', ctx.value ? 'true' : 'false');\n radio.setAttribute('aria-label', ctx.column.header ?? '선택');\n if (ctx.column.group) radio.name = `og-radio-${ctx.rowIndex}-${ctx.column.group}`;\n radio.style.cssText = 'width:14px;height:14px;cursor:pointer;accent-color:var(--og-primary,#1976d2);';\n wrap.appendChild(radio);\n return wrap;\n }\n}\n\n// ─── ImgRenderer ──────────────────────────────────────────\nexport class ImgRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:flex;align-items:center;justify-content:center;height:100%;overflow:hidden;';\n if (!ctx.value) return wrap;\n const img = document.createElement('img');\n img.src = String(ctx.value);\n img.alt = (ctx.column as any).alt ?? ctx.column.field;\n img.style.cssText = 'max-width:100%;max-height:100%;object-fit:contain;display:block;';\n img.setAttribute('role', 'img');\n wrap.appendChild(img);\n return wrap;\n }\n}\n\n// ─── HtmlRenderer ─────────────────────────────────────────\nfunction _sanitizeHtml(html: string): string {\n const div = document.createElement('div');\n div.innerHTML = html;\n div.querySelectorAll('script,iframe,object,embed').forEach(el => el.remove());\n div.querySelectorAll('*').forEach(el => {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith('on')) el.removeAttribute(attr.name);\n }\n if (el.tagName === 'A') {\n const href = el.getAttribute('href') ?? '';\n if (/^javascript:/i.test(href)) el.removeAttribute('href');\n }\n });\n return div.innerHTML;\n}\n\nexport class HtmlRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const wrap = document.createElement('span');\n wrap.style.cssText = 'display:block;overflow:hidden;width:100%;';\n const doSanitize = (ctx.column as any).sanitize !== false;\n const html = String(ctx.value ?? '');\n wrap.innerHTML = doSanitize ? _sanitizeHtml(html) : html;\n return wrap;\n }\n}\n\n// ─── BarcodeRenderer (Code128B) ───────────────────────────\nconst _C128W: string[] = [\n '212222','222122','222221','121223','121322','131222','122213','122312', // 0-7\n '132212','221213','221312','231212','112232','122132','122231','113222', // 8-15\n '123122','123221','223211','221132','221231','213212','223112','312131', // 16-23\n '311222','321122','321221','312212','322112','322211','212123','212321', // 24-31\n '232121','111323','131123','131321','112313','132113','132311','211313', // 32-39\n '231113','231311','112133','112331','132131','113123','113321','133121', // 40-47\n '313121','211331','231131','213113','213311','213131','311123','311321', // 48-55\n '331121','312113','312311','332111','314111','221411','431111','111224', // 56-63\n '111422','121124','121421','141122','141221','112214','112412','122114', // 64-71\n '122411','142112','142211','241211','221114','413111','241112','134111', // 72-79\n '111242','121142','121241','114212','124112','124211','411212','421112', // 80-87\n '421211','212141','214121','412121','111143','111341','131141','114113', // 88-95\n '114311','411113','411311','113141','114131','311141','411131','211412', // 96-103\n '211214','211232', // 104 (Start B), 105 (Start C)\n];\nconst _C128_STOP = '2331112';\n\nfunction _c128Bits(w: string): string {\n let out = '', bar = true;\n for (const ch of w) { out += (bar ? '1' : '0').repeat(+ch); bar = !bar; }\n return out;\n}\n\nfunction _encodeC128B(text: string): string {\n const codes: number[] = [104]; // Start B\n for (const ch of text) {\n const c = ch.charCodeAt(0) - 32;\n if (c >= 0 && c <= 94) codes.push(c);\n }\n let sum = 104;\n for (let i = 1; i < codes.length; i++) sum += codes[i]! * i;\n codes.push(sum % 103);\n return codes.map(c => _c128Bits(_C128W[c]!)).join('') + _c128Bits(_C128_STOP) + '11';\n}\n\nexport class BarcodeRenderer implements CellRenderer {\n render(ctx: RenderContext): HTMLElement {\n const val = String(ctx.value ?? '');\n const h = (ctx.column as any).barcodeHeight ?? 28;\n const wrap = document.createElement('div');\n wrap.style.cssText = 'display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;overflow:hidden;gap:1px;';\n wrap.setAttribute('role', 'img');\n wrap.setAttribute('aria-label', `바코드: ${val}`);\n wrap.innerHTML = _barcodeSvg(val, h);\n const label = document.createElement('span');\n label.textContent = val;\n label.style.cssText = 'font-size:9px;font-family:monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;';\n wrap.appendChild(label);\n return wrap;\n }\n}\n\nfunction _barcodeSvg(text: string, H: number): string {\n if (!text) return '';\n const bits = _encodeC128B(text);\n const MW = 1.4, QZ = 6;\n const TW = bits.length * MW + QZ * 2;\n const rects: string[] = [];\n let i = 0, x = QZ;\n while (i < bits.length) {\n if (bits[i] === '1') {\n let n = 0;\n while (i + n < bits.length && bits[i + n] === '1') n++;\n rects.push(`<rect x=\"${x.toFixed(2)}\" y=\"0\" width=\"${(n * MW).toFixed(2)}\" height=\"${H}\"/>`);\n x += n * MW; i += n;\n } else { x += MW; i++; }\n }\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${TW.toFixed(2)} ${H}\" width=\"${TW.toFixed(2)}\" height=\"${H}\" style=\"display:block\" aria-hidden=\"true\"><g fill=\"currentColor\">${rects.join('')}</g></svg>`;\n}\n\n// ─── Renderer 팩토리 ──────────────────────────────────────\nexport function createRenderer(col: ColumnDef): CellRenderer {\n const renderer = col.renderer;\n if (!renderer) {\n switch (col.type as string) {\n case 'number': return new NumberRenderer();\n case 'date': return new DateRenderer();\n case 'boolean': return new CheckboxRenderer();\n case 'radio': return new RadioRenderer();\n case 'img': return new ImgRenderer();\n case 'html': return new HtmlRenderer();\n case 'barcode': return new BarcodeRenderer();\n case 'select': return new SelectRenderer(col.options as any ?? [], col.optionsFn as any);\n default: return new TextRenderer();\n }\n }\n if (typeof renderer === 'string') {\n switch (renderer) {\n case 'number': return new NumberRenderer();\n case 'date': return new DateRenderer();\n case 'checkbox': return new CheckboxRenderer();\n case 'button': return new ButtonRenderer();\n case 'link': return new LinkRenderer();\n case 'badge': return new BadgeRenderer();\n case 'switch': return new SwitchRenderer();\n case 'radio': return new RadioRenderer();\n case 'img': return new ImgRenderer();\n case 'html': return new HtmlRenderer();\n case 'barcode': return new BarcodeRenderer();\n default: return new TextRenderer();\n }\n }\n // RendererDef 객체\n switch (renderer.type) {\n case 'button': return new ButtonRenderer(renderer as ButtonRendererDef);\n case 'checkbox': return new CheckboxRenderer();\n case 'link': return new LinkRenderer(renderer.hrefFn, renderer.target);\n case 'template': return new TemplateRenderer(renderer.templateFn);\n case 'badge': return new BadgeRenderer(renderer.colorMap, renderer.labelMap ?? renderer.valueMap);\n case 'image': return new ImageRenderer(renderer as ImageRendererDef);\n case 'progress': return new ProgressRenderer(renderer as ProgressRendererDef);\n case 'sparkline': return new SparklineRenderer(renderer as SparklineRendererDef);\n case 'switch': return new SwitchRenderer();\n case 'rating': return new RatingRenderer(renderer as RatingRendererDef);\n case 'number': return new NumberRenderer();\n case 'date': return new DateRenderer();\n case 'radio': return new RadioRenderer();\n case 'img': return new ImgRenderer();\n case 'html': return new HtmlRenderer();\n case 'barcode': return new BarcodeRenderer();\n default: return new TextRenderer();\n }\n}\n","import { DataLayer } from './DataLayer.js';\nimport { RowDragDrop } from './RowDragDrop.js';\nimport { MergeEngine } from './MergeEngine.js';\nimport { createRenderer } from './renderers/CellRenderer.js';\nimport type { ColumnDef, SortItem, TreeNodeIconDef } from './types.js';\n\n// ─── RendererCallbacks ────────────────────────────────────\nexport interface RendererCallbacks {\n onHeaderClick: (field: string, shiftKey: boolean) => void;\n onCellClick: (ri: number, ci: number, e: MouseEvent) => void;\n onCellDblClick: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseOver: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseOut: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseDown: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseUp: (ri: number, ci: number, e: MouseEvent) => void;\n onCellMouseMove: (ri: number, ci: number, e: MouseEvent) => void;\n onRowCheck: (ri: number, checked: boolean) => void;\n onAllCheck: (checked: boolean) => void;\n onColResize: (colIndex: number, newWidth: number) => void;\n onFilterIconClick: (field: string, anchorEl: HTMLElement) => void;\n getDndManager: () => RowDragDrop | null;\n onColDragStart: (colIndex: number) => void;\n onColDrop: (toIndex: number) => void;\n getColDragIdx: () => number | null;\n}\n\n// ─── GridRenderer ─────────────────────────────────────────\nexport class GridRenderer {\n private _root: HTMLElement;\n private _header: HTMLElement;\n private _bodyWrap: HTMLElement;\n private _body: HTMLElement;\n private _opts: any;\n private _cbs: RendererCallbacks;\n // rowIndex → {colIndex → cellEl} 맵\n private _cellMap: Map<number, Map<number, HTMLElement>> = new Map();\n\n get bodyWrapper() { return this._bodyWrap; }\n\n constructor(root: HTMLElement, opts: any, cbs: RendererCallbacks) {\n this._root = root;\n this._opts = opts;\n this._cbs = cbs;\n\n this._header = _el('div', 'og-header');\n // host isolation: border:0 로 4변 폭을 먼저 0 으로 못박는다. WordPress 전역 스타일\n // `:where([style*=\"border-color\"]){border-style:solid}` 이 인라인의 var(--og-border-color)\n // 문자열에 매칭되어, 폭 미지정 변에 medium(3px) 기본 보더를 강제하는 것을 차단(헤더 좌/우/상 굵은선 방지).\n this._header.style.cssText = `flex-shrink:0;overflow-x:auto;overflow-y:hidden;border:0;border-bottom:1px solid var(--og-border-color,#e0e0e0);scrollbar-width:none;`;\n\n this._bodyWrap = _el('div', 'og-body-wrapper');\n this._bodyWrap.style.cssText = `flex:1;overflow:auto;position:relative;`;\n this._bodyWrap.style.setProperty('--scrollbar-size', '8px');\n\n this._body = _el('div', 'og-body');\n this._body.style.cssText = `position:relative;`;\n this._bodyWrap.appendChild(this._body);\n\n root.appendChild(this._header);\n root.appendChild(this._bodyWrap);\n\n // 헤더 가로 스크롤 동기화\n this._bodyWrap.addEventListener('scroll', () => {\n this._header.scrollLeft = this._bodyWrap.scrollLeft;\n }, { passive: true });\n }\n\n updateSize(totalHeight: number, headerHeight: number): void {\n this._bodyWrap.style.height = `${totalHeight - headerHeight}px`;\n }\n\n /** 현재 렌더된 헤더 영역의 실제 높이(px). 헤더 줄바꿈으로 늘어난 높이를 레이아웃에 반영할 때 사용. */\n getHeaderHeight(): number {\n return this._header.offsetHeight;\n }\n\n renderHeader(\n headerRows: any[][],\n leaves: ColumnDef[],\n widths: number[],\n sortList: SortItem[],\n opts: any\n ): void {\n this._header.innerHTML = '';\n const frozenCount: number = opts._frozenCount ?? 0;\n\n // 헤더·바디 정렬을 위해 총 컬럼 너비를 계산 — 헤더 table은 이 너비로 고정\n let _extraW = 0;\n if (opts.stateColumn) _extraW += 24;\n if (opts.draggable) _extraW += 18;\n if (opts.rowNumber) _extraW += 44;\n if (opts.checkColumn) _extraW += 36;\n const totalColWidth = _extraW + leaves.reduce((s: number, _: any, i: number) => s + (widths[i] ?? opts.defaultColumnWidth), 0);\n\n // 헤더 div 배경 — 테이블이 totalColWidth보다 짧아도 헤더 영역 전체에 배경 유지\n this._header.style.background = 'var(--og-header-bg,#f5f5f5)';\n\n const table = _el('table', 'og-header-table') as HTMLTableElement;\n table.setAttribute('role', 'presentation');\n // host isolation: margin/border-spacing 을 인라인으로도 0 고정 → 호스트 table{} 차단.\n // (og-header-table 클래스로 base.css 규칙도 적용되나, 인라인으로 이중 방어)\n table.style.cssText = `table-layout:fixed;border-collapse:collapse;border-spacing:0;margin:0;width:${totalColWidth}px;background:var(--og-header-bg,#f5f5f5);`;\n\n // 엑스트라 컬럼 헤더\n const extraRows = headerRows.length;\n let extraHeaderLeft = 0;\n const addExtraCol = (tr: HTMLElement, w: number, label: string, extraClass = '') => {\n const th = _el('th', `og-header-cell og-extra-col ${extraClass}`);\n th.setAttribute('rowspan', String(extraRows));\n th.textContent = label;\n _style(th, {\n width: `${w}px`, minWidth: `${w}px`, textAlign: 'center',\n borderRight: '1px solid var(--og-border-color,#e0e0e0)',\n borderBottom: '1px solid var(--og-border-color,#e0e0e0)',\n // host isolation: extra 컬럼 th 도 호스트 th{} 침범 차단 (border/line-height)\n borderTop: '0', borderLeft: '0', lineHeight: 'normal', verticalAlign: 'middle',\n padding: '0', fontSize: '11px', color: '#999',\n userSelect: 'none', boxSizing: 'border-box',\n background: 'var(--og-header-bg,#f5f5f5)',\n });\n if (frozenCount > 0) {\n th.style.position = 'sticky';\n th.style.left = `${extraHeaderLeft}px`;\n th.style.zIndex = '4';\n }\n extraHeaderLeft += w;\n tr.appendChild(th);\n };\n\n for (let ri = 0; ri < headerRows.length; ri++) {\n const tr = _el('tr', 'og-header-row') as HTMLTableRowElement;\n // 테이블 행의 height 는 사실상 '최소 높이'로 동작한다(내용이 더 크면 행이 늘어남).\n // 따라서 줄바꿈 헤더는 height 를 넘어 자동 확장되고, 줄바꿈 없는 헤더는 기존과 동일하게 유지된다.\n tr.style.height = `${opts.headerHeight}px`;\n\n if (ri === 0) {\n // 컬럼 순서: stateColumn → draggable → rowNumber → checkColumn\n if (opts.stateColumn) addExtraCol(tr, 24, '');\n if (opts.draggable) addExtraCol(tr, 18, '');\n if (opts.rowNumber) addExtraCol(tr, 44, 'No');\n if (opts.checkColumn) {\n const th = _el('th', 'og-header-cell og-extra-col');\n th.setAttribute('rowspan', String(extraRows));\n th.style.cssText = `width:36px;min-width:36px;text-align:center;border-right:1px solid var(--og-border-color,#e0e0e0);border-bottom:1px solid var(--og-border-color,#e0e0e0);border-top:0;border-left:0;line-height:normal;vertical-align:middle;background:var(--og-header-bg,#f5f5f5);box-sizing:border-box;`;\n if (frozenCount > 0) {\n th.style.position = 'sticky';\n th.style.left = `${extraHeaderLeft}px`;\n th.style.zIndex = '4';\n }\n extraHeaderLeft += 36;\n const allChk = document.createElement('input');\n allChk.type = 'checkbox';\n allChk.setAttribute('aria-label', '전체 행 선택');\n allChk.style.cssText = 'width:16px;height:16px;';\n allChk.addEventListener('change', () => this._cbs.onAllCheck(allChk.checked));\n th.appendChild(allChk);\n tr.appendChild(th);\n }\n }\n\n for (const cell of (headerRows[ri] ?? [])) {\n const th = _el('th', 'og-header-cell') as HTMLTableHeaderCellElement;\n const col: ColumnDef = cell.column;\n if (cell.colSpan > 1) th.colSpan = cell.colSpan;\n if (cell.rowSpan > 1) th.rowSpan = cell.rowSpan;\n\n // 너비: leaf 컬럼만\n const leafIdx = cell.colSpan === 1 ? leaves.findIndex(l => l.field === col.field) : -1;\n if (cell.colSpan === 1) {\n const w = leafIdx >= 0 ? (widths[leafIdx] ?? opts.defaultColumnWidth) : (col.width ?? opts.defaultColumnWidth);\n th.style.width = `${w}px`;\n th.style.minWidth = `${w}px`;\n }\n\n const sortInfo = sortList.find(s => s.field === col.field);\n const sortable = col.sortable !== false && opts.sortable && cell.colSpan === 1;\n\n // ARIA + 키보드 접근성\n th.setAttribute('role', 'columnheader');\n th.setAttribute('scope', 'col');\n if (sortable) {\n th.setAttribute('aria-sort', sortInfo ? (sortInfo.dir === 'asc' ? 'ascending' : 'descending') : 'none');\n // 정렬 가능한 헤더는 키보드로 접근 가능 (roving tabindex: 첫 번째만 0)\n th.tabIndex = leafIdx === 0 ? 0 : -1;\n th.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this._cbs.onHeaderClick(col.field, e.shiftKey);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n const next = th.nextElementSibling as HTMLElement;\n if (next?.tagName === 'TH') next.focus();\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n const prev = th.previousElementSibling as HTMLElement;\n if (prev?.tagName === 'TH') prev.focus();\n }\n });\n }\n\n // 고정 컬럼 sticky\n if (leafIdx >= 0 && leafIdx < frozenCount) {\n let leftOff = 0;\n // extra 컬럼 순서와 동일하게: stateColumn → draggable → rowNumber → checkColumn\n if (opts.stateColumn) leftOff += 24;\n if (opts.draggable) leftOff += 18;\n if (opts.rowNumber) leftOff += 44;\n if (opts.checkColumn) leftOff += 36;\n for (let i = 0; i < leafIdx; i++) leftOff += widths[i] ?? opts.defaultColumnWidth;\n th.classList.add('og-frozen');\n if (leafIdx === frozenCount - 1) th.classList.add('og-frozen-last');\n th.style.left = `${leftOff}px`;\n }\n\n // 헤더 줄바꿈 여부: col.headerWrap 또는 header 문자열에 명시적 '\\n' 이 있으면 줄바꿈한다.\n const headerText = col.header ?? col.field;\n const hasExplicitBreak = typeof headerText === 'string' && headerText.indexOf('\\n') >= 0;\n const headerWrap = col.headerWrap === true || hasExplicitBreak;\n\n _style(th, {\n padding: '4px 8px', boxSizing: 'border-box',\n // host isolation: 헤더 <th> 의 모든 시각 속성을 인라인으로 고정한다.\n // 임베드 호스트(WordPress 등)가 `.entry-content th`/`.fn-post-content th`(특이도 0,2,1)로\n // 배경·글자·라인높이·보더·폰트크기를 덮어써도 인라인(최고 우선순위)이 이긴다.\n // (var 참조라 setTheme 시 자동 반영. text-align/padding 은 그리드 의도값 유지)\n background: 'var(--og-header-bg)', color: 'var(--og-header-color)',\n lineHeight: headerWrap ? '1.3' : 'normal', verticalAlign: 'middle',\n fontSize: 'var(--og-font-size)',\n textAlign: col.headerAlign ?? 'center',\n borderTop: '0', borderLeft: '0',\n borderRight: '1px solid var(--og-border-color,#e0e0e0)',\n borderBottom: '1px solid var(--og-border-color,#e0e0e0)',\n userSelect: 'none', cursor: sortable ? 'pointer' : 'default',\n // 줄바꿈 컬럼: nowrap+ellipsis 대신 여러 줄 허용(word-break). 미설정 컬럼은 기존 동작 유지.\n whiteSpace: headerWrap ? 'normal' : 'nowrap',\n overflow: headerWrap ? 'visible' : 'hidden',\n textOverflow: headerWrap ? 'clip' : 'ellipsis',\n wordBreak: headerWrap ? 'break-word' : 'normal',\n position: 'relative',\n });\n\n // 헤더 툴팁: col.tooltip(문자열) 우선, 없으면 헤더 텍스트 — 잘린 헤더 가독성 보조\n th.title = (typeof col.tooltip === 'string' ? col.tooltip : headerText) ?? '';\n\n const label = _el('span');\n if (headerWrap) {\n // 줄바꿈 허용: '\\n' 을 <br> 로 분할 렌더. label 도 nowrap/ellipsis 해제.\n label.style.cssText = 'overflow:visible;text-overflow:clip;white-space:normal;word-break:break-word;';\n const parts = String(headerText).split('\\n');\n parts.forEach((part, i) => {\n if (i > 0) label.appendChild(document.createElement('br'));\n label.appendChild(document.createTextNode(part));\n });\n } else {\n label.textContent = headerText;\n label.style.cssText = 'overflow:hidden;text-overflow:ellipsis;white-space:nowrap;';\n }\n th.appendChild(label);\n\n // 정렬 아이콘\n if (sortInfo) {\n th.classList.add('og-sorted');\n const icon = _el('span', 'og-sort-icon');\n icon.textContent = sortInfo.dir === 'asc' ? ' ↑' : ' ↓';\n th.appendChild(icon);\n }\n\n // 필터 아이콘 (leaf 컬럼 + filterable)\n const filterable = col.filterable !== false && opts.filterable && cell.colSpan === 1;\n if (filterable) {\n const filterIcon = _el('span', 'og-filter-icon');\n const hasFilter = opts._activeFilters?.[col.field]?.length > 0;\n filterIcon.textContent = hasFilter ? '⊿' : '▿';\n filterIcon.title = '필터';\n filterIcon.style.cssText = 'margin-left:3px;cursor:pointer;font-size:10px;opacity:0.6;';\n if (hasFilter) filterIcon.classList.add('og-filter-icon--active');\n filterIcon.addEventListener('click', (e) => {\n e.stopPropagation();\n this._cbs.onFilterIconClick(col.field, filterIcon);\n });\n th.appendChild(filterIcon);\n }\n\n // 컬럼 리사이즈 핸들\n if (col.resizable !== false) {\n const resizer = _el('div', 'og-resize-handle');\n resizer.style.cssText = `position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;z-index:1;`;\n th.appendChild(resizer);\n const capturedLeafIdx = leafIdx;\n _addResizer(resizer, th, (w) => {\n if (capturedLeafIdx >= 0) this._cbs.onColResize(capturedLeafIdx, w);\n });\n }\n\n // 컬럼 드래그 리오더\n if (opts.columnReorder && leafIdx >= 0 && cell.colSpan === 1) {\n th.draggable = true;\n th.addEventListener('dragstart', (e) => {\n this._cbs.onColDragStart(leafIdx);\n th.classList.add('og-col-dragging');\n e.dataTransfer?.setData('text/plain', String(leafIdx));\n });\n th.addEventListener('dragend', () => {\n th.classList.remove('og-col-dragging');\n this._header.querySelectorAll('.og-col-drop-over').forEach(el => el.classList.remove('og-col-drop-over'));\n });\n th.addEventListener('dragover', (e) => {\n e.preventDefault();\n const fromIdx = this._cbs.getColDragIdx();\n if (fromIdx !== null && fromIdx !== leafIdx) {\n this._header.querySelectorAll('.og-col-drop-over').forEach(el => el.classList.remove('og-col-drop-over'));\n th.classList.add('og-col-drop-over');\n }\n });\n th.addEventListener('dragleave', () => {\n th.classList.remove('og-col-drop-over');\n });\n th.addEventListener('drop', (e) => {\n e.preventDefault();\n th.classList.remove('og-col-drop-over');\n this._cbs.onColDrop(leafIdx);\n });\n }\n\n if (sortable) {\n th.addEventListener('click', (e) => {\n if ((e.target as HTMLElement).classList.contains('og-resize-handle')) return;\n this._cbs.onHeaderClick(col.field, e.shiftKey);\n });\n }\n\n tr.appendChild(th);\n }\n table.appendChild(tr);\n }\n this._header.appendChild(table);\n }\n\n renderBody(\n startIndex: number, endIndex: number,\n data: DataLayer<any>,\n leaves: ColumnDef[],\n widths: number[],\n opts: any,\n offsetY: number,\n totalHeight: number,\n selectedRows: Set<number>,\n checkedRows: Set<number>,\n groupFlatRows: Array<any> | null = null,\n onGroupToggle?: (key: string) => void,\n onTreeToggle?: (nodeId: any) => void,\n extraOpts: Record<string, any> = {},\n mergeEngine?: MergeEngine\n ): void {\n // opts에 extraOpts 병합 (DnD _totalRows 등)\n if (Object.keys(extraOpts).length) opts = { ...opts, ...extraOpts };\n this._body.innerHTML = '';\n this._cellMap.clear();\n // autoHeight(비가상): 행을 플로우로 쌓아 높이 자동. 그 외: 고정 rowHeight 절대배치.\n const auto: boolean = opts.autoHeight === true;\n this._body.classList.toggle('og-autoheight', auto);\n this._body.style.height = auto ? '' : `${totalHeight}px`;\n const frozenCount: number = opts._frozenCount ?? 0;\n\n // 바디 최소 너비를 totalColWidth로 설정 — 헤더 table과 너비 동기화 (수평 스크롤 영역 확보)\n {\n let _ew = 0;\n if (opts.stateColumn) _ew += 24;\n if (opts.draggable) _ew += 18;\n if (opts.rowNumber) _ew += 44;\n if (opts.checkColumn) _ew += 36;\n const _totalCW = _ew + leaves.reduce((s: number, _: any, i: number) => s + (widths[i] ?? opts.defaultColumnWidth), 0);\n this._body.style.minWidth = `${_totalCW}px`;\n }\n\n if (endIndex < startIndex) return;\n\n const frag = document.createDocumentFragment();\n for (let ri = startIndex; ri <= endIndex; ri++) {\n // 그룹/트리 모드: flatRow 배열 사용\n const flatItem = groupFlatRows ? groupFlatRows[ri] : null;\n const isGroupRow = flatItem && (flatItem as any)._isGroup === true;\n const isTreeRow = flatItem && (flatItem as any)._isTree === true;\n\n if (isGroupRow) {\n const g = flatItem as any;\n const groupKey = `__${g._groupField}:${g._groupValue}`;\n const rowEl = _el('div', 'og-group-row');\n const top = offsetY + (ri - startIndex) * opts.rowHeight;\n rowEl.style.cssText = [\n auto ? '' : `top:${top}px;height:${opts.rowHeight}px;`,\n 'display:flex;align-items:stretch;cursor:pointer;',\n `padding-left:${4 + g._depth * 12}px;`,\n 'background:var(--og-header-bg,#f5f5f5);',\n // host isolation: border:0 선행 (WP :where([style*=border-color]) 의 3px 강제 차단)\n 'border:0;border-bottom:1px solid var(--og-border-color,#e0e0e0);',\n ].join('');\n rowEl.setAttribute('role', 'row');\n rowEl.setAttribute('aria-expanded', g._expanded ? 'true' : 'false');\n rowEl.setAttribute('aria-rowindex', String(ri + 1));\n rowEl.setAttribute('aria-level', String(g._depth + 1));\n\n // ── extra 컬럼 영역 (stateColumn/draggable/rowNumber/checkColumn) ──────\n let extraW = 0;\n if (opts.stateColumn) extraW += 24;\n if (opts.draggable) extraW += 18;\n if (opts.rowNumber) extraW += 44;\n if (opts.checkColumn) extraW += 36;\n\n // stateColumn 자리: 편집 상태 배지 표시\n if (extraW > 0) {\n const stCell = _el('div', 'og-group-state-cell');\n stCell.style.cssText = [\n `width:${extraW}px;min-width:${extraW}px;flex-shrink:0;`,\n 'display:flex;align-items:center;justify-content:center;',\n 'font-size:10px;font-weight:700;gap:2px;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n ].join('');\n const st = g._states ?? { added: 0, edited: 0, removed: 0 };\n if (st.added > 0) { const b = _el('span'); b.textContent=`+${st.added}`; b.style.cssText='color:var(--og-row-added-bg,#2e7d32);background:#e8f5e9;padding:1px 3px;border-radius:3px;'; stCell.appendChild(b); }\n if (st.edited > 0) { const b = _el('span'); b.textContent=`M${st.edited}`; b.style.cssText='color:#e65100;background:#fff8e1;padding:1px 3px;border-radius:3px;'; stCell.appendChild(b); }\n if (st.removed > 0) { const b = _el('span'); b.textContent=`D${st.removed}`; b.style.cssText='color:var(--og-row-removed-bg,#c62828);background:#ffebee;padding:1px 3px;border-radius:3px;'; stCell.appendChild(b); }\n rowEl.appendChild(stCell);\n }\n\n // ── 컬럼별 셀 ─────────────────────────────────────────────────────────\n let labelPlaced = false;\n for (let ci = 0; ci < leaves.length; ci++) {\n const col = leaves[ci]!;\n const w = widths[ci] ?? opts.defaultColumnWidth;\n const hasSummary = g._summaryFmt !== undefined && col.field in (g._summaryFmt ?? {});\n\n const cell = _el('div', 'og-group-cell');\n cell.style.cssText = [\n `width:${w}px;min-width:${w}px;flex-shrink:0;`,\n 'padding:2px 8px;box-sizing:border-box;overflow:hidden;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n 'display:flex;align-items:center;',\n 'white-space:nowrap;text-overflow:ellipsis;',\n ].join('');\n\n if (hasSummary) {\n // 소계 값 — 숫자 컬럼은 우측 정렬\n const fmt = g._summaryFmt[col.field];\n cell.textContent = fmt !== '' ? fmt : '-';\n cell.style.justifyContent = 'flex-end';\n cell.style.color = 'var(--og-primary,#1976d2)';\n cell.style.fontWeight = '600';\n } else if (!labelPlaced) {\n // 맨 첫 번째 비-소계 컬럼에 그룹 레이블 배치\n labelPlaced = true;\n const arrow = _el('span', 'og-group-arrow');\n arrow.textContent = g._expanded ? '▾ ' : '▸ ';\n arrow.style.cssText = 'color:var(--og-primary,#1976d2);margin-right:4px;flex-shrink:0;';\n cell.appendChild(arrow);\n\n const lbl = _el('span', 'og-group-label');\n lbl.textContent = `${g._groupLabel} (${g._childCount}건)`;\n lbl.style.cssText = 'overflow:hidden;text-overflow:ellipsis;font-weight:600;';\n cell.appendChild(lbl);\n cell.style.gap = '0';\n }\n // 소계도 없고 첫 번째도 아닌 열: 빈 셀 (간격 유지)\n\n rowEl.appendChild(cell);\n }\n\n rowEl.addEventListener('click', () => onGroupToggle?.(groupKey));\n frag.appendChild(rowEl);\n continue;\n }\n\n // 일반 데이터 행 (트리 노드 포함)\n const treeNode: any | null = isTreeRow ? (flatItem as any) : null;\n const rowData = treeNode ? treeNode.data : (groupFlatRows ? flatItem : data.getRowByIndex(ri));\n if (!rowData) continue;\n const rowState = (isTreeRow || isGroupRow) ? 'none' : data.getRowState(ri);\n\n const rowEl = _el('div', 'og-row');\n rowEl.setAttribute('role', 'row');\n rowEl.setAttribute('aria-rowindex', String(ri + 1));\n if (!auto) {\n const top = offsetY + (ri - startIndex) * opts.rowHeight;\n rowEl.style.top = `${top}px`;\n rowEl.style.height = `${opts.rowHeight}px`;\n }\n\n // 교차 행 배경 — 가상스크롤에서 :nth-child는 DOM 위치 기반이라 ri 기준으로 인라인 설정\n let bg = ri % 2 === 0 ? 'var(--og-row-bg,#fff)' : 'var(--og-row-alt-bg,#fafafa)';\n rowEl.style.background = bg;\n\n // 상태/선택 CSS 클래스 부착 — !important 로 인라인 background 오버라이드\n if (rowState === 'added') rowEl.classList.add('og-state-added');\n if (rowState === 'edited') rowEl.classList.add('og-state-edited');\n if (rowState === 'removed') rowEl.classList.add('og-state-removed');\n if (selectedRows.has(ri)) rowEl.classList.add('og-selected');\n rowEl.setAttribute('aria-selected', selectedRows.has(ri) ? 'true' : 'false');\n\n // frozen 셀 배경용 bg — 상태행은 상태 색으로 덮어쓰기\n if (rowState === 'added') bg = 'var(--og-row-added-bg,#e8f5e9)';\n if (rowState === 'edited') bg = 'var(--og-row-edited-bg,#fff8e1)';\n if (rowState === 'removed') bg = 'var(--og-row-removed-bg,#ffebee)';\n if (selectedRows.has(ri)) bg = 'var(--og-row-selected-bg,#bbdefb)';\n\n // 행 레벨 클릭 (rowNumber·stateColumn 등 extra 컬럼 포함) → 선택 처리\n const localRowRi = ri;\n rowEl.addEventListener('click', (e) => { this._cbs.onCellClick(localRowRi, -1, e); });\n\n const colMap = new Map<number, HTMLElement>();\n\n // extra 컬럼 순서: stateColumn → draggable → rowNumber → checkColumn\n let extraBodyLeft = 0;\n\n // 상태 컬럼 (맨 앞)\n if (opts.stateColumn) {\n const stCell = _el('div', 'og-cell og-col-state');\n const icons: Record<string, string> = { added: '✚', edited: '✎', removed: '✖', none: '' };\n const colors: Record<string, string> = { added: '#2e7d32', edited: '#bf360c', removed: '#c62828', none: '' };\n stCell.textContent = icons[rowState] ?? '';\n stCell.style.color = colors[rowState] ?? '';\n stCell.title = rowState;\n if (frozenCount > 0) {\n stCell.style.position = 'sticky';\n stCell.style.left = `${extraBodyLeft}px`;\n stCell.style.zIndex = '2';\n stCell.style.background = bg;\n }\n extraBodyLeft += 24;\n rowEl.appendChild(stCell);\n }\n\n // 드래그 핸들\n const dnd = this._cbs.getDndManager();\n if (opts.draggable && dnd) {\n const handle = dnd.attachHandle(rowEl, ri, opts._totalRows ?? endIndex + 1);\n if (frozenCount > 0) {\n handle.style.position = 'sticky';\n handle.style.left = `${extraBodyLeft}px`;\n handle.style.zIndex = '2';\n handle.style.background = bg;\n }\n extraBodyLeft += 18;\n rowEl.appendChild(handle);\n }\n\n // 행 번호 컬럼\n if (opts.rowNumber) {\n const numCell = _el('div', 'og-cell og-col-rownum');\n numCell.textContent = String(ri + 1);\n if (frozenCount > 0) {\n numCell.style.position = 'sticky';\n numCell.style.left = `${extraBodyLeft}px`;\n numCell.style.zIndex = '2';\n numCell.style.background = bg;\n }\n extraBodyLeft += 44;\n rowEl.appendChild(numCell);\n }\n\n // 체크박스 컬럼\n if (opts.checkColumn) {\n const chkCell = _el('div', 'og-cell og-col-check');\n const chk = document.createElement('input');\n chk.type = 'checkbox';\n chk.checked = checkedRows.has(ri);\n chk.setAttribute('aria-label', `${ri + 1}행 선택`);\n chk.addEventListener('click', (e) => e.stopPropagation());\n chk.addEventListener('change', (e) => {\n e.stopPropagation();\n this._cbs.onRowCheck(ri, chk.checked);\n });\n chkCell.appendChild(chk);\n if (frozenCount > 0) {\n chkCell.style.position = 'sticky';\n chkCell.style.left = `${extraBodyLeft}px`;\n chkCell.style.zIndex = '2';\n chkCell.style.background = bg;\n }\n extraBodyLeft += 36;\n rowEl.appendChild(chkCell);\n }\n\n // 데이터 컬럼\n for (let ci = 0; ci < leaves.length; ci++) {\n const col = leaves[ci]!;\n const w = widths[ci] ?? opts.defaultColumnWidth;\n const isEditable = opts.editable && col.editable !== false;\n const isFirstCol = ci === 0;\n\n // 셀 병합 처리\n const mergeInfo = mergeEngine && !mergeEngine.isEmpty\n ? mergeEngine.getInfo(ri, ci)\n : null;\n if (mergeInfo?.hidden) {\n // 병합 하위 셀: flex 공간만 차지하는 투명 placeholder (컬럼 정렬 보존)\n const ph = _el('div', 'og-cell og-cell--merge-ph');\n ph.style.cssText = `width:${w}px;min-width:${w}px;flex-shrink:0;visibility:hidden;box-sizing:border-box;`;\n rowEl.appendChild(ph);\n continue;\n }\n\n const cellEl = _el('div', 'og-cell');\n cellEl.setAttribute('role', 'gridcell');\n cellEl.setAttribute('aria-colindex', String(ci + 1));\n\n // rowSpan 적용: 여러 행 높이만큼 절대 위치로 늘림\n const rs = mergeInfo?.rowSpan ?? 1;\n const cs = mergeInfo?.colSpan ?? 1;\n const mergedHeight = rs > 1 ? rs * opts.rowHeight : opts.rowHeight;\n // colSpan 시 width 합산\n let mergedWidth = w;\n if (cs > 1) {\n for (let dc = 1; dc < cs; dc++) {\n mergedWidth += widths[ci + dc] ?? opts.defaultColumnWidth;\n }\n }\n\n const hPad = treeNode && isFirstCol ? 0 : 8;\n\n // 고정 컬럼 sticky\n const isFrozenCell = ci < frozenCount;\n let frozenLeftOff = 0;\n if (isFrozenCell) {\n // extra 컬럼 순서: stateColumn → draggable → rowNumber → checkColumn\n if (opts.stateColumn) frozenLeftOff += 24;\n if (opts.draggable) frozenLeftOff += 18;\n if (opts.rowNumber) frozenLeftOff += 44;\n if (opts.checkColumn) frozenLeftOff += 36;\n for (let i = 0; i < ci; i++) frozenLeftOff += widths[i] ?? opts.defaultColumnWidth;\n cellEl.classList.add('og-frozen-cell');\n if (ci === frozenCount - 1) cellEl.classList.add('og-frozen-last');\n }\n\n // frozen 셀: sticky 특성상 배경 필요 → bg 적용. 일반 셀: 행에서 상속\n const cellBg = isFrozenCell ? bg : 'inherit';\n cellEl.style.width = `${mergedWidth}px`;\n cellEl.style.minWidth = `${mergedWidth}px`;\n cellEl.style.maxWidth = `${mergedWidth}px`;\n if (rs > 1) cellEl.style.height = `${mergedHeight}px`;\n if (isFrozenCell) cellEl.style.background = bg;\n if (treeNode && isFirstCol) cellEl.style.padding = '0';\n cellEl.style.overflow = 'hidden';\n if (rs > 1) {\n // rowSpan 마스터셀: body 기준 absolute 위치 (flex flow 밖)\n cellEl.style.height = `${mergedHeight}px`;\n cellEl.style.position = 'absolute';\n cellEl.style.zIndex = '3';\n // 마스터셀에 명시적 배경색 필요(하단 행 덮기)\n cellEl.style.background = (bg && bg !== 'inherit') ? bg : 'var(--og-row-bg, #fff)';\n // host isolation: 미지정 변 폭 0 명시 (WP :where([style*=border-color]) 의 3px 강제 차단)\n cellEl.style.borderTop = '0';\n cellEl.style.borderLeft = '0';\n cellEl.style.borderBottom = `1px solid var(--og-border-color, #e0e0e0)`;\n } else if (isFrozenCell) {\n cellEl.style.position = 'sticky';\n cellEl.style.left = `${frozenLeftOff}px`;\n cellEl.style.zIndex = '1';\n }\n if (col.type === 'number' || col.align === 'right') cellEl.classList.add('og-cell--right');\n else if (col.align === 'center') cellEl.classList.add('og-cell--center');\n if (isEditable) cellEl.classList.add('og-cell--editable');\n // 줄바꿈(wrap): nowrap+ellipsis 대신 여러 줄 표시 (rowHeight를 키워 함께 사용)\n if (col.wrap) cellEl.classList.add('og-cell--wrap');\n\n // ── ARIA + 포커스 셀 ───────────────────────\n if (!isEditable) cellEl.setAttribute('aria-readonly', 'true');\n if (cs > 1) cellEl.setAttribute('aria-colspan', String(cs));\n if (rs > 1) cellEl.setAttribute('aria-rowspan', String(rs));\n // 포커스 셀 표시 (og-cell-focused 클래스 + tabIndex for programmatic focus)\n const isFocused = opts._focusCell?.ri === ri && opts._focusCell?.ci === ci;\n if (isFocused) {\n cellEl.classList.add('og-cell-focused');\n cellEl.tabIndex = -1;\n }\n // 셀 접근성 레이블 (헤더명: 값)\n const _rawVal = rowData ? rowData[col.field] : null;\n cellEl.setAttribute('aria-label', `${col.header}: ${_rawVal == null ? '' : String(_rawVal)}`);\n\n // 툴팁(native title): col.tooltip(문자열|함수) 우선, 없고 opts.tooltips 면 셀 값 자동 노출\n if (col.tooltip != null) {\n cellEl.title = typeof col.tooltip === 'function'\n ? String(col.tooltip(_rawVal, rowData as any) ?? '')\n : String(col.tooltip);\n } else if (opts.tooltips && _rawVal != null && _rawVal !== '') {\n cellEl.title = String(_rawVal);\n }\n\n // ── 트리 첫 컬럼: 탐색기 스타일 렌더링 ──────────────\n let _treeRenderTarget: HTMLElement = cellEl;\n\n if (treeNode && isFirstCol) {\n const treeCell = _el('div', 'og-tree-cell');\n\n // ① 조상 가이드 라인 (│ or 空白) — 깊이만큼 반복\n const hasMoreChain: boolean[] = treeNode._ancestorHasMore ?? [];\n for (let d = 0; d < treeNode._depth; d++) {\n const guide = _el('span', 'og-tree-guide');\n if (hasMoreChain[d]) guide.classList.add('og-tree-guide--line');\n treeCell.appendChild(guide);\n }\n\n // ② 연결선 (depth > 0 만) : ├─ 또는 └─\n if (treeNode._depth > 0) {\n const conn = _el('span', 'og-tree-connector');\n conn.classList.add(\n treeNode._isLastChild ? 'og-tree-connector--last' : 'og-tree-connector--mid'\n );\n treeCell.appendChild(conn);\n }\n\n // ③ 토글 래퍼 — branch: 정렬 스페이서(빈 칸), leaf: 원형 점\n const toggleWrap = _el('span', 'og-tree-toggle-wrap');\n if (!treeNode._hasChildren) {\n const dot = _el('span', 'og-tree-leaf-dot');\n toggleWrap.appendChild(dot);\n }\n treeCell.appendChild(toggleWrap);\n\n // ④ 노드 아이콘 — branch: 폴더(클릭 토글), leaf: 파일\n const nodeIcon = document.createElement('i');\n if (treeNode._hasChildren) {\n const iconCls = _resolveTreeIcon(col.treeNodeIcon, rowData, true, treeNode._expanded);\n nodeIcon.className = treeNode._expanded\n ? `${iconCls} og-tree-node-icon og-tree-node-icon--branch og-tree-node-icon--open og-tree-node-icon--toggle`\n : `${iconCls} og-tree-node-icon og-tree-node-icon--branch og-tree-node-icon--toggle`;\n nodeIcon.setAttribute('role', 'button');\n nodeIcon.setAttribute('tabindex', '0');\n nodeIcon.setAttribute('aria-expanded', treeNode._expanded ? 'true' : 'false');\n nodeIcon.setAttribute('aria-label', treeNode._expanded ? '접기' : '펼치기');\n nodeIcon.addEventListener('click', (e: MouseEvent) => {\n e.stopPropagation();\n onTreeToggle?.(treeNode._treeId);\n });\n nodeIcon.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n onTreeToggle?.(treeNode._treeId);\n }\n });\n } else {\n const iconCls = _resolveTreeIcon(col.treeNodeIcon, rowData, false, false);\n nodeIcon.setAttribute('aria-hidden', 'true');\n nodeIcon.className = `${iconCls} og-tree-node-icon og-tree-node-icon--leaf`;\n }\n treeCell.appendChild(nodeIcon);\n\n cellEl.appendChild(treeCell);\n _treeRenderTarget = treeCell;\n }\n\n // 사용자 정의 cellStyle\n if (col.cellStyle) {\n const val = rowData[col.field];\n const s = typeof col.cellStyle === 'function' ? col.cellStyle(val, rowData as any, ri) : col.cellStyle;\n Object.assign(cellEl.style, s);\n }\n\n // 렌더러 사용 — 트리 첫 컬럼은 treeCell 안에 추가, 그 외는 cellEl에 추가\n const renderer = createRenderer(col);\n const rendered = renderer.render({\n value: rowData[col.field], row: rowData, rowIndex: ri,\n column: col as any, colIndex: ci,\n isSelected: selectedRows.has(ri), rowState\n });\n _treeRenderTarget.appendChild(rendered);\n\n // 이벤트\n const localRi = ri, localCi = ci;\n cellEl.addEventListener('click', (e) => { e.stopPropagation(); this._cbs.onCellClick(localRi, localCi, e); });\n cellEl.addEventListener('dblclick', (e) => { e.stopPropagation(); this._cbs.onCellDblClick(localRi, localCi, e); });\n cellEl.addEventListener('mouseover', (e) => { e.stopPropagation(); this._cbs.onCellMouseOver(localRi, localCi, e); });\n cellEl.addEventListener('mouseout', (e) => { e.stopPropagation(); this._cbs.onCellMouseOut(localRi, localCi, e); });\n cellEl.addEventListener('mousedown', (e) => { e.stopPropagation(); this._cbs.onCellMouseDown(localRi, localCi, e); });\n cellEl.addEventListener('mouseup', (e) => { e.stopPropagation(); this._cbs.onCellMouseUp(localRi, localCi, e); });\n cellEl.addEventListener('mousemove', (e) => { e.stopPropagation(); this._cbs.onCellMouseMove(localRi, localCi, e); });\n\n colMap.set(ci, cellEl);\n\n if (rs > 1) {\n // ① 마스터 행의 flex에 투명 placeholder 삽입 → 컬럼 너비 보존\n const ph = document.createElement('div');\n ph.style.cssText = [\n `width:${w}px;min-width:${w}px;height:${opts.rowHeight}px;`,\n 'flex-shrink:0;box-sizing:border-box;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n ].join('');\n rowEl.appendChild(ph);\n\n // ② 마스터셀은 body 기준 absolute — top/left 정밀 계산\n let leftOff = 0;\n if (opts.stateColumn) leftOff += 24;\n if (opts.draggable) leftOff += 18;\n if (opts.rowNumber) leftOff += 44;\n if (opts.checkColumn) leftOff += 36;\n for (let pc = 0; pc < ci; pc++) leftOff += widths[pc] ?? opts.defaultColumnWidth;\n const rowTop = offsetY + (ri - startIndex) * opts.rowHeight;\n cellEl.style.left = `${leftOff}px`;\n cellEl.style.top = `${rowTop}px`;\n frag.appendChild(cellEl); // rowEl이 아닌 body 레벨에 직접 부착\n } else {\n rowEl.appendChild(cellEl);\n }\n }\n\n this._cellMap.set(ri, colMap);\n frag.appendChild(rowEl);\n }\n\n // 빈 데이터 메시지\n if (data.rowCount === 0) {\n const empty = _el('div', 'og-empty-message');\n empty.textContent = '데이터가 없습니다.';\n empty.style.cssText = `width:100%;`;\n frag.appendChild(empty);\n }\n\n this._body.appendChild(frag);\n }\n\n getCellEl(rowIndex: number, colIndex: number): HTMLElement | undefined {\n return this._cellMap.get(rowIndex)?.get(colIndex);\n }\n\n destroy(): void {\n this._root.innerHTML = '';\n }\n}\n\n// ─── 트리 노드 아이콘 해석 ────────────────────────────────\nfunction _resolveTreeIcon(\n def: TreeNodeIconDef | ((row: Record<string, any>, hasChildren: boolean, expanded: boolean) => string) | undefined,\n row: Record<string, any>,\n hasChildren: boolean,\n expanded: boolean\n): string {\n let icon: string;\n if (!def) {\n icon = hasChildren ? (expanded ? 'bi-folder2-open' : 'bi-folder2') : 'bi-file-earmark';\n } else if (typeof def === 'function') {\n icon = def(row, hasChildren, expanded);\n } else {\n if (hasChildren) {\n icon = expanded ? (def.branchOpen ?? 'bi-folder2-open') : (def.branch ?? 'bi-folder2');\n } else {\n icon = def.leaf ?? 'bi-file-earmark';\n }\n }\n return icon.startsWith('bi ') ? icon : `bi ${icon}`;\n}\n\n// ─── DOM 유틸 ─────────────────────────────────────────────\nexport function _el(tag: string, className?: string): HTMLElement {\n const e = document.createElement(tag);\n if (className) e.className = className;\n return e;\n}\n\nexport function _style(el: HTMLElement, styles: Partial<CSSStyleDeclaration>): void {\n Object.assign(el.style, styles);\n}\n\nexport function _downloadText(content: string, filename: string, mime = 'text/plain;charset=utf-8'): void {\n const blob = new Blob([content], { type: mime });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url; a.download = filename; a.click();\n URL.revokeObjectURL(url);\n}\n\n// ─── 컬럼 리사이즈 헬퍼 ──────────────────────────────────\nfunction _addResizer(handle: HTMLElement, th: HTMLElement, onChange: (w: number) => void): void {\n let startX = 0, startW = 0;\n\n handle.addEventListener('mousedown', (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n startX = e.clientX;\n startW = th.offsetWidth;\n\n const onMove = (ev: MouseEvent) => {\n const w = Math.max(40, startW + ev.clientX - startX);\n th.style.width = `${w}px`;\n th.style.minWidth = `${w}px`;\n };\n const onUp = (ev: MouseEvent) => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n onChange(Math.max(40, startW + ev.clientX - startX));\n };\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n });\n}\n","import { DataLayer } from './DataLayer.js';\n\nexport class RowManager<T extends Record<string, any> = any> {\n private _selectedRows: Set<number> = new Set();\n private _checkedRows: Set<number> = new Set();\n private _data: DataLayer<T>;\n\n constructor(data: DataLayer<T>) {\n this._data = data;\n }\n\n // ─── Read-only 접근 ───────────────────────────────────────\n get selectedRows(): Set<number> { return this._selectedRows; }\n get checkedRows(): Set<number> { return this._checkedRows; }\n\n // ─── 선택 변경 ───────────────────────────────────────────\n selectSingle(ri: number): void {\n this._selectedRows.clear();\n this._selectedRows.add(ri);\n }\n\n selectToggle(ri: number): void {\n if (this._selectedRows.has(ri)) this._selectedRows.delete(ri);\n else this._selectedRows.add(ri);\n }\n\n clearSelection(): void { this._selectedRows.clear(); }\n\n // ─── 체크 변경 ───────────────────────────────────────────\n check(ri: number, checked: boolean): void {\n if (checked) this._checkedRows.add(ri);\n else this._checkedRows.delete(ri);\n }\n\n checkAll(checked: boolean, totalRows: number): void {\n if (checked) {\n for (let i = 0; i < totalRows; i++) this._checkedRows.add(i);\n } else {\n this._checkedRows.clear();\n }\n }\n\n checkByValue(field: string, values: any[]): void {\n for (let i = 0; i < this._data.rowCount; i++) {\n if (values.includes(this._data.getCellValue(i, field))) this._checkedRows.add(i);\n }\n }\n\n uncheckAll(): void { this._checkedRows.clear(); }\n\n checkById(_ids: string[]): void {}\n addCheckById(_ids: string[]): void {}\n uncheckById(_ids: string[]): void {}\n\n // ─── 선택 쿼리 API ───────────────────────────────────────\n getSelections(): T[] {\n return [...this._selectedRows]\n .map(i => this._data.getRowByIndex(i))\n .filter(Boolean) as T[];\n }\n\n getChecked(): Array<{ row: T; rowIndex: number }> {\n return [...this._checkedRows].map(i => ({\n row: this._data.getRowByIndex(i) as T,\n rowIndex: i,\n }));\n }\n\n getAllChecked(): T[] { return this.getChecked().map(r => r.row); }\n\n getActiveRow(): number {\n return this._selectedRows.size > 0 ? [...this._selectedRows][0]! : -1;\n }\n\n activate(index: number): void {\n this._selectedRows.clear();\n this._selectedRows.add(index);\n }\n\n deselect(): void { this._selectedRows.clear(); }\n\n // ─── 전체 초기화 (setData / clearData 시) ────────────────\n reset(): void {\n this._selectedRows.clear();\n this._checkedRows.clear();\n }\n}\n","import type { CellEditor } from './CellEditor.js';\nimport type { RenderContext } from '../renderers/CellRenderer.js';\nimport { formatDate } from '../renderers/CellRenderer.js';\n\nexport class DateEditor implements CellEditor {\n private input!: HTMLInputElement;\n private _container!: HTMLElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._container = container;\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n container.setAttribute('aria-haspopup', 'dialog');\n container.setAttribute('aria-expanded', 'true');\n\n this.input = document.createElement('input');\n this.input.type = 'date';\n this.input.className = 'og-cell-input';\n this.input.setAttribute('aria-label', ctx.column.header ?? '날짜 선택');\n\n const raw = ctx.value;\n if (raw) {\n const d = raw instanceof Date ? raw : new Date(raw);\n if (!isNaN(d.getTime())) {\n this.input.value = formatDate(d, 'yyyy-MM-dd');\n }\n }\n\n this.input.addEventListener('keydown', this._onKeyDown);\n this.input.addEventListener('blur', this._onBlur);\n container.appendChild(this.input);\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n e.stopPropagation();\n if (e.key === 'Enter') { e.preventDefault(); this._onCommit(this.input.value); }\n else if (e.key === 'Escape') this._onCancel();\n };\n\n private _onBlur = (): void => { this._onCommit(this.input.value); };\n\n getValue(): any { return this.input?.value; }\n focus(): void { this.input?.focus(); }\n\n destroy(): void {\n this._container?.setAttribute('aria-expanded', 'false');\n this.input?.removeEventListener('keydown', this._onKeyDown);\n this.input?.removeEventListener('blur', this._onBlur);\n }\n}\n","import type { CellEditor } from './CellEditor.js';\nimport type { RenderContext } from '../renderers/CellRenderer.js';\n\nexport type SelectOption = string | { label?: string; text?: string; value: any };\n\nfunction normalizeOptions(raw: SelectOption[]): Array<{ label: string; value: any }> {\n return raw.map(o => {\n if (typeof o === 'string') return { label: o, value: o };\n const label = (o as any).label ?? (o as any).text ?? String((o as any).value ?? '');\n return { label, value: (o as any).value };\n });\n}\n\nexport class SelectEditor implements CellEditor {\n private select!: HTMLSelectElement;\n private _container!: HTMLElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n private _options: Array<{ label: string; value: any }>;\n private _optionsFn: ((row: any, rowIndex: number) => SelectOption[]) | null;\n\n constructor(\n options: SelectOption[] = [],\n optionsFn?: (row: any, rowIndex: number) => SelectOption[]\n ) {\n this._options = normalizeOptions(options);\n this._optionsFn = optionsFn ?? null;\n }\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._container = container;\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n container.setAttribute('aria-haspopup', 'listbox');\n container.setAttribute('aria-expanded', 'true');\n\n this.select = document.createElement('select');\n this.select.className = 'og-cell-select';\n this.select.setAttribute('aria-label', ctx.column.header ?? '선택');\n\n const resolved = this._optionsFn\n ? normalizeOptions(this._optionsFn(ctx.row, ctx.rowIndex))\n : this._options;\n\n for (const opt of resolved) {\n const el = document.createElement('option');\n el.value = String(opt.value);\n el.textContent = opt.label;\n this.select.appendChild(el);\n }\n\n const cur = ctx.value == null ? '' : String(ctx.value);\n if (resolved.some(o => String(o.value) === cur)) this.select.value = cur;\n\n this.select.addEventListener('change', () => onCommit(this.select.value));\n this.select.addEventListener('blur', () => onCommit(this.select.value));\n this.select.addEventListener('keydown', (e) => { if (e.key === 'Escape') onCancel(); });\n container.appendChild(this.select);\n }\n\n getValue(): any { return this.select?.value; }\n focus(): void { this.select?.focus(); }\n\n destroy(): void {\n this._container?.setAttribute('aria-expanded', 'false');\n }\n}\n","import type { ColumnDef } from '../types.js';\nimport type { RenderContext } from '../renderers/CellRenderer.js';\nexport { DateEditor } from './DateEditor.js';\nexport { SelectEditor } from './SelectEditor.js';\nimport { DateEditor } from './DateEditor.js';\nimport { SelectEditor } from './SelectEditor.js';\n\nexport interface EditorResult {\n committed: boolean;\n value: any;\n}\n\nexport interface CellEditor {\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (value: any) => void, onCancel: () => void): void;\n getValue(): any;\n focus(): void;\n destroy(): void;\n}\n\n// ─── TextEditor ───────────────────────────────────────────\nexport class TextEditor implements CellEditor {\n private input!: HTMLInputElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n this.input = document.createElement('input');\n this.input.type = 'text';\n this.input.value = ctx.value == null ? '' : String(ctx.value);\n this.input.style.cssText = `\n width:100%;height:100%;border:none;outline:none;padding:0 8px;\n font-size:var(--og-font-size,13px);font-family:var(--og-font-family,sans-serif);\n background:var(--og-row-bg,#fff);box-sizing:border-box;\n `;\n\n this.input.addEventListener('keydown', this._onKeyDown);\n this.input.addEventListener('blur', this._onBlur);\n container.appendChild(this.input);\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n e.stopPropagation();\n if (e.key === 'Enter' || e.key === 'Tab') {\n e.preventDefault();\n this._onCommit(this.input.value);\n } else if (e.key === 'Escape') {\n this._onCancel();\n }\n };\n\n private _onBlur = (): void => {\n this._onCommit(this.input.value);\n };\n\n getValue(): any { return this.input?.value; }\n\n focus(): void {\n this.input?.focus();\n this.input?.select();\n }\n\n destroy(): void {\n this.input?.removeEventListener('keydown', this._onKeyDown);\n this.input?.removeEventListener('blur', this._onBlur);\n }\n}\n\n// ─── NumberEditor ─────────────────────────────────────────\nexport class NumberEditor implements CellEditor {\n private input!: HTMLInputElement;\n private _onCommit!: (v: any) => void;\n private _onCancel!: () => void;\n private min: number | undefined;\n private max: number | undefined;\n private step: number | undefined;\n\n constructor(opts?: { min?: number; max?: number; step?: number }) {\n this.min = opts?.min;\n this.max = opts?.max;\n this.step = opts?.step;\n }\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, onCancel: () => void): void {\n this._onCommit = onCommit;\n this._onCancel = onCancel;\n\n this.input = document.createElement('input');\n this.input.type = 'number';\n this.input.value = ctx.value == null ? '' : String(ctx.value);\n if (this.min != null) this.input.min = String(this.min);\n if (this.max != null) this.input.max = String(this.max);\n if (this.step != null) this.input.step = String(this.step);\n this.input.style.cssText = `\n width:100%;height:100%;border:none;outline:none;padding:0 8px;\n font-size:var(--og-font-size,13px);text-align:right;\n background:var(--og-row-bg,#fff);box-sizing:border-box;\n `;\n this.input.addEventListener('keydown', this._onKeyDown);\n this.input.addEventListener('blur', this._onBlur);\n container.appendChild(this.input);\n }\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n e.stopPropagation();\n if (e.key === 'Enter' || e.key === 'Tab') { e.preventDefault(); this._commit(); }\n else if (e.key === 'Escape') this._onCancel();\n };\n\n private _onBlur = (): void => { this._commit(); };\n\n private _commit(): void {\n const v = this.input.value === '' ? null : Number(this.input.value);\n this._onCommit(v);\n }\n\n getValue(): any { return this.input?.value === '' ? null : Number(this.input?.value); }\n focus(): void { this.input?.focus(); this.input?.select(); }\n destroy(): void {\n this.input?.removeEventListener('keydown', this._onKeyDown);\n this.input?.removeEventListener('blur', this._onBlur);\n }\n}\n\n\n// ─── CheckboxEditor ───────────────────────────────────────\nexport class CheckboxEditor implements CellEditor {\n private chk!: HTMLInputElement;\n private _onCommit!: (v: any) => void;\n\n mount(container: HTMLElement, ctx: RenderContext, onCommit: (v: any) => void, _onCancel: () => void): void {\n this._onCommit = onCommit;\n container.style.cssText += 'display:flex;align-items:center;justify-content:center;';\n\n this.chk = document.createElement('input');\n this.chk.type = 'checkbox';\n this.chk.checked = !!ctx.value;\n this.chk.style.cursor = 'pointer';\n this.chk.addEventListener('change', () => onCommit(this.chk.checked));\n container.appendChild(this.chk);\n }\n\n getValue(): any { return this.chk?.checked; }\n focus(): void { this.chk?.focus(); }\n destroy(): void {}\n}\n\n// ─── Editor 팩토리 ────────────────────────────────────────\nexport function createEditor(col: ColumnDef): CellEditor {\n const editor = col.editor;\n if (!editor) {\n switch (col.type as string) {\n case 'number': return new NumberEditor();\n case 'date': return new DateEditor();\n case 'boolean': return new CheckboxEditor();\n case 'select': return new SelectEditor(col.options ?? [], col.optionsFn as any);\n default: return new TextEditor();\n }\n }\n if (typeof editor === 'string') {\n switch (editor) {\n case 'number': return new NumberEditor();\n case 'date': return new DateEditor();\n case 'select': return new SelectEditor(col.options ?? [], col.optionsFn as any);\n case 'checkbox': return new CheckboxEditor();\n default: return new TextEditor();\n }\n }\n // EditorDef 객체\n switch (editor.type) {\n case 'number': {\n const opts: { min?: number; max?: number; step?: number } = {};\n if (editor.min != null) opts.min = editor.min;\n if (editor.max != null) opts.max = editor.max;\n if (editor.step != null) opts.step = editor.step;\n return new NumberEditor(opts);\n }\n case 'date': return new DateEditor();\n case 'select': return new SelectEditor(editor.options ?? [], col.optionsFn as any);\n case 'checkbox': return new CheckboxEditor();\n default: return new TextEditor();\n }\n}\n","import type { ColumnDef } from './types.js';\n\nexport function isToggleCol<T>(col: ColumnDef<T>): boolean {\n const rendType = typeof col.renderer === 'string'\n ? col.renderer\n : (col.renderer && typeof col.renderer === 'object' ? (col.renderer as any).type : '');\n return col.type === 'boolean' || (col.type as string) === 'checkbox'\n || rendType === 'checkbox' || rendType === 'switch';\n}\n\nexport function isSelectCol<T>(col: ColumnDef<T>): boolean {\n return (col.type as string) === 'select';\n}\n\nexport function isRadioCol<T>(col: ColumnDef<T>): boolean {\n return (col.type as string) === 'radio';\n}\n","import { DataLayer } from './DataLayer.js';\nimport { ColumnLayout } from './ColumnLayout.js';\nimport { GridRenderer } from './GridRenderer.js';\nimport { createEditor } from './editors/CellEditor.js';\nimport type { CellEditor } from './editors/CellEditor.js';\nimport type { ColumnDef, EditEvent } from './types.js';\nimport { isToggleCol } from './CellTypeRegistry.js';\n\nexport interface CellEditDeps<T extends Record<string, any>> {\n data: DataLayer<T>;\n colLayout: ColumnLayout<T>;\n getRenderer: () => GridRenderer | null;\n getContainer: () => HTMLElement;\n getOptions: () => any;\n emit: (event: string, ...args: any[]) => void;\n doRender: () => void;\n announce: (msg: string) => void;\n writeCell: (ri: number, field: string, value: any) => void;\n scrollToRow: (ri: number) => void;\n getVisibleLeaves: () => ColumnDef<T>[];\n}\n\nexport class CellEditManager<T extends Record<string, any> = any> {\n private _activeEditor: CellEditor | null = null;\n private _editCell: { ri: number; ci: number } | null = null;\n private _focusCell: { ri: number; ci: number } | null = null;\n private _dragColIdx: number | null = null;\n\n private _d: CellEditDeps<T>;\n\n constructor(deps: CellEditDeps<T>) {\n this._d = deps;\n }\n\n // ─── 상태 접근자 ─────────────────────────────────────────\n get activeEditor(): CellEditor | null { return this._activeEditor; }\n get editCell(): { ri: number; ci: number } | null { return this._editCell; }\n get focusCell(): { ri: number; ci: number } | null { return this._focusCell; }\n get dragColIdx(): number | null { return this._dragColIdx; }\n set dragColIdx(v: number | null) { this._dragColIdx = v; }\n\n // ─── 포커스 셀 ───────────────────────────────────────────\n setFocusCell(ri: number, ci: number): void {\n this._focusCell = { ri, ci };\n this._d.scrollToRow(ri);\n this._d.doRender();\n const col = this._d.getVisibleLeaves()[ci];\n const row = this._d.data.getRowByIndex(ri);\n if (col && row) {\n const val = (row as any)[col.field];\n this._d.announce(\n `${ri + 1}행 ${ci + 1}열, ${col.header}: ${val == null ? '빈 값' : String(val)}`\n );\n }\n }\n\n clearFocusCell(): void { this._focusCell = null; }\n\n // ─── 편집 시작 (키보드) ──────────────────────────────────\n startEditByKey(rowIndex: number, colIndex: number): void {\n const col = this._d.getVisibleLeaves()[colIndex];\n if (!col) return;\n\n if (isToggleCol(col)) {\n const opts = this._d.getOptions();\n const colEditable = col.editable !== false && (col.editable !== undefined || opts.editable);\n if (colEditable) {\n const row = this._d.data.getRowByIndex(rowIndex);\n if (row) this._d.writeCell(rowIndex, col.field as unknown as string, !(row as any)[col.field]);\n }\n return;\n }\n\n const row = this._d.data.getRowByIndex(rowIndex);\n if (col.editable === false) return;\n if (typeof col.editable === 'function' && !col.editable(row as T, rowIndex)) return;\n\n this.commitEdit();\n const cellEl = this._d.getRenderer()?.getCellEl(rowIndex, colIndex);\n if (!cellEl) return;\n cellEl.innerHTML = '';\n\n const editor = createEditor(col);\n this._activeEditor = editor;\n this._editCell = { ri: rowIndex, ci: colIndex };\n\n const startEvt: EditEvent<T> = {\n type: 'editStart', rowIndex, columnIndex: colIndex,\n field: col.field, oldValue: row?.[col.field], newValue: row?.[col.field],\n row: row as T, column: col as any\n };\n this._d.emit('editStart', startEvt);\n this._d.getOptions().onEditStart?.(startEvt);\n\n cellEl.classList.add('og-editing');\n const ctx = {\n value: row?.[col.field], row: row as any, rowIndex,\n column: col as any, colIndex, isSelected: true, rowState: 'none' as any\n };\n editor.mount(cellEl, ctx,\n (value) => this.commitEditWithValue(rowIndex, colIndex, value),\n () => this.cancelEdit()\n );\n requestAnimationFrame(() => editor.focus());\n }\n\n // ─── 편집 시작 (마우스) ──────────────────────────────────\n startEdit(rowIndex: number, colIndex: number, _e: MouseEvent): void {\n const opts = this._d.getOptions();\n if (!opts.editable) return;\n const col = this._d.getVisibleLeaves()[colIndex];\n if (!col) return;\n\n if (isToggleCol(col)) return;\n\n const row = this._d.data.getRowByIndex(rowIndex);\n if (col.editable === false) return;\n if (typeof col.editable === 'function' && !col.editable(row as T, rowIndex)) return;\n if (!col.editable && !opts.editable) return;\n\n this.commitEdit();\n\n const cellEl = this._d.getRenderer()?.getCellEl(rowIndex, colIndex);\n if (!cellEl) return;\n cellEl.innerHTML = '';\n\n const editor = createEditor(col);\n this._activeEditor = editor;\n this._editCell = { ri: rowIndex, ci: colIndex };\n\n const startEvt: EditEvent<T> = {\n type: 'editStart', rowIndex, columnIndex: colIndex,\n field: col.field, oldValue: row?.[col.field], newValue: row?.[col.field],\n row: row as T, column: col as any\n };\n this._d.emit('editStart', startEvt);\n opts.onEditStart?.(startEvt);\n\n cellEl.classList.add('og-editing');\n const ctx = {\n value: row?.[col.field], row: row as any, rowIndex,\n column: col as any, colIndex, isSelected: true, rowState: 'none' as any\n };\n editor.mount(cellEl, ctx,\n (value) => this.commitEditWithValue(rowIndex, colIndex, value),\n () => this.cancelEdit()\n );\n requestAnimationFrame(() => editor.focus());\n }\n\n // ─── 편집 종료 ───────────────────────────────────────────\n commitEdit(): void {\n if (!this._activeEditor || !this._editCell) return;\n const val = this._activeEditor.getValue();\n const { ri, ci } = this._editCell;\n this._finishEdit(ri, ci, val, false);\n }\n\n commitEditWithValue(ri: number, ci: number, value: any): void {\n this._finishEdit(ri, ci, value, false);\n }\n\n cancelEdit(): void {\n if (!this._editCell) return;\n const { ri, ci } = this._editCell;\n this._finishEdit(ri, ci, undefined, true);\n }\n\n private _finishEdit(ri: number, ci: number, value: any, cancel: boolean): void {\n if (!this._activeEditor) return;\n const col = this._d.getVisibleLeaves()[ci];\n const cellEl = this._d.getRenderer()?.getCellEl(ri, ci);\n if (cellEl) {\n this._activeEditor.destroy();\n cellEl.classList.remove('og-editing');\n }\n this._activeEditor = null;\n this._editCell = null;\n\n if (!cancel && col) {\n const old = this._d.data.getCellValue(ri, col.field);\n if (value !== old) {\n this._d.data.updateCell(ri, col.field, value);\n const row = this._d.data.getRowByIndex(ri);\n const opts = this._d.getOptions();\n const evt: EditEvent<T> = {\n type: 'editEnd', rowIndex: ri, columnIndex: ci,\n field: col.field, oldValue: old, newValue: value,\n row: row as T, column: col as any\n };\n this._d.emit('editEnd', evt);\n opts.onEditEnd?.(evt);\n this._d.emit('dataChange', this._d.data.getData());\n opts.onDataChange?.(this._d.data.getData());\n }\n }\n this._d.doRender();\n requestAnimationFrame(() => this._d.getContainer().focus({ preventScroll: true }));\n }\n}\n","import type { FilterItem } from './types.js';\n\n// ─── 공개 타입 ────────────────────────────────────────────\n\nexport interface FilterSelectOption {\n value: string;\n text: string;\n}\n\n/**\n * 캐스케이딩 필터 셀렉트 컬럼 정의.\n *\n * ### 데이터 공급 방식 (택 1)\n *\n * **A. JSON 배열 바인딩** (권장)\n * ```ts\n * {\n * field: 'brand',\n * label: '브랜드',\n * data: brandList, // any[] ← JSON 배열\n * valueKey: 'brandCode', // 필터·선택값으로 사용할 키\n * textKey: 'brandName', // 화면에 표시할 텍스트 키\n * filterKey: 'brand', // 그리드 행 데이터의 필터 기준 키 (기본: field)\n * dependsOn: 'category', // 부모 컬럼 field\n * dependsOnKey: 'catCode', // 자식 data[]에서 부모값과 매칭할 키\n * }\n * ```\n *\n * **B. 정적 옵션 배열**\n * ```ts\n * { field: 'status', options: [{ value: 'Y', text: '활성' }] }\n * ```\n */\nexport interface FilterSelectColumn {\n /** 캐스케이딩 식별자 / 기본 필터 키 */\n field: string;\n /** 화면 표시 라벨 */\n label: string;\n\n // ── A. JSON 배열 바인딩 ──────────────────────────────\n /** 바인딩할 JSON 배열 */\n data?: any[];\n /** data[]에서 option value로 사용할 키 */\n valueKey?: string;\n /** data[]에서 화면 표시 text로 사용할 키 (미지정 시 valueKey 사용) */\n textKey?: string;\n /**\n * 그리드 행 데이터에서 실제 필터링할 키.\n * 미지정 시 `field` 값 그대로 사용.\n *\n * @example\n * // 그리드 row.category === selectedValue 로 필터링\n * filterKey: 'category'\n */\n filterKey?: string;\n\n // ── B. 정적 옵션 (data 대신 사용) ───────────────────\n options?: FilterSelectOption[];\n\n // ── 캐스케이딩 ────────────────────────────────────────\n /** 부모 컬럼의 field 명 */\n dependsOn?: string;\n /**\n * 자식 data[]에서 부모 선택값과 비교할 키.\n *\n * @example\n * // brandList.filter(b => b.catCode === parentSelectedValue)\n * dependsOnKey: 'catCode'\n */\n dependsOnKey?: string;\n}\n\nexport interface FilterSelectConfig {\n columns: FilterSelectColumn[];\n /** fieldset 제목 (기본: '필터') */\n legend?: string;\n}\n\ntype FilterFn = (field: string, items: FilterItem[]) => void;\ntype ResetFn = (field?: string) => void;\n\n// ─── FilterSelectPanel ────────────────────────────────────\nexport class FilterSelectPanel {\n private _el: HTMLFieldSetElement;\n private _selects = new Map<string, HTMLSelectElement>();\n /** 현재 선택 상태 { field → selectedValue } */\n private _selected: Record<string, string> = {};\n private _config: FilterSelectConfig;\n private _onFilter: FilterFn;\n private _onReset: ResetFn;\n\n constructor(\n container: HTMLElement,\n config: FilterSelectConfig,\n onFilter: FilterFn,\n onReset: ResetFn,\n gridId?: string,\n ) {\n this._config = config;\n this._onFilter = onFilter;\n this._onReset = onReset;\n\n /* fieldset */\n this._el = document.createElement('fieldset');\n this._el.className = 'og-filter-select';\n\n const legend = document.createElement('legend');\n legend.className = 'og-filter-select-legend';\n legend.textContent = config.legend ?? '필터';\n this._el.appendChild(legend);\n\n const row = document.createElement('div');\n row.className = 'og-filter-select-row';\n\n for (const col of config.columns) {\n const uid = `og-fsel-${col.field}`;\n\n const wrap = document.createElement('div');\n wrap.className = 'og-filter-select-group';\n\n const label = document.createElement('label');\n label.htmlFor = uid;\n label.textContent = col.label;\n label.className = 'og-filter-select-label';\n\n const select = document.createElement('select');\n select.id = uid;\n select.className = 'og-filter-select-sel';\n select.setAttribute('aria-label', col.label);\n if (gridId) select.setAttribute('aria-controls', gridId);\n\n if (!col.dependsOn) {\n /* 루트 컬럼 — 즉시 전체 옵션 로드 */\n this._fill(select, this._resolve(col, ''), true);\n } else {\n /* 종속 컬럼 — 부모 선택 전까지 비활성 */\n this._fill(select, [], false);\n }\n\n select.addEventListener('change', () => this._onChange(col.field, select.value));\n\n wrap.appendChild(label);\n wrap.appendChild(select);\n row.appendChild(wrap);\n this._selects.set(col.field, select);\n }\n\n /* 초기화 버튼 */\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.textContent = '초기화';\n btn.className = 'og-filter-select-reset';\n btn.setAttribute('aria-label', '필터 초기화');\n btn.addEventListener('click', () => this._reset());\n\n this._el.appendChild(row);\n this._el.appendChild(btn);\n\n /* 그리드 헤더 앞에 삽입 */\n container.insertBefore(this._el, container.firstChild);\n }\n\n // ─── 옵션 해결 ────────────────────────────────────────\n /**\n * 컬럼의 옵션 목록을 계산한다.\n *\n * @param col 대상 컬럼 정의\n * @param parentValue 부모 선택값 (캐스케이딩 필터에 사용)\n */\n private _resolve(col: FilterSelectColumn, parentValue: string): FilterSelectOption[] {\n /* B. 정적 옵션 배열 */\n if (col.options) return col.options;\n\n /* A. JSON 배열 + 키 매핑 */\n let rows = col.data ?? [];\n\n /* 캐스케이딩: dependsOnKey 기준으로 부모 선택값과 매칭 */\n if (col.dependsOn && col.dependsOnKey && parentValue) {\n rows = rows.filter(\n item => String(item[col.dependsOnKey!] ?? '') === parentValue,\n );\n }\n\n const vk = col.valueKey ?? 'value';\n const tk = col.textKey ?? vk;\n\n return rows.map(item => ({\n value: String(item[vk] ?? ''),\n text: String(item[tk] ?? item[vk] ?? ''),\n }));\n }\n\n // ─── select DOM 채우기 ────────────────────────────────\n private _fill(\n select: HTMLSelectElement,\n opts: FilterSelectOption[],\n enabled: boolean,\n ): void {\n select.innerHTML = '';\n const all = document.createElement('option');\n all.value = ''; all.textContent = '전체';\n select.appendChild(all);\n for (const o of opts) {\n const el = document.createElement('option');\n el.value = o.value; el.textContent = o.text;\n select.appendChild(el);\n }\n select.disabled = !enabled;\n }\n\n // ─── 선택 변경 처리 ───────────────────────────────────\n private _onChange(field: string, value: string): void {\n const col = this._config.columns.find(c => c.field === field)!;\n const fk = col.filterKey ?? col.field; // 실제 그리드 필터 키\n\n if (value) {\n this._selected[field] = value;\n this._onFilter(fk, [{ operator: '=', value }]);\n } else {\n delete this._selected[field];\n this._onReset(fk);\n }\n this._cascade(field);\n }\n\n /**\n * 부모 컬럼 변경 후 자식 컬럼 옵션을 재계산한다 (재귀).\n */\n private _cascade(parentField: string): void {\n const parentValue = this._selected[parentField] ?? '';\n\n for (const col of this._config.columns) {\n if (col.dependsOn !== parentField) continue;\n const sel = this._selects.get(col.field);\n if (!sel) continue;\n const fk = col.filterKey ?? col.field;\n\n if (!parentValue) {\n /* 부모 초기화 → 자식 비활성 */\n this._fill(sel, [], false);\n delete this._selected[col.field];\n this._onReset(fk);\n this._cascade(col.field); // 하위로 재귀\n } else {\n /* 부모 값 있음 → 자식 옵션 재로드 */\n this._fill(sel, this._resolve(col, parentValue), true);\n sel.value = '';\n delete this._selected[col.field];\n this._onReset(fk);\n }\n }\n }\n\n // ─── 전체 초기화 ──────────────────────────────────────\n private _reset(): void {\n this._selected = {};\n for (const col of this._config.columns) {\n const sel = this._selects.get(col.field);\n const fk = col.filterKey ?? col.field;\n if (!sel) continue;\n if (!col.dependsOn) {\n sel.value = ''; sel.disabled = false;\n } else {\n this._fill(sel, [], false);\n }\n this._onReset(fk);\n }\n }\n\n // ─── 공개 API ─────────────────────────────────────────\n reset(): void { this._reset(); }\n destroy(): void { this._el.remove(); }\n}\n","export interface PageChangeEvent {\n page: number;\n pageSize: number;\n totalRows: number;\n totalPages: number;\n}\n\nexport type PageChangeFn = (e: PageChangeEvent) => void;\n\n/**\n * 그리드 하단 페이지네이션 UI + 상태 관리.\n * DataLayer의 _displayIndexes 슬라이싱을 담당.\n */\nexport class Pagination {\n private _el: HTMLElement;\n private _page = 1;\n private _pageSize: number;\n private _totalRows = 0;\n private _onChange: PageChangeFn;\n\n constructor(container: HTMLElement, pageSize: number, onChange: PageChangeFn) {\n this._pageSize = pageSize;\n this._onChange = onChange;\n\n this._el = document.createElement('div');\n this._el.className = 'og-pagination';\n this._el.style.cssText = `\n display:flex;align-items:center;justify-content:center;gap:4px;\n padding:6px 8px;border-top:1px solid var(--og-border-color,#e0e0e0);\n background:var(--og-header-bg,#f5f5f5);flex-shrink:0;user-select:none;\n font-size:12px;color:var(--og-text-color,#333);\n `;\n container.appendChild(this._el);\n this._render();\n }\n\n get page() { return this._page; }\n get pageSize() { return this._pageSize; }\n get totalPages() { return Math.max(1, Math.ceil(this._totalRows / this._pageSize)); }\n\n /** 전체 행 수 갱신 → 현재 페이지 유효성 검사 후 재렌더 */\n setTotalRows(n: number): void {\n this._totalRows = n;\n if (this._page > this.totalPages) this._page = this.totalPages;\n this._render();\n }\n\n setPageSize(size: number): void {\n this._pageSize = size;\n this._page = 1;\n this._render();\n this._emit();\n }\n\n goTo(page: number): void {\n const p = Math.max(1, Math.min(page, this.totalPages));\n if (p === this._page) return;\n this._page = p;\n this._render();\n this._emit();\n }\n\n /** 현재 페이지의 [startIndex, endIndex] 반환 (DataLayer 인덱스 기준) */\n getRange(): { start: number; end: number } {\n const start = (this._page - 1) * this._pageSize;\n const end = Math.min(start + this._pageSize - 1, this._totalRows - 1);\n return { start, end };\n }\n\n private _emit(): void {\n this._onChange({\n page: this._page, pageSize: this._pageSize,\n totalRows: this._totalRows, totalPages: this.totalPages,\n });\n }\n\n private _render(): void {\n this._el.innerHTML = '';\n const total = this.totalPages;\n\n // 페이지 크기 선택\n const sizeWrap = document.createElement('span');\n sizeWrap.style.cssText = 'display:flex;align-items:center;gap:3px;margin-right:8px;';\n const sizeLabel = document.createElement('span');\n sizeLabel.textContent = '행/페이지:';\n sizeLabel.style.color = '#888';\n const sizeSel = document.createElement('select');\n sizeSel.style.cssText = `padding:2px 4px;border:1px solid var(--og-border-color,#e0e0e0);border-radius:3px;font-size:11px;cursor:pointer;`;\n for (const s of [10, 20, 50, 100, 200]) {\n const opt = document.createElement('option');\n opt.value = String(s);\n opt.textContent = String(s);\n if (s === this._pageSize) opt.selected = true;\n sizeSel.appendChild(opt);\n }\n sizeSel.addEventListener('change', () => this.setPageSize(Number(sizeSel.value)));\n sizeWrap.appendChild(sizeLabel);\n sizeWrap.appendChild(sizeSel);\n this._el.appendChild(sizeWrap);\n\n // 총 행 수\n const info = document.createElement('span');\n const { start, end } = this.getRange();\n info.textContent = this._totalRows > 0\n ? `${start + 1}–${end + 1} / ${this._totalRows}건`\n : '0건';\n info.style.cssText = 'margin-right:8px;color:#888;';\n this._el.appendChild(info);\n\n // 이전/다음 버튼 + 페이지 번호\n const mkBtn = (label: string, page: number, disabled: boolean) => {\n const btn = document.createElement('button');\n btn.textContent = label;\n btn.disabled = disabled;\n btn.style.cssText = `\n min-width:28px;height:24px;padding:0 6px;\n border:1px solid var(--og-border-color,#e0e0e0);border-radius:3px;\n background:${disabled ? '#f5f5f5' : '#fff'};\n color:${disabled ? '#bbb' : 'var(--og-text-color,#333)'};\n cursor:${disabled ? 'default' : 'pointer'};font-size:12px;\n `;\n if (!disabled) btn.addEventListener('click', () => this.goTo(page));\n return btn;\n };\n\n this._el.appendChild(mkBtn('«', 1, this._page === 1));\n this._el.appendChild(mkBtn('‹', this._page - 1, this._page === 1));\n\n // 페이지 번호 (최대 5개 표시)\n const range = _pageRange(this._page, total);\n for (const p of range) {\n if (p === -1) {\n const dot = document.createElement('span');\n dot.textContent = '…';\n dot.style.padding = '0 3px';\n this._el.appendChild(dot);\n } else {\n const btn = mkBtn(String(p), p, p === this._page);\n if (p === this._page) {\n btn.style.background = 'var(--og-primary,#1976d2)';\n btn.style.color = '#fff';\n btn.style.borderColor = 'var(--og-primary,#1976d2)';\n }\n this._el.appendChild(btn);\n }\n }\n\n this._el.appendChild(mkBtn('›', this._page + 1, this._page === total));\n this._el.appendChild(mkBtn('»', total, this._page === total));\n }\n\n destroy(): void {\n this._el.remove();\n }\n}\n\n/** 현재 페이지 기준 표시할 페이지 번호 배열 (-1 = ellipsis) */\nfunction _pageRange(current: number, total: number): number[] {\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n const pages: number[] = [1];\n if (current > 3) pages.push(-1);\n for (let p = Math.max(2, current - 1); p <= Math.min(total - 1, current + 1); p++) {\n pages.push(p);\n }\n if (current < total - 2) pages.push(-1);\n pages.push(total);\n return pages;\n}\n","// ============================================================\n// 드래그 시각 요소 — 고스트(따라다니는 점선 박스) + 드롭 인디케이터(라인)\n// RowDragDrop 에서 분리해 단일 책임으로 캡슐화한다.\n// ============================================================\n\n/** 커서를 따라다니는 점선 고스트. transform 으로 X·Y 모두 이동(부드럽게). */\nexport class DragGhost {\n private _el: HTMLElement;\n private _dx: number; // grab 지점의 좌측 오프셋\n private _dy: number; // grab 지점의 상단 오프셋\n\n constructor(rect: DOMRect, grabX: number, grabY: number, count: number) {\n this._dx = grabX - rect.left;\n this._dy = grabY - rect.top;\n\n const el = document.createElement('div');\n el.className = 'og-drag-ghost';\n el.style.cssText =\n `position:fixed;left:0;top:0;width:${rect.width}px;height:${Math.min(rect.height, 40)}px;` +\n `transform:translate(${rect.left}px,${rect.top}px);` +\n 'background:rgba(25,118,210,0.12);border:2px dashed #1976d2;box-sizing:border-box;' +\n 'pointer-events:none;z-index:10000;border-radius:3px;opacity:0.92;' +\n 'display:flex;align-items:center;padding-left:10px;font-size:12px;color:#1565c0;font-weight:600;' +\n 'white-space:nowrap;overflow:hidden;';\n if (count > 1) el.textContent = `${count}개 행 이동`;\n document.body.appendChild(el);\n this._el = el;\n }\n\n /** 커서 위치로 이동 (grab 오프셋 유지) */\n move(clientX: number, clientY: number): void {\n this._el.style.transform = `translate(${clientX - this._dx}px,${clientY - this._dy}px)`;\n }\n\n destroy(): void { this._el.remove(); }\n}\n\n/**\n * 드롭(삽입) 위치 마커. 행과 행 사이 경계에 \"▶━━━◀\" 형태로 또렷하게 표시해\n * \"여기에 삽입됩니다 / 지금 버튼을 떼면 됩니다\" 를 직관적으로 알린다(워드 표 삽입 표시 느낌).\n * 자기 그리드/타깃 그리드 모두에 재사용.\n */\nexport class DropIndicator {\n private _el: HTMLElement;\n\n constructor(color = '#1976d2') {\n const el = document.createElement('div');\n el.className = 'og-drop-indicator';\n // 경계(top) 중앙에 마커가 오도록 translateY(-50%)\n el.style.cssText =\n 'position:absolute;left:0;right:0;display:none;align-items:center;' +\n 'pointer-events:none;z-index:9998;transform:translateY(-50%);';\n\n const cap = (dir: 'left' | 'right'): HTMLElement => {\n const c = document.createElement('div');\n const side = dir === 'left' ? `border-left:7px solid ${color}` : `border-right:7px solid ${color}`;\n c.style.cssText =\n `width:0;height:0;flex-shrink:0;border-top:5px solid transparent;border-bottom:5px solid transparent;${side};`;\n return c;\n };\n const bar = document.createElement('div');\n bar.style.cssText =\n `flex:1;height:3px;background:${color};border-radius:2px;box-shadow:0 0 0 1px rgba(255,255,255,0.7);`;\n\n el.append(cap('left'), bar, cap('right')); // ▶━━━◀\n this._el = el;\n }\n\n /** parent(그리드 바디) 안의 top(행 경계) 위치에 표시 */\n showIn(parent: HTMLElement, top: number): void {\n if (this._el.parentElement !== parent) {\n this._el.remove();\n parent.appendChild(this._el);\n }\n this._el.style.display = 'flex';\n this._el.style.top = `${top}px`;\n }\n\n hide(): void { this._el.style.display = 'none'; }\n\n destroy(): void { this._el.remove(); }\n}\n","import { DragGhost, DropIndicator } from './DragVisuals.js';\n\nexport type RowDropCallback = (fromIndex: number, toIndex: number) => void;\n\n/** 커서 좌표로 다른 그리드의 바디를 찾는 해석기 */\nexport interface CrossGridResolveResult {\n bodyEl: HTMLElement;\n rowHeight: number;\n totalRows: number;\n}\nexport interface CrossGridConfig {\n /** 커서 위치(x,y)에 있는 다른(crossGrid 허용) 그리드 바디 정보 반환. 없으면 null */\n resolveTarget: (clientX: number, clientY: number) => CrossGridResolveResult | null;\n /** 다른 그리드로 드롭됐을 때 호출 (소스 fromIndex, 타깃 바디, 타깃 삽입 인덱스) */\n onCrossDrop: (fromIndex: number, targetBodyEl: HTMLElement, targetIndex: number) => void;\n}\n\ninterface DragState {\n fromIndex: number;\n bodyEl: HTMLElement;\n rowHeight: number;\n totalRows: number;\n ghost: DragGhost;\n currentTarget: number;\n /** 현재 커서가 올라가 있는 다른 그리드 (없으면 null = 자기 그리드 내 재정렬) */\n crossTarget: { bodyEl: HTMLElement; index: number } | null;\n}\n\nconst clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));\n\n/**\n * 행 드래그앤드롭 관리자 (순수 DnD).\n * 행 DOM에 드래그 핸들을 심고, 고스트/인디케이터로 위치를 표시한 뒤 콜백으로 알림.\n * 그리드 간 이동 판정(타깃 그리드 해석)은 주입된 CrossGridConfig 에 위임한다.\n */\nexport class RowDragDrop {\n private _drag: DragState | null = null;\n private readonly _selfIndicator = new DropIndicator('#1976d2'); // 자기 그리드 재정렬\n private readonly _crossIndicator = new DropIndicator('#2e7d32'); // 다른 그리드 드롭\n\n constructor(\n private _bodyEl: HTMLElement,\n private _rowHeight: number,\n private _onDrop: RowDropCallback,\n private _cross: CrossGridConfig | null = null,\n /** fromIndex 기준 함께 드래그할 행 수(멀티행 배지용). 기본 1 */\n private _getDragCount: (fromIndex: number) => number = () => 1,\n ) {\n this._onMouseMove = this._onMouseMove.bind(this);\n this._onMouseUp = this._onMouseUp.bind(this);\n }\n\n /** 행 엘리먼트에 드래그 핸들 삽입 */\n attachHandle(rowEl: HTMLElement, rowIndex: number, totalRows: number): HTMLElement {\n const handle = document.createElement('div');\n handle.className = 'og-drag-handle';\n handle.innerHTML = '⠿';\n handle.style.cssText = `\n width:18px;min-width:18px;height:100%;\n display:flex;align-items:center;justify-content:center;\n cursor:grab;font-size:14px;color:#bbb;flex-shrink:0;\n user-select:none;border-right:1px solid var(--og-border-color,#e0e0e0);\n `;\n handle.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this._startDrag(e, rowEl, rowIndex, totalRows);\n });\n return handle;\n }\n\n private _startDrag(e: MouseEvent, rowEl: HTMLElement, fromIndex: number, totalRows: number): void {\n const rect = rowEl.getBoundingClientRect();\n const count = this._getDragCount(fromIndex);\n this._drag = {\n fromIndex,\n bodyEl: this._bodyEl,\n rowHeight: this._rowHeight,\n totalRows,\n ghost: new DragGhost(rect, e.clientX, e.clientY, count),\n currentTarget: fromIndex,\n crossTarget: null,\n };\n // 캡처 단계로 등록 — 바디 셀이 mousemove/mouseup 에서 stopPropagation 해도\n // (버블 단계 차단) 드래그 추적/종료가 항상 동작하게 한다.\n document.addEventListener('mousemove', this._onMouseMove, true);\n document.addEventListener('mouseup', this._onMouseUp, true);\n }\n\n private _onMouseMove(e: MouseEvent): void {\n if (!this._drag) return;\n const d = this._drag;\n\n // 고스트가 커서를 X·Y 모두 따라간다 (다른 그리드로 끌어도 끊기지 않음)\n d.ghost.move(e.clientX, e.clientY);\n\n // ── 크로스그리드: 커서가 다른 그리드 위에 있는지 ──\n if (this._cross) {\n const hit = this._cross.resolveTarget(e.clientX, e.clientY);\n if (hit && hit.bodyEl !== d.bodyEl) {\n const tRect = hit.bodyEl.getBoundingClientRect();\n const tRelY = e.clientY - tRect.top + hit.bodyEl.scrollTop;\n const tIdx = clamp(Math.round(tRelY / hit.rowHeight), 0, hit.totalRows);\n d.crossTarget = { bodyEl: hit.bodyEl, index: tIdx };\n this._selfIndicator.hide();\n this._crossIndicator.showIn(hit.bodyEl, tIdx * hit.rowHeight);\n return;\n }\n }\n\n // ── 자기 그리드 내 재정렬 ──\n d.crossTarget = null;\n this._crossIndicator.hide();\n const bodyRect = d.bodyEl.getBoundingClientRect();\n const relY = e.clientY - bodyRect.top + d.bodyEl.scrollTop;\n d.currentTarget = clamp(Math.round(relY / d.rowHeight), 0, d.totalRows - 1);\n this._selfIndicator.showIn(d.bodyEl, d.currentTarget * d.rowHeight);\n }\n\n private _onMouseUp(_e: MouseEvent): void {\n document.removeEventListener('mousemove', this._onMouseMove, true);\n document.removeEventListener('mouseup', this._onMouseUp, true);\n\n if (!this._drag) return;\n const { fromIndex, currentTarget, ghost, crossTarget } = this._drag;\n this._drag = null;\n\n // 모든 드래그 잔상 제거\n ghost.destroy();\n this._selfIndicator.hide();\n this._crossIndicator.hide();\n\n if (crossTarget && this._cross) {\n this._cross.onCrossDrop(fromIndex, crossTarget.bodyEl, crossTarget.index);\n } else if (fromIndex !== currentTarget) {\n this._onDrop(fromIndex, currentTarget);\n }\n }\n\n destroy(): void {\n document.removeEventListener('mousemove', this._onMouseMove, true);\n document.removeEventListener('mouseup', this._onMouseUp, true);\n this._drag?.ghost.destroy();\n this._selfIndicator.destroy();\n this._crossIndicator.destroy();\n this._drag = null;\n }\n}\n","/**\n * 셀 병합 관리 엔진.\n *\n * 두 가지 병합 방식 지원:\n * 1. 동적 병합: mergeCells([{row, col, rowSpan, colSpan}])\n * 2. 자동 병합: 같은 필드에 같은 값이 연속되면 자동으로 rowSpan\n */\n\nexport interface MergeCell {\n row: number; // display row index (0-based)\n col: number; // leaf column index (0-based)\n rowSpan?: number; // 1 이상 (기본 1)\n colSpan?: number; // 1 이상 (기본 1)\n}\n\nexport interface MergeInfo {\n rowSpan: number;\n colSpan: number;\n hidden: boolean; // 병합으로 숨겨진 셀 (렌더링 생략)\n}\n\nexport class MergeEngine {\n // (row, col) → MergeInfo\n private _map: Map<string, MergeInfo> = new Map();\n\n private static _key(row: number, col: number): string {\n return `${row}:${col}`;\n }\n\n /** 수동 병합 정의 목록으로 맵 구성 */\n applyMergeCells(cells: MergeCell[]): void {\n this._map.clear();\n for (const mc of cells) {\n const rs = Math.max(1, mc.rowSpan ?? 1);\n const cs = Math.max(1, mc.colSpan ?? 1);\n // 기준 셀\n this._map.set(MergeEngine._key(mc.row, mc.col), {\n rowSpan: rs, colSpan: cs, hidden: false,\n });\n // 병합된 하위 셀 — hidden:true\n for (let r = 0; r < rs; r++) {\n for (let c = 0; c < cs; c++) {\n if (r === 0 && c === 0) continue;\n this._map.set(MergeEngine._key(mc.row + r, mc.col + c), {\n rowSpan: 1, colSpan: 1, hidden: true,\n });\n }\n }\n }\n }\n\n /**\n * 자동 병합: 지정 컬럼 인덱스 목록에 대해 연속 같은 값을 rowSpan으로 병합.\n * data: 현재 표시 순서의 행 배열, colIndexes: 자동병합할 leaf 컬럼 인덱스\n * fields: colIndexes[i] 에 대응하는 field 이름\n */\n applyAutoMerge(\n data: Record<string, any>[],\n colIndexes: number[],\n fields: string[]\n ): void {\n this._map.clear();\n for (let ci = 0; ci < colIndexes.length; ci++) {\n const col = colIndexes[ci]!;\n const field = fields[ci]!;\n let spanStart = 0;\n\n for (let ri = 1; ri <= data.length; ri++) {\n const prevVal = data[ri - 1]?.[field];\n const curVal = ri < data.length ? data[ri]?.[field] : undefined;\n\n if (ri === data.length || curVal !== prevVal) {\n const span = ri - spanStart;\n if (span > 1) {\n this._map.set(MergeEngine._key(spanStart, col), {\n rowSpan: span, colSpan: 1, hidden: false,\n });\n for (let r = spanStart + 1; r < ri; r++) {\n this._map.set(MergeEngine._key(r, col), {\n rowSpan: 1, colSpan: 1, hidden: true,\n });\n }\n }\n spanStart = ri;\n }\n }\n }\n }\n\n /** 셀 병합 정보 조회. 없으면 null */\n getInfo(row: number, col: number): MergeInfo | null {\n return this._map.get(MergeEngine._key(row, col)) ?? null;\n }\n\n /** 병합 맵 초기화 */\n clear(): void {\n this._map.clear();\n }\n\n get isEmpty(): boolean {\n return this._map.size === 0;\n }\n}\n","// ============================================================\n// ContextMenu — 우클릭 팝업 컨텍스트 메뉴 관리자\n// 레이어: Orchestration (UI 생성 + 이벤트 조율)\n// 설계 근거(Why): 메뉴를 document.body가 아닌 그리드 컨테이너(_anchor)의\n// 자식으로 추가한다. position:fixed로 뷰포트 기준 배치를 유지하면서\n// CSS 변수(--og-*)를 컨테이너에서 자동 상속 → 테마 즉시 반영.\n// ============================================================\n\nimport type { ContextMenuItem } from './types.js';\n\nexport type { ContextMenuItem };\n\nexport interface ContextMenuActions {\n onSortAsc: () => void;\n onSortDesc: () => void;\n onFind: () => void;\n onExcel: () => void;\n onCsv: () => void;\n onPrint: () => void;\n}\n\nexport const DEFAULT_CONTEXT_ITEMS: ContextMenuItem[] = [\n { id: 'sort-asc', label: '오름차순 정렬', icon: '↑', action: 'sortAsc' },\n { id: 'sort-desc', label: '내림차순 정렬', icon: '↓', action: 'sortDesc' },\n { type: 'divider' },\n { id: 'find', label: '찾기', icon: '🔍', action: 'find' },\n { type: 'divider' },\n { id: 'excel', label: 'Excel로 저장', icon: '📊', action: 'excel' },\n { id: 'csv', label: 'CSV로 저장', icon: '📄', action: 'csv' },\n { id: 'print', label: '인쇄', icon: '🖨', action: 'print' },\n];\n\nexport class ContextMenuManager {\n private _el: HTMLElement | null = null;\n private _docClick: ((e: MouseEvent) => void) | null = null;\n private _docKey: ((e: KeyboardEvent) => void) | null = null;\n private _docScroll: (() => void) | null = null;\n private _docMouseMove: ((e: MouseEvent) => void) | null = null;\n private _focusIdx = -1;\n\n /**\n * @param _anchor 그리드 컨테이너 엘리먼트 — CSS 변수 상속 기준점\n * @param _actions 기본 액션 핸들러 (OpenGrid에서 주입)\n */\n constructor(\n private readonly _anchor: HTMLElement,\n private readonly _actions: ContextMenuActions,\n ) {}\n\n open(e: MouseEvent, customItems?: ContextMenuItem[]): void {\n this.close();\n\n const items = customItems ?? DEFAULT_CONTEXT_ITEMS;\n const menu = document.createElement('div');\n menu.className = 'og-context-menu';\n menu.setAttribute('role', 'menu');\n\n for (const item of items) {\n if (item.type === 'divider') {\n const hr = document.createElement('div');\n hr.className = 'og-cm-divider';\n hr.setAttribute('role', 'separator');\n menu.appendChild(hr);\n continue;\n }\n\n const btn = document.createElement('button');\n btn.className = 'og-cm-item';\n btn.setAttribute('role', 'menuitem');\n btn.setAttribute('tabindex', '-1');\n if (item.disabled) {\n btn.classList.add('og-cm-disabled');\n btn.setAttribute('aria-disabled', 'true');\n }\n\n if (item.icon) {\n const ic = document.createElement('span');\n ic.className = 'og-cm-icon';\n // CSS 클래스명(예: 'bi bi-star', 'fa fa-home')이면 <i> 태그로 렌더링\n // 이모지·특수문자·단일 기호면 textContent로 처리\n if (/^[a-zA-Z][\\w-]*(\\s+[\\w-]+)+$/.test(item.icon.trim())) {\n const i = document.createElement('i');\n i.className = item.icon;\n ic.appendChild(i);\n } else {\n ic.textContent = item.icon;\n }\n ic.setAttribute('aria-hidden', 'true');\n btn.appendChild(ic);\n }\n\n const lbl = document.createElement('span');\n lbl.className = 'og-cm-label';\n lbl.textContent = item.label ?? '';\n btn.appendChild(lbl);\n\n btn.addEventListener('click', (ev) => {\n ev.stopPropagation();\n if (!item.disabled) this._runAction(item);\n this.close();\n });\n menu.appendChild(btn);\n }\n\n // document.body 자식으로 추가 → position:fixed 가 항상 뷰포트 기준으로 동작.\n // Why: 그리드 컨테이너(_anchor)에 붙이면, 임베드 호스트(WordPress 글 등)의\n // 조상에 transform/filter 가 있을 때 fixed 기준점이 그 조상으로 바뀌어\n // 메뉴가 마우스 좌표에서 어긋난다(특히 그리드 너비를 넓힐 때). body 부착으로 회피.\n // 테마 CSS 변수(--og-cm-*, --og-*)는 menu 에 data-og-theme 를 복사해 보존한다.\n const themeEl = this._anchor.closest('[data-og-theme]') as HTMLElement | null;\n const theme = themeEl?.getAttribute('data-og-theme');\n if (theme) menu.setAttribute('data-og-theme', theme);\n document.body.appendChild(menu);\n this._el = menu;\n\n // mousemove capture 단계로 등록 — 셀의 stopPropagation() 우회\n // Why: 그리드 셀이 mousemove에 stopPropagation()을 호출해 bubble 단계 document 리스너가 차단됨\n this._docMouseMove = (ev) => {\n if (!this._el) return;\n const r = this._el.getBoundingClientRect();\n if (ev.clientX < r.left - 4 || ev.clientX > r.right + 4 ||\n ev.clientY < r.top - 4 || ev.clientY > r.bottom + 4) {\n this.close();\n }\n };\n\n // position:fixed 기준 좌표 설정 → 포지셔닝 완료 후 올바른 bounds로 리스너 등록\n this._position(menu, e.clientX, e.clientY, () => {\n if (this._el === menu) {\n document.addEventListener('mousemove', this._docMouseMove!, { capture: true, passive: true });\n }\n });\n\n // 외부 클릭 닫기 (다음 틱 — 현재 contextmenu 이벤트 전파 완료 후)\n this._docClick = (ev) => {\n if (!menu.contains(ev.target as Node)) this.close();\n };\n // 키보드 접근성\n this._docKey = (ev) => {\n if (ev.key === 'Escape') { this.close(); return; }\n if (ev.key === 'ArrowDown') { ev.preventDefault(); this._moveFocus(1); return; }\n if (ev.key === 'ArrowUp') { ev.preventDefault(); this._moveFocus(-1); return; }\n if (ev.key === 'Enter') {\n const focused = menu.querySelector<HTMLButtonElement>('.og-cm-item:focus');\n focused?.click();\n }\n };\n this._docScroll = () => this.close();\n\n setTimeout(() => {\n document.addEventListener('click', this._docClick!);\n document.addEventListener('keydown', this._docKey!);\n window.addEventListener('scroll', this._docScroll!, { passive: true });\n }, 0);\n\n // 첫 활성 항목에 포커스\n this._focusIdx = -1;\n this._moveFocus(1);\n }\n\n close(): void {\n this._el?.remove();\n this._el = null;\n if (this._docClick) document.removeEventListener('click', this._docClick);\n if (this._docKey) document.removeEventListener('keydown', this._docKey);\n if (this._docScroll) window.removeEventListener('scroll', this._docScroll);\n if (this._docMouseMove) document.removeEventListener('mousemove', this._docMouseMove, { capture: true });\n this._docClick = this._docKey = this._docScroll = this._docMouseMove = null;\n this._focusIdx = -1;\n }\n\n destroy(): void { this.close(); }\n\n // ── 위치 결정 ─────────────────────────────────────────────\n\n private _position(menu: HTMLElement, x: number, y: number, onPositioned?: () => void): void {\n menu.style.cssText = 'position:fixed;visibility:hidden;left:0;top:0;';\n\n requestAnimationFrame(() => {\n const { width, height } = menu.getBoundingClientRect();\n const vw = window.innerWidth, vh = window.innerHeight;\n const left = x + width > vw ? Math.max(0, x - width) : x;\n const top = y + height > vh ? Math.max(0, y - height) : y;\n menu.style.cssText = `position:fixed;left:${left}px;top:${top}px;z-index:9999;`;\n // 포지셔닝 완료 후 콜백 — mousemove 체크는 정확한 위치 기준으로만 동작\n onPositioned?.();\n });\n }\n\n // ── 키보드 포커스 이동 ────────────────────────────────────\n\n private _moveFocus(dir: 1 | -1): void {\n if (!this._el) return;\n const btns = Array.from(\n this._el.querySelectorAll<HTMLButtonElement>('.og-cm-item:not(.og-cm-disabled)')\n );\n if (!btns.length) return;\n this._focusIdx = (this._focusIdx + dir + btns.length) % btns.length;\n btns[this._focusIdx]?.focus();\n }\n\n // ── 액션 실행 ─────────────────────────────────────────────\n\n private _runAction(item: ContextMenuItem): void {\n if (typeof item.action === 'function') { item.action(); return; }\n switch (item.action) {\n case 'sortAsc': this._actions.onSortAsc(); break;\n case 'sortDesc': this._actions.onSortDesc(); break;\n case 'find': this._actions.onFind(); break;\n case 'excel': this._actions.onExcel(); break;\n case 'csv': this._actions.onCsv(); break;\n case 'print': this._actions.onPrint(); break;\n }\n }\n}\n","// ============================================================\n// WorksheetManager — 그리드 다중 워크시트(탭) 관리자\n// 레이어: Orchestration (시트 상태 관리 + 탭 UI 조율)\n// 설계 근거(Why): OpenGrid 내부에 _wsManager로 보유.\n// 시트별로 독립적인 columns + data를 Map으로 관리하고,\n// 탭 클릭 시 OpenGrid.setData/applyColumns로 화면 전환.\n// 탭 UI는 그리드 컨테이너 하단에 .og-sheet-tabs 영역으로 삽입.\n// ============================================================\n\nimport type { ColumnDef, WorksheetDef, WorksheetState } from './types.js';\n\nexport type SwitchCallback<T> = (name: string, state: WorksheetState<T>) => void;\n\nexport class WorksheetManager<T extends Record<string, any> = any> {\n private _sheets: Map<string, WorksheetState<T>> = new Map();\n private _active: string = '';\n private _tabBar: HTMLElement;\n private _onSwitch: SwitchCallback<T>;\n\n constructor(container: HTMLElement, onSwitch: SwitchCallback<T>) {\n this._onSwitch = onSwitch;\n this._tabBar = this._buildTabBar(container);\n }\n\n // ── 시트 CRUD ────────────────────────────────────────────\n\n add(name: string, columns: ColumnDef<T>[] = [], data: T[] = []): void {\n if (this._sheets.has(name)) {\n throw new Error(`WorksheetManager: 시트 '${name}'이 이미 존재합니다`);\n }\n this._sheets.set(name, { name, columns, data });\n this._renderTabs();\n\n // 첫 시트는 자동 활성\n if (this._sheets.size === 1) this.switch(name);\n }\n\n remove(name: string): void {\n if (!this._sheets.has(name)) return;\n if (this._sheets.size === 1) {\n throw new Error('WorksheetManager: 마지막 시트는 삭제할 수 없습니다');\n }\n const wasActive = this._active === name;\n this._sheets.delete(name);\n this._renderTabs();\n\n if (wasActive) {\n // 삭제 후 첫 번째 남은 시트로 전환\n this.switch(this._sheets.keys().next().value!);\n }\n }\n\n rename(oldName: string, newName: string): void {\n if (!this._sheets.has(oldName)) return;\n if (this._sheets.has(newName)) {\n throw new Error(`WorksheetManager: 시트 '${newName}'이 이미 존재합니다`);\n }\n const state = this._sheets.get(oldName)!;\n // Map 순서 유지를 위해 재삽입\n const entries = Array.from(this._sheets.entries()).map(([k, v]) =>\n k === oldName ? [newName, { ...v, name: newName }] as [string, WorksheetState<T>] : [k, v] as [string, WorksheetState<T>]\n );\n this._sheets = new Map(entries);\n if (this._active === oldName) this._active = newName;\n this._renderTabs();\n }\n\n switch(name: string): void {\n const state = this._sheets.get(name);\n if (!state) throw new Error(`WorksheetManager: 시트 '${name}'을 찾을 수 없습니다`);\n this._active = name;\n this._renderTabs();\n this._onSwitch(name, state);\n }\n\n get(name: string): WorksheetState<T> | undefined {\n return this._sheets.get(name);\n }\n\n getNames(): string[] {\n return Array.from(this._sheets.keys());\n }\n\n getActive(): string { return this._active; }\n\n /** 현재 활성 시트의 data를 갱신 (그리드 편집 동기화용) */\n syncData(name: string, data: T[]): void {\n const state = this._sheets.get(name);\n if (state) state.data = data;\n }\n\n destroy(): void {\n this._tabBar.remove();\n }\n\n // ── 탭 UI ────────────────────────────────────────────────\n\n private _buildTabBar(container: HTMLElement): HTMLElement {\n const bar = document.createElement('div');\n bar.className = 'og-sheet-tabs';\n container.appendChild(bar);\n return bar;\n }\n\n private _renderTabs(): void {\n this._tabBar.innerHTML = '';\n\n for (const name of this._sheets.keys()) {\n const tab = document.createElement('button');\n tab.className = 'og-sheet-tab';\n tab.textContent = name;\n tab.setAttribute('role', 'tab');\n tab.setAttribute('aria-selected', name === this._active ? 'true' : 'false');\n if (name === this._active) tab.classList.add('og-sheet-tab--active');\n\n // 단순 클릭: 시트 전환\n tab.addEventListener('click', () => {\n if (name !== this._active) this.switch(name);\n });\n\n // 더블클릭: 인라인 이름 변경\n tab.addEventListener('dblclick', () => this._startRename(tab, name));\n\n this._tabBar.appendChild(tab);\n }\n\n // '+' 새 시트 버튼\n const addBtn = document.createElement('button');\n addBtn.className = 'og-sheet-add';\n addBtn.textContent = '+';\n addBtn.setAttribute('aria-label', '새 워크시트 추가');\n addBtn.addEventListener('click', () => {\n const n = `Sheet${this._sheets.size + 1}`;\n this.add(n, [], []);\n this.switch(n);\n });\n this._tabBar.appendChild(addBtn);\n }\n\n /** 탭 더블클릭 → input으로 전환해 이름 변경 */\n private _startRename(tab: HTMLButtonElement, oldName: string): void {\n const input = document.createElement('input');\n input.className = 'og-sheet-tab-rename';\n input.value = oldName;\n tab.replaceWith(input);\n input.focus();\n input.select();\n\n const commit = () => {\n const newName = input.value.trim() || oldName;\n try {\n if (newName !== oldName) this.rename(oldName, newName);\n else this._renderTabs();\n } catch {\n this._renderTabs();\n }\n };\n\n input.addEventListener('blur', commit);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') { input.blur(); }\n if (e.key === 'Escape') { input.value = oldName; input.blur(); }\n });\n }\n}\n","import { ColumnLayout } from './ColumnLayout.js';\nimport { _downloadText } from './GridRenderer.js';\nimport { applyMask } from './MaskingEngine.js';\nimport type { WorksheetManager } from './WorksheetManager.js';\nimport type { ExportOptions } from './types.js';\n\nexport interface ExportDeps<T extends Record<string, any>> {\n getData: () => T[];\n getColLayout: () => ColumnLayout<T>;\n getColWidths: () => number[];\n getOptions: () => any;\n getContainer: () => HTMLElement;\n getMaskEnabled: (field: string) => boolean;\n getWsManager: () => WorksheetManager<T> | null;\n /** Phase 2: OverrideKernel.getStrategy 주입(슬롯 cellSerializer 도달용). */\n getStrategy?: <F extends Function>(slot: string, fallback: F) => F;\n}\n\nexport class ExportManager<T extends Record<string, any> = any> {\n private _d: ExportDeps<T>;\n\n constructor(deps: ExportDeps<T>) {\n this._d = deps;\n }\n\n private _readCssVar(name: string): string {\n return getComputedStyle(this._d.getContainer()).getPropertyValue(name).trim();\n }\n\n private _hexToXlsxRgb(hex: string): string {\n const s = hex.trim();\n const rgbMatch = s.match(/^rgba?\\(\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)/i);\n if (rgbMatch) {\n return [rgbMatch[1], rgbMatch[2], rgbMatch[3]]\n .map(n => parseInt(n).toString(16).padStart(2, '0'))\n .join('').toUpperCase();\n }\n const h = s.replace('#', '').toUpperCase();\n if (h.length === 3) return h[0]+h[0]+h[1]+h[1]+h[2]+h[2];\n return h.length === 6 ? h : '';\n }\n\n exportExcel(options?: ExportOptions | string): void {\n const opts = typeof options === 'string' ? { filename: options } : (options ?? {});\n let fname = opts.filename ?? 'export';\n if (!fname.toLowerCase().endsWith('.xlsx')) fname += '.xlsx';\n const sheetName = opts.sheetName ?? (this._d.getOptions().ariaLabel || 'Sheet1');\n const data = this._d.getData();\n const cols = this._d.getColLayout().visibleLeaves.filter(c => !opts.exceptFields?.includes(c.field));\n const includeHeader = opts.includeHeader !== false;\n\n // Phase 2 슬롯 #4: cellSerializer. default = 현행 인라인(number→v, boolean→✓, object→'', else String).\n const serialize = (this._d.getStrategy ?? ((_s: string, fb: any) => fb))(\n 'cellSerializer',\n (v: any, col: any, _row: any): any => {\n if (col.type === 'number' && typeof v === 'number') return v;\n if (typeof v === 'boolean') return v ? '✓' : '';\n if (typeof v === 'object') return '';\n return String(v);\n },\n );\n\n import('xlsx-js-style').then(({ utils, writeFile }) => {\n const rows: any[][] = [];\n if (includeHeader) rows.push(cols.map(c => c.header));\n for (const row of data) {\n rows.push(cols.map(c => {\n const raw = (row as any)[c.field];\n if (opts.maskOnExport && c.mask && this._d.getMaskEnabled(c.field)) {\n return applyMask(raw == null ? '' : String(raw), c.mask);\n }\n const v = raw;\n if (v == null || v === '') return '';\n return serialize(v, c, row);\n }));\n }\n\n const ws = utils.aoa_to_sheet(rows);\n\n const colWidths = this._d.getColWidths();\n const colLayout = this._d.getColLayout();\n ws['!cols'] = cols.map(c => ({\n wpx: colWidths[colLayout.getColumnIndex(c.field)] ?? 100,\n }));\n ws['!rows'] = rows.map((_, ri) => ({ hpx: ri === 0 && includeHeader ? 22 : 19 }));\n\n const styleMode = opts.styleMode ?? 'theme';\n let hdrBgRgb = '1565C0', hdrFgRgb = 'FFFFFF';\n let rowBgRgb = 'FFFFFF', rowAltRgb = 'EEF2FF';\n let rowFgRgb = '212121', borderRgb = 'BDBDBD';\n let fontSize = 10;\n\n if (styleMode === 'theme') {\n const toRgb = (v: string) => this._hexToXlsxRgb(v);\n hdrBgRgb = toRgb(this._readCssVar('--og-header-bg')) || hdrBgRgb;\n hdrFgRgb = toRgb(this._readCssVar('--og-header-color')) || hdrFgRgb;\n rowBgRgb = toRgb(this._readCssVar('--og-row-bg')) || rowBgRgb;\n rowAltRgb = toRgb(this._readCssVar('--og-row-alt-bg')) || rowAltRgb;\n rowFgRgb = toRgb(this._readCssVar('--og-row-color')) || rowFgRgb;\n borderRgb = toRgb(this._readCssVar('--og-border-color')) || borderRgb;\n const fsStr = this._readCssVar('--og-font-size');\n if (fsStr) fontSize = Math.max(8, Math.round(parseFloat(fsStr) * 0.75));\n }\n\n const noStyle = styleMode === 'none';\n const S = {\n hdrFont: noStyle ? {} : { bold: true, color: { rgb: hdrFgRgb }, sz: fontSize, name: '맑은 고딕' },\n dataFont: noStyle ? {} : { sz: fontSize, color: { rgb: rowFgRgb }, name: '맑은 고딕' },\n hdrFill: noStyle ? {} : { patternType: 'solid' as const, fgColor: { rgb: hdrBgRgb } },\n evenFill: noStyle ? {} : { patternType: 'solid' as const, fgColor: { rgb: rowBgRgb } },\n oddFill: noStyle ? {} : { patternType: 'solid' as const, fgColor: { rgb: rowAltRgb } },\n hdrBorder: noStyle ? {} : {\n top: { style: 'medium', color: { rgb: hdrBgRgb } },\n bottom: { style: 'medium', color: { rgb: hdrBgRgb } },\n left: { style: 'thin', color: { rgb: hdrBgRgb } },\n right: { style: 'thin', color: { rgb: hdrBgRgb } },\n },\n dataBorder: noStyle ? {} : {\n top: { style: 'thin', color: { rgb: borderRgb } },\n bottom: { style: 'thin', color: { rgb: borderRgb } },\n left: { style: 'thin', color: { rgb: borderRgb } },\n right: { style: 'thin', color: { rgb: borderRgb } },\n },\n };\n\n rows.forEach((row, ri) => {\n const isHdr = includeHeader && ri === 0;\n const dataRi = includeHeader ? ri - 1 : ri;\n const isEven = dataRi % 2 === 0;\n\n row.forEach((_v, ci) => {\n const addr = utils.encode_cell({ r: ri, c: ci });\n if (!ws[addr]) ws[addr] = { t: 's', v: '' };\n\n const col = cols[ci]!;\n const isNum = col.type === 'number' || col.align === 'right';\n const hAlign = isHdr ? 'center' : isNum ? 'right' : (col.align ?? 'left');\n\n ws[addr].s = {\n font: isHdr ? S.hdrFont : S.dataFont,\n fill: isHdr ? S.hdrFill : (isEven ? S.evenFill : S.oddFill),\n border: isHdr ? S.hdrBorder : S.dataBorder,\n alignment: { horizontal: hAlign, vertical: 'center', wrapText: false },\n };\n });\n });\n\n const wb = utils.book_new();\n utils.book_append_sheet(wb, ws, sheetName);\n writeFile(wb, fname, { cellStyles: true } as any);\n opts.onAfter?.(new Blob([]));\n }).catch(() => {\n console.error('Excel 내보내기 실패: xlsx 패키지를 확인하세요.');\n });\n }\n\n exportCsv(options?: ExportOptions | string): void {\n const opts = typeof options === 'string' ? { filename: options } : (options ?? {});\n const data = this._d.getData();\n const cols = this._d.getColLayout().visibleLeaves;\n const hdr = cols.map(c => `\"${c.header}\"`).join(',');\n const rows = data.map(row => cols.map(c => {\n const raw = row[c.field] ?? '';\n if (opts.maskOnExport && c.mask && this._d.getMaskEnabled(c.field)) {\n return applyMask(String(raw), c.mask);\n }\n const v = raw;\n return typeof v === 'string' && v.includes(',') ? `\"${v}\"` : v;\n }).join(','));\n const fname = opts.filename ?? 'export.csv';\n _downloadText('' + [hdr, ...rows].join('\\n'), fname);\n }\n\n exportJson(options?: ExportOptions | string): void {\n const fname = typeof options === 'string' ? options : (options?.filename ?? 'export.json');\n _downloadText(JSON.stringify(this._d.getData(), null, 2), fname, 'application/json');\n }\n\n print(options?: { title?: string; excludeFields?: string[]; footerText?: string }): void {\n const title = options?.title ?? 'OPEN_GRID';\n const footerText = options?.footerText ?? '';\n const data = this._d.getData();\n const cols = this._d.getColLayout().visibleLeaves\n .filter(c => !options?.excludeFields?.includes(c.field));\n\n const headerRow = cols.map(c => `<th>${c.header ?? c.field}</th>`).join('');\n const bodyRows = data.map(row =>\n `<tr>${cols.map(c => `<td>${String(row[c.field] ?? '')}</td>`).join('')}</tr>`\n ).join('');\n const footerHtml = footerText\n ? `<div class=\"og-print-footer\">${footerText}</div>`\n : '';\n\n const html = `<!DOCTYPE html>\n<html lang=\"ko\"><head>\n<meta charset=\"UTF-8\"><title>${title}</title>\n<style>\n @page{margin:0;}\n body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:12px;margin:0;padding:1cm;}\n h2{margin:0 0 10px;font-size:14px;color:#333;}\n p{margin:0 0 8px;font-size:11px;color:#999;}\n table{border-collapse:collapse;width:100%;}\n th,td{border:1px solid #ccc;padding:5px 8px;text-align:left;white-space:nowrap;}\n th{background:#f5f5f5;font-weight:600;color:#333;}\n tr:nth-child(even) td{background:#fafafa;}\n .og-print-footer{position:fixed;bottom:0;left:0;right:0;padding:6px 1cm;font-size:10px;color:#888;border-top:1px solid #e5e7eb;background:#fff;text-align:center;}\n</style>\n</head><body>\n<h2>${title}</h2>\n<p>${data.length}행 × ${cols.length}열 · ${new Date().toLocaleString('ko-KR')}</p>\n<table>\n <thead><tr>${headerRow}</tr></thead>\n <tbody>${bodyRows}</tbody>\n</table>\n${footerHtml}\n<script>window.addEventListener('load',()=>{window.print();window.addEventListener('afterprint',()=>window.close());});<\\/script>\n</body></html>`;\n\n const win = window.open('', '_blank', 'width=960,height=640');\n if (win) { win.document.write(html); win.document.close(); }\n }\n\n exportSheetsExcel(filename?: string): void {\n const wsManager = this._d.getWsManager();\n if (!wsManager) { this.exportExcel(filename ?? 'workbook'); return; }\n const fname = filename ?? 'workbook.xlsx';\n\n // Phase 2 슬롯 #4: cellSerializer(시트 직렬화 지점). default = 현행 인라인.\n const serialize = (this._d.getStrategy ?? ((_s: string, fb: any) => fb))(\n 'cellSerializer',\n (v: any, col: any, _row: any): any => {\n if (typeof v === 'boolean') return v ? '✓' : '';\n return col.type === 'number' && typeof v === 'number' ? v : String(v);\n },\n );\n\n import('xlsx-js-style').then(({ utils, writeFile }) => {\n const wb = utils.book_new();\n const opts = this._d.getOptions();\n for (const name of wsManager.getNames()) {\n const state = wsManager.get(name)!;\n const cols = state.columns.length ? state.columns : opts.columns;\n const rows: any[][] = [cols.map((c: any) => c.header)];\n for (const row of state.data) {\n rows.push(cols.map((c: any) => {\n const v = (row as any)[c.field];\n if (v == null) return '';\n return serialize(v, c, row);\n }));\n }\n const ws = utils.aoa_to_sheet(rows);\n ws['!cols'] = cols.map(() => ({ wpx: 100 }));\n utils.book_append_sheet(wb, ws, name);\n }\n writeFile(wb, fname.endsWith('.xlsx') ? fname : fname + '.xlsx', { cellStyles: true } as any);\n }).catch(() => console.error('exportSheetsExcel: xlsx 패키지를 확인하세요.'));\n }\n}\n","import { ColumnLayout } from './ColumnLayout.js';\nimport { OGDecimal } from './OGDecimal.js';\n\nexport interface FooterDeps<T extends Record<string, any>> {\n getData: () => T[];\n getColLayout: () => ColumnLayout<T>;\n getColWidths: () => number[];\n getOptions: () => any;\n getContainer: () => HTMLElement;\n /** Phase 2: OverrideKernel.getStrategy 주입(슬롯 summaryOp 도달용). */\n getStrategy?: <F extends Function>(slot: string, fallback: F) => F;\n}\n\nexport class FooterManager<T extends Record<string, any> = any> {\n private _d: FooterDeps<T>;\n\n constructor(deps: FooterDeps<T>) {\n this._d = deps;\n }\n\n fmtNum(value: number, fmt?: string): string {\n if (!fmt) {\n return Math.round(value).toLocaleString('ko-KR');\n }\n // 통화 기호 등 접두/접미 분리 (숫자 토큰: #,0,콤마,소수 또는 레거시 정수)\n const tok = fmt.match(/[#0][#0,]*(?:\\.[#0]+)?|\\d+/);\n const prefix = tok ? fmt.slice(0, tok.index) : '';\n const suffix = tok ? fmt.slice(tok.index! + tok[0].length) : '';\n const numFmt = tok ? tok[0] : fmt;\n\n const useComma = numFmt.includes('#') || numFmt.includes(',');\n const dpMatch = numFmt.match(/\\.(\\d+)$/);\n const dp = dpMatch\n ? parseInt(dpMatch[1]!, 10)\n : /^\\d+$/.test(numFmt) ? parseInt(numFmt, 10) : 0;\n\n const fixed = Math.abs(value).toFixed(dp);\n const [intPart = '0', decPart] = fixed.split('.');\n const intStr = useComma\n ? intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n : intPart;\n\n const body = decPart !== undefined ? `${intStr}.${decPart}` : intStr;\n const result = `${prefix}${body}${suffix}`;\n return value < 0 ? `-${result}` : result;\n }\n\n computeValues(): any[] {\n const footerDefs = this._d.getOptions().footer;\n if (!footerDefs || footerDefs.length === 0) return [];\n\n const allData = this._d.getData();\n\n return footerDefs\n .filter((d: any) => d.field && d.op)\n .map((def: any) => {\n const field = def.field!;\n const op = def.op!;\n const nums = allData\n .map((r: any) => r[field])\n .filter((v: any) => v !== null && v !== undefined && v !== '');\n\n let result: OGDecimal | null = null;\n const opUC = (op as string).toUpperCase();\n\n // Phase 2 슬롯 #6: summaryOp. default = null(미가로챔 → 기존 SUM/AVG/COUNT/MAX/MIN switch).\n // 슬롯이 number 반환 시 그 값을 사용(MEDIAN/STDEV 등만 가로챔), null 반환 시 기본 분기 폴백.\n const customOp = (this._d.getStrategy ?? ((_s: string, fb: any) => fb))(\n 'summaryOp',\n null as ((op: string, nums: any[], field: string) => number | null) | null,\n );\n if (customOp) {\n const cv = customOp(opUC, nums, field);\n if (cv != null) {\n return { _field: field, _value: cv, _formatted: this.fmtNum(cv, def.format) };\n }\n }\n\n if (opUC === 'SUM') {\n result = nums.length > 0 ? OGDecimal.sum(nums.map((v: any) => String(v))) : null;\n } else if (opUC === 'AVG') {\n result = nums.length > 0\n ? OGDecimal.sum(nums.map((v: any) => String(v))).div(OGDecimal.from(String(nums.length)))\n : null;\n } else if (opUC === 'COUNT') {\n const cnt = nums.length;\n return { _field: field, _value: cnt, _formatted: cnt.toLocaleString('ko-KR') };\n } else if (opUC === 'MAX') {\n result = nums.length > 0 ? OGDecimal.max(nums.map((v: any) => String(v))) : null;\n } else if (opUC === 'MIN') {\n result = nums.length > 0 ? OGDecimal.min(nums.map((v: any) => String(v))) : null;\n }\n\n if (!result) return { _field: field, _value: null, _formatted: '' };\n\n const numVal = result.toNumber();\n const formatted = this.fmtNum(numVal, def.format);\n return { _field: field, _value: numVal, _formatted: formatted };\n });\n }\n\n render(): void {\n const container = this._d.getContainer();\n const old = container.querySelector('.og-footer-bar');\n old?.remove();\n\n const opts = this._d.getOptions();\n const footerDefs = opts.footer;\n if (!footerDefs || footerDefs.length === 0) return;\n\n const leaves = this._d.getColLayout().visibleLeaves;\n const widths = this._d.getColWidths() ?? leaves.map((l: any) => l.width ?? 100);\n const valMap = new Map(\n this.computeValues().map((v: any) => [v._field, v])\n );\n\n const bar = document.createElement('div');\n bar.className = 'og-footer-bar';\n bar.style.cssText = [\n 'display:flex;align-items:stretch;',\n `min-height:${opts.footerHeight}px;`,\n 'border-top:2px solid var(--og-primary,#1976d2);',\n 'background:var(--og-header-bg,#f5f5f5);',\n 'overflow:hidden;flex-shrink:0;font-size:13px;font-weight:600;',\n ].join('');\n\n let extraW = 0;\n if (opts.stateColumn) extraW += 24;\n if (opts.draggable) extraW += 18;\n if (opts.rowNumber) extraW += 44;\n if (opts.checkColumn) extraW += 36;\n if (extraW > 0) {\n const spacer = document.createElement('div');\n spacer.style.cssText = `width:${extraW}px;flex-shrink:0;border-right:1px solid var(--og-border-color,#e0e0e0);`;\n bar.appendChild(spacer);\n }\n\n let leafCursor = 0;\n\n for (const def of footerDefs) {\n const colspan = Math.max(1, def.colspan ?? 1);\n\n let cellW = 0;\n for (let c = 0; c < colspan; c++) {\n cellW += widths[leafCursor + c] ?? 100;\n }\n const targetLeaf = leaves[leafCursor];\n leafCursor += colspan;\n\n const cell = document.createElement('div');\n cell.style.cssText = [\n `width:${cellW}px;min-width:${cellW}px;flex-shrink:0;`,\n 'padding:4px 8px;box-sizing:border-box;overflow:hidden;',\n 'border-right:1px solid var(--og-border-color,#e0e0e0);',\n 'white-space:nowrap;text-overflow:ellipsis;',\n ].join('');\n\n const field = def.field;\n const val = field ? valMap.get(field) : null;\n\n if (val) {\n const displayVal = val._formatted ?? String(val._value ?? '');\n const prefix = def.label ? `${def.label}: ` : '';\n cell.textContent = prefix + displayVal;\n cell.title = `${(def.op as string)?.toUpperCase() ?? ''} = ${displayVal}`;\n cell.style.color = 'var(--og-primary,#1976d2)';\n cell.style.textAlign = def.align ?? (targetLeaf?.type === 'number' ? 'right' : 'right');\n } else if (def.label) {\n cell.textContent = def.label;\n cell.style.textAlign = def.align ?? 'left';\n cell.style.color = 'var(--og-row-color,#212121)';\n }\n\n bar.appendChild(cell);\n }\n\n if (opts.footerPosition === 'top') {\n container.insertBefore(bar, container.firstChild);\n } else {\n container.appendChild(bar);\n }\n }\n}\n","import type { DataLayer } from './DataLayer.js';\nimport type { ColumnLayout } from './ColumnLayout.js';\nimport type { CellEditManager } from './CellEditManager.js';\nimport type { RowManager } from './RowManager.js';\n\nexport interface KeyboardDeps<T extends Record<string, any>> {\n getEditMgr: () => CellEditManager<T>;\n getRowMgr: () => RowManager<T>;\n getData: () => DataLayer<T>;\n getColLayout: () => ColumnLayout<T>;\n getOptions: () => any;\n setFocusCell: (ri: number, ci: number) => void;\n handleRowDrop: (from: number, to: number) => void;\n doRender: () => void;\n announce: (msg: string) => void;\n emit: (event: string, ...args: any[]) => void;\n visRange: () => [number, number];\n handleCellKeyEvt: (eventName: 'cellKeyDown' | 'cellKeyUp' | 'cellKeyPress', e: KeyboardEvent) => void;\n}\n\nexport class KeyboardManager<T extends Record<string, any> = any> {\n private _d: KeyboardDeps<T>;\n\n constructor(deps: KeyboardDeps<T>) {\n this._d = deps;\n }\n\n handleKeyDown(e: KeyboardEvent): void {\n const editMgr = this._d.getEditMgr();\n if (editMgr.activeEditor) return;\n\n this._d.handleCellKeyEvt('cellKeyDown', e);\n\n const data = this._d.getData();\n const colLayout = this._d.getColLayout();\n const totalRows = data.rowCount;\n const totalCols = colLayout.visibleLeaves.length;\n if (totalRows === 0 || totalCols === 0) return;\n\n if ((e.ctrlKey || e.metaKey) && e.key === 'c') {\n e.preventDefault();\n this._copyToClipboard();\n return;\n }\n if ((e.ctrlKey || e.metaKey) && e.key === 'v') {\n e.preventDefault();\n this._pasteFromClipboard();\n return;\n }\n\n const opts = this._d.getOptions();\n if ((e.ctrlKey || e.metaKey) && opts.draggable && editMgr.focusCell) {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n const ri = editMgr.focusCell.ci !== undefined ? editMgr.focusCell.ri : 0;\n if (ri < totalRows - 1) {\n this._d.handleRowDrop(ri, ri + 1);\n this._d.setFocusCell(ri + 1, editMgr.focusCell.ci);\n this._d.announce(`행 ${ri + 1}을(를) ${ri + 2}번째 위치로 이동`);\n }\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n const ri = editMgr.focusCell.ri;\n if (ri > 0) {\n this._d.handleRowDrop(ri, ri - 1);\n this._d.setFocusCell(ri - 1, editMgr.focusCell.ci);\n this._d.announce(`행 ${ri + 1}을(를) ${ri}번째 위치로 이동`);\n }\n return;\n }\n }\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const nextRi = cur ? Math.min(cur.ri + 1, totalRows - 1) : 0;\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const nextRi = cur ? Math.max(cur.ri - 1, 0) : 0;\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case 'ArrowRight': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n if (!cur) { this._d.setFocusCell(0, 0); break; }\n if (cur.ci < totalCols - 1) {\n this._d.setFocusCell(cur.ri, cur.ci + 1);\n } else if (cur.ri < totalRows - 1) {\n this._d.setFocusCell(cur.ri + 1, 0);\n }\n break;\n }\n case 'ArrowLeft': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n if (!cur) { this._d.setFocusCell(0, 0); break; }\n if (cur.ci > 0) {\n this._d.setFocusCell(cur.ri, cur.ci - 1);\n } else if (cur.ri > 0) {\n this._d.setFocusCell(cur.ri - 1, totalCols - 1);\n }\n break;\n }\n case 'Tab': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n if (!cur) { this._d.setFocusCell(0, 0); break; }\n if (!e.shiftKey) {\n if (cur.ci < totalCols - 1) this._d.setFocusCell(cur.ri, cur.ci + 1);\n else if (cur.ri < totalRows - 1) this._d.setFocusCell(cur.ri + 1, 0);\n } else {\n if (cur.ci > 0) this._d.setFocusCell(cur.ri, cur.ci - 1);\n else if (cur.ri > 0) this._d.setFocusCell(cur.ri - 1, totalCols - 1);\n }\n break;\n }\n case 'Home': {\n e.preventDefault();\n if (e.ctrlKey || e.metaKey) {\n this._d.setFocusCell(0, 0);\n } else {\n const cur = editMgr.focusCell;\n this._d.setFocusCell(cur?.ri ?? 0, 0);\n }\n break;\n }\n case 'End': {\n e.preventDefault();\n if (e.ctrlKey || e.metaKey) {\n this._d.setFocusCell(totalRows - 1, totalCols - 1);\n } else {\n const cur = editMgr.focusCell;\n this._d.setFocusCell(cur?.ri ?? 0, totalCols - 1);\n }\n break;\n }\n case 'PageDown': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const step = this._d.getOptions().pageSize ?? 10;\n const nextRi = cur ? Math.min(cur.ri + step, totalRows - 1) : Math.min(step - 1, totalRows - 1);\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case 'PageUp': {\n e.preventDefault();\n const cur = editMgr.focusCell;\n const step = this._d.getOptions().pageSize ?? 10;\n const nextRi = cur ? Math.max(cur.ri - step, 0) : 0;\n this._d.setFocusCell(nextRi, cur?.ci ?? 0);\n break;\n }\n case ' ': {\n if (editMgr.focusCell) {\n e.preventDefault();\n const ri = editMgr.focusCell.ri;\n const rowMgr = this._d.getRowMgr();\n if (this._d.getOptions().checkColumn) {\n rowMgr.check(ri, !rowMgr.checkedRows.has(ri));\n this._d.doRender();\n } else {\n rowMgr.selectToggle(ri);\n this._d.doRender();\n }\n }\n break;\n }\n case 'F2':\n case 'Enter': {\n if (editMgr.focusCell && this._d.getOptions().editable) {\n e.preventDefault();\n editMgr.startEditByKey(editMgr.focusCell.ri, editMgr.focusCell.ci);\n }\n break;\n }\n case 'Escape': {\n editMgr.clearFocusCell();\n this._d.doRender();\n break;\n }\n }\n }\n\n private _copyToClipboard(): void {\n const opts = this._d.getOptions();\n if (!opts.clipboard) return;\n\n const editMgr = this._d.getEditMgr();\n const colLayout = this._d.getColLayout();\n const data = this._d.getData();\n\n let text = '';\n if (editMgr.focusCell) {\n const { ri, ci } = editMgr.focusCell;\n const col = colLayout.visibleLeaves[ci];\n if (col) text = String(data.getCellValue(ri, col.field) ?? '');\n } else if (this._d.getRowMgr().selectedRows.size > 0) {\n const cols = colLayout.visibleLeaves;\n const rowTexts = [...this._d.getRowMgr().selectedRows].sort((a, b) => a - b).map(ri => {\n const row = data.getRowByIndex(ri);\n return cols.map(c => String(row?.[c.field] ?? '')).join('\\t');\n });\n text = rowTexts.join('\\n');\n }\n\n if (text) navigator.clipboard?.writeText(text).catch(() => {});\n }\n\n private _pasteFromClipboard(): void {\n const opts = this._d.getOptions();\n if (!opts.clipboard || !opts.editable) return;\n\n const editMgr = this._d.getEditMgr();\n if (!editMgr.focusCell) return;\n\n navigator.clipboard?.readText().then(text => {\n if (!text) return;\n const { ri, ci } = editMgr.focusCell!;\n const lines = text.split('\\n');\n const cols = this._d.getColLayout().visibleLeaves;\n const data = this._d.getData();\n\n for (let dr = 0; dr < lines.length; dr++) {\n const cells = lines[dr]!.split('\\t');\n for (let dc = 0; dc < cells.length; dc++) {\n const targetRi = ri + dr;\n const targetCi = ci + dc;\n const col = cols[targetCi];\n if (col && targetRi < data.rowCount) {\n data.updateCell(targetRi, col.field, cells[dc]);\n }\n }\n }\n this._d.emit('dataChange', data.getData());\n this._d.doRender();\n }).catch(() => {});\n }\n}\n","import type { ColumnLayout } from './ColumnLayout.js';\nimport type { DataLayer } from './DataLayer.js';\nimport type { Pagination } from './Pagination.js';\nimport type { VirtualScroll } from './VirtualScroll.js';\n\nexport interface FindBarDeps<T extends Record<string, any>> {\n getColLayout: () => ColumnLayout<T>;\n getData: () => DataLayer<T>;\n getFilters: () => Record<string, any[]>;\n getVs: () => VirtualScroll | null;\n getPagination: () => Pagination | null;\n doRender: () => void;\n}\n\nexport class FindBarManager<T extends Record<string, any> = any> {\n private _bar: HTMLElement | null = null;\n private _input: HTMLInputElement | null = null;\n private _count: HTMLElement | null = null;\n private _filter: string = '';\n private _d: FindBarDeps<T>;\n\n constructor(deps: FindBarDeps<T>) {\n this._d = deps;\n }\n\n get findFilter(): string { return this._filter; }\n\n init(container: HTMLElement): void {\n const bar = document.createElement('div');\n bar.className = 'og-find-bar';\n bar.hidden = true;\n\n const lbl = document.createElement('span');\n lbl.className = 'og-find-label';\n lbl.textContent = '찾기';\n\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'og-find-input';\n input.placeholder = '검색어 입력...';\n input.setAttribute('aria-label', '그리드 내 검색');\n\n const count = document.createElement('span');\n count.className = 'og-find-count';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'og-find-close';\n closeBtn.textContent = '✕';\n closeBtn.setAttribute('aria-label', '찾기 닫기');\n\n bar.appendChild(lbl);\n bar.appendChild(input);\n bar.appendChild(count);\n bar.appendChild(closeBtn);\n\n container.insertBefore(bar, container.firstChild);\n\n input.addEventListener('input', () => {\n this._filter = input.value.trim();\n this._apply();\n });\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') this.close();\n });\n closeBtn.addEventListener('click', () => this.close());\n\n this._bar = bar;\n this._input = input;\n this._count = count;\n }\n\n open(): void {\n if (!this._bar) return;\n this._bar.hidden = false;\n this._input!.focus();\n this._input!.select();\n }\n\n close(): void {\n if (!this._bar) return;\n this._bar.hidden = true;\n this._filter = '';\n this._input!.value = '';\n if (this._count) this._count.textContent = '';\n this._apply();\n }\n\n private _apply(): void {\n const data = this._d.getData();\n const fields = this._d.getColLayout().visibleLeaves.map(c => c.field);\n data.setFindFilter(this._filter, fields);\n data.applyFilter(this._d.getFilters());\n const n = data.rowCount;\n this._d.getVs()?.setTotalRows(n);\n this._d.getPagination()?.setTotalRows(n);\n if (this._count) this._count.textContent = this._filter ? `${n}건` : '';\n this._d.doRender();\n }\n}\n","import type { SummaryOp } from './types.js';\nimport { OGDecimal } from './OGDecimal.js';\n\nexport interface GroupRow<T = any> {\n _isGroup: true;\n _groupField: string;\n _groupValue: any;\n _groupLabel: string;\n _depth: number;\n _expanded: boolean;\n _childCount: number;\n _summary: Record<string, any>; // { field → 계산값(number) }\n _summaryFmt: Record<string, string>; // { field → 포맷된 문자열 }\n _states: { added: number; edited: number; removed: number };\n children: Array<GroupRow<T> | T>;\n}\n\nexport type GroupItem<T> = GroupRow<T> | T;\n\nexport interface SummaryDef {\n field: string;\n op: SummaryOp;\n label?: string;\n format?: string; // '#,##0' | '#,##0.00' | '0.00' | '2' 등\n}\n\nfunction _isGroup<T>(item: any): item is GroupRow<T> {\n return item && item._isGroup === true;\n}\n\n/**\n * flat 데이터를 fields 기준으로 계층 그룹핑.\n * Phase 2 슬롯 #5: groupKeyFn(getKey) — 미지정 시 default = `row[field]`(현행 단일 필드 키).\n * GroupTreeManager 가 host.getStrategy 로 주입. ⚠️ 핫패스(행당) — 슬롯 예외 비격리.\n */\nexport function buildGroups<T extends Record<string, any>>(\n data: T[],\n fields: string[],\n summaryDefs: SummaryDef[] = [],\n expandedKeys: Set<string> = new Set(),\n getRowState?: (row: T) => string,\n getKey?: (row: T, remainingFields: string[]) => any\n): GroupRow<T>[] {\n if (!fields.length) return [];\n return _groupByFields(data, fields, 0, summaryDefs, expandedKeys, '', getRowState, getKey);\n}\n\nfunction _groupByFields<T extends Record<string, any>>(\n data: T[],\n fields: string[],\n depth: number,\n summaryDefs: SummaryDef[],\n expandedKeys: Set<string>,\n parentKey: string,\n getRowState?: (row: T) => string,\n getKey?: (row: T, remainingFields: string[]) => any\n): GroupRow<T>[] {\n const field = fields[depth]!;\n const map = new Map<any, T[]>();\n\n for (const row of data) {\n const key = getKey ? getKey(row, fields.slice(depth)) : row[field];\n if (!map.has(key)) map.set(key, []);\n map.get(key)!.push(row);\n }\n\n const result: GroupRow<T>[] = [];\n for (const [value, rows] of map) {\n const groupKey = `${parentKey}__${field}:${value}`;\n const expanded = expandedKeys.has(groupKey);\n\n let children: Array<GroupRow<T> | T>;\n if (depth < fields.length - 1) {\n children = _groupByFields(rows, fields, depth + 1, summaryDefs, expandedKeys, groupKey, getRowState, getKey);\n } else {\n children = rows;\n }\n\n const { summary, summaryFmt } = _calcSummary(rows, summaryDefs);\n const states = _calcStates(rows, getRowState);\n\n result.push({\n _isGroup: true,\n _groupField: field,\n _groupValue: value,\n _groupLabel: value == null ? '(없음)' : String(value),\n _depth: depth,\n _expanded: expanded,\n _childCount: rows.length,\n _summary: summary,\n _summaryFmt: summaryFmt,\n _states: states,\n children,\n } as GroupRow<T>);\n }\n return result;\n}\n\n/** OGDecimal 정밀 계산으로 summary 집계 */\nfunction _calcSummary(\n data: Record<string, any>[],\n defs: SummaryDef[]\n): { summary: Record<string, any>; summaryFmt: Record<string, string> } {\n const summary: Record<string, any> = {};\n const summaryFmt: Record<string, string> = {};\n\n for (const def of defs) {\n const vals = data\n .map(r => r[def.field])\n .filter(v => v !== null && v !== undefined && v !== '');\n\n let result: OGDecimal | null = null;\n const opUC = (def.op as string).toUpperCase();\n\n if (opUC === 'SUM') {\n result = vals.length > 0 ? OGDecimal.sum(vals.map(String)) : null;\n } else if (opUC === 'AVG') {\n result = vals.length > 0\n ? OGDecimal.sum(vals.map(String)).div(OGDecimal.from(String(vals.length)))\n : null;\n } else if (opUC === 'COUNT') {\n summary[def.field] = data.length;\n summaryFmt[def.field] = data.length.toLocaleString('ko-KR');\n continue;\n } else if (opUC === 'MAX') {\n result = vals.length > 0 ? OGDecimal.max(vals.map(String)) : null;\n } else if (opUC === 'MIN') {\n result = vals.length > 0 ? OGDecimal.min(vals.map(String)) : null;\n }\n\n if (!result) { summary[def.field] = null; summaryFmt[def.field] = ''; continue; }\n\n const numVal = result.toNumber();\n summary[def.field] = numVal;\n summaryFmt[def.field] = _fmtNum(numVal, def.format);\n }\n\n return { summary, summaryFmt };\n}\n\n/** 그룹 내 행 편집 상태 집계 */\nfunction _calcStates<T extends Record<string, any>>(\n rows: T[],\n getRowState?: (row: T) => string\n): { added: number; edited: number; removed: number } {\n if (!getRowState) return { added: 0, edited: 0, removed: 0 };\n let added = 0, edited = 0, removed = 0;\n for (const r of rows) {\n const s = getRowState(r);\n if (s === 'added') added++;\n else if (s === 'edited') edited++;\n else if (s === 'removed') removed++;\n }\n return { added, edited, removed };\n}\n\n/**\n * 숫자 포맷팅 (GroupEngine 내부 + 외부 공용)\n * '#,##0' → 천단위 콤마, 정수\n * '#,##0.00' → 천단위 콤마, 소수 2자리\n * '0.00' → 소수 2자리 (콤마 없음)\n * '2' → 소수 2자리 (하위 호환)\n */\nexport function _fmtNum(value: number, fmt?: string): string {\n if (fmt === undefined || fmt === null) {\n return value % 1 === 0\n ? value.toLocaleString('ko-KR')\n : parseFloat(value.toFixed(6)).toLocaleString('ko-KR', {\n minimumFractionDigits: 2, maximumFractionDigits: 6,\n });\n }\n const useComma = fmt.includes('#') || fmt.includes(',');\n const dpMatch = fmt.match(/\\.(\\d+)$/);\n const dp = dpMatch ? parseInt(dpMatch[1]!, 10) : /^\\d+$/.test(fmt) ? parseInt(fmt, 10) : 0;\n\n const fixed = Math.abs(value).toFixed(dp);\n const [intPart = '0', decPart] = fixed.split('.');\n const intStr = useComma\n ? intPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n : intPart;\n const result = decPart !== undefined ? `${intStr}.${decPart}` : intStr;\n return value < 0 ? `-${result}` : result;\n}\n\n/**\n * 그룹 트리를 화면에 표시할 flat 행 배열로 변환.\n * 접힌 그룹(expanded=false)의 자식은 포함하지 않음.\n */\nexport function flattenGroups<T>(groups: GroupRow<T>[]): Array<GroupRow<T> | T> {\n const result: Array<GroupRow<T> | T> = [];\n for (const g of groups) {\n result.push(g);\n if (g._expanded) {\n for (const child of g.children) {\n if (_isGroup(child)) {\n result.push(...flattenGroups([child as GroupRow<T>]));\n } else {\n result.push(child);\n }\n }\n }\n }\n return result;\n}\n\n/** 특정 그룹 키의 펼침 상태를 토글 */\nexport function toggleGroup<T>(\n groups: GroupRow<T>[],\n groupKey: string,\n expandedKeys: Set<string>\n): void {\n if (expandedKeys.has(groupKey)) {\n expandedKeys.delete(groupKey);\n } else {\n expandedKeys.add(groupKey);\n }\n}\n\n/** 모든 그룹 키 수집 */\nexport function collectAllKeys<T>(groups: GroupRow<T>[], parentKey = ''): string[] {\n const keys: string[] = [];\n for (const g of groups) {\n const key = `${parentKey}__${g._groupField}:${g._groupValue}`;\n keys.push(key);\n const nested = g.children.filter((c): c is GroupRow<T> => _isGroup(c));\n if (nested.length) keys.push(...collectAllKeys(nested, key));\n }\n return keys;\n}\n\nexport { _isGroup };\n","export interface TreeNode<T = any> {\n _isTree: true;\n _treeId: any;\n _treeParentId: any;\n _depth: number;\n _expanded: boolean;\n _hasChildren: boolean;\n _childCount: number;\n // 탐색기 스타일 트리 라인 렌더링용 메타\n _isLastChild: boolean; // true → └─ / false → ├─\n _ancestorHasMore: boolean[]; // [d] = true → 깊이 d 조상에 형제가 더 있어 │ 라인 표시\n data: T;\n children: TreeNode<T>[];\n}\n\nexport type TreeItem<T> = TreeNode<T>;\n\nexport function isTreeNode<T>(item: any): item is TreeNode<T> {\n return item != null && item._isTree === true;\n}\n\nexport interface TreeBuildOptions {\n idField: string;\n parentIdField: string;\n expandOnLoad?: boolean;\n}\n\n/**\n * flat 데이터를 트리 구조로 변환.\n * parentId가 null/undefined/''인 행이 루트 노드.\n */\nexport function buildTree<T extends Record<string, any>>(\n data: T[],\n opts: TreeBuildOptions,\n expandedKeys: Set<any> = new Set()\n): TreeNode<T>[] {\n const { idField, parentIdField, expandOnLoad = false } = opts;\n\n const nodeMap = new Map<any, TreeNode<T>>();\n const roots: TreeNode<T>[] = [];\n\n // 1단계: 모든 노드 생성\n for (const row of data) {\n const id = row[idField];\n const node: TreeNode<T> = {\n _isTree: true,\n _treeId: id,\n _treeParentId: row[parentIdField],\n _depth: 0,\n _expanded: expandOnLoad || expandedKeys.has(id),\n _hasChildren: false,\n _childCount: 0,\n _isLastChild: false,\n _ancestorHasMore: [],\n data: row,\n children: [],\n };\n nodeMap.set(id, node);\n }\n\n // 2단계: 부모-자식 연결\n for (const node of nodeMap.values()) {\n const pid = node._treeParentId;\n const isRoot = pid == null || pid === '' || !nodeMap.has(pid);\n if (isRoot) {\n roots.push(node);\n } else {\n const parent = nodeMap.get(pid)!;\n parent.children.push(node);\n parent._hasChildren = true;\n }\n }\n\n // 3단계: 깊이 설정 + childCount\n function assignDepth(nodes: TreeNode<T>[], depth: number): void {\n for (const n of nodes) {\n n._depth = depth;\n n._childCount = _countDescendants(n);\n assignDepth(n.children, depth + 1);\n }\n }\n assignDepth(roots, 0);\n\n // 4단계: 탐색기 라인 메타 (_isLastChild, _ancestorHasMore)\n // parentHasMoreChain[d] = true → 깊이 d 위치에서 아직 형제가 남아있음 → │ 라인\n function assignLineMeta(nodes: TreeNode<T>[], parentHasMoreChain: boolean[]): void {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]!;\n const isLast = i === nodes.length - 1;\n node._isLastChild = isLast;\n node._ancestorHasMore = parentHasMoreChain;\n if (node.children.length > 0) {\n // 자식에게 전달: 이 노드가 마지막이 아니면 자식들 가이드에 │ 표시\n assignLineMeta(node.children, [...parentHasMoreChain, !isLast]);\n }\n }\n }\n assignLineMeta(roots, []);\n\n return roots;\n}\n\nfunction _countDescendants<T>(node: TreeNode<T>): number {\n let count = node.children.length;\n for (const child of node.children) count += _countDescendants(child);\n return count;\n}\n\n/**\n * 트리를 화면에 표시할 flat 배열로 변환.\n * 접힌 노드(_expanded=false)의 자식은 제외.\n */\nexport function flattenTree<T>(nodes: TreeNode<T>[]): TreeNode<T>[] {\n const result: TreeNode<T>[] = [];\n for (const node of nodes) {\n result.push(node);\n if (node._expanded && node.children.length > 0) {\n result.push(...flattenTree(node.children));\n }\n }\n return result;\n}\n\n/** 특정 id 노드의 펼침 상태 토글 */\nexport function toggleTreeNode<T>(\n expandedKeys: Set<any>,\n nodeId: any\n): void {\n if (expandedKeys.has(nodeId)) {\n expandedKeys.delete(nodeId);\n } else {\n expandedKeys.add(nodeId);\n }\n}\n\n/** 모든 노드 id 수집 */\nexport function collectAllTreeIds<T>(nodes: TreeNode<T>[]): any[] {\n const ids: any[] = [];\n for (const n of nodes) {\n ids.push(n._treeId);\n if (n.children.length) ids.push(...collectAllTreeIds(n.children));\n }\n return ids;\n}\n","import { DataLayer } from './DataLayer.js';\nimport { VirtualScroll } from './VirtualScroll.js';\nimport {\n buildGroups, flattenGroups, collectAllKeys,\n type GroupRow, type SummaryDef,\n} from './GroupEngine.js';\nimport {\n buildTree, flattenTree, toggleTreeNode, collectAllTreeIds,\n type TreeNode,\n} from './TreeEngine.js';\n\nexport interface GroupTreeDeps<T extends Record<string, any>> {\n getData: () => T[];\n getDataLayer: () => DataLayer<T>;\n getOptions: () => any;\n getVs: () => VirtualScroll | null;\n doRenderFull: (totalRows: number) => void;\n doRender: () => void;\n /** Phase 2: OverrideKernel.getStrategy 주입(슬롯 groupKeyFn 도달용). */\n getStrategy?: <F extends Function>(slot: string, fallback: F) => F;\n}\n\nexport class GroupTreeManager<T extends Record<string, any> = any> {\n private _groupFields: string[] = [];\n private _groupExpandedKeys: Set<string> = new Set();\n private _groupFlatRows: Array<GroupRow<T> | T> = [];\n private _isGroupMode = false;\n private _treeRoots: TreeNode<T>[] = [];\n private _treeFlatRows: TreeNode<T>[] = [];\n private _treeExpandedKeys: Set<any> = new Set();\n private _isTreeMode = false;\n private _d: GroupTreeDeps<T>;\n\n constructor(deps: GroupTreeDeps<T>) {\n this._d = deps;\n }\n\n // ─── 상태 접근자 ─────────────────────────────────────────\n get isGroupMode(): boolean { return this._isGroupMode; }\n get isTreeMode(): boolean { return this._isTreeMode; }\n get groupFlatRows(): Array<GroupRow<T> | T> { return this._groupFlatRows; }\n get treeFlatRows(): TreeNode<T>[] { return this._treeFlatRows; }\n\n // ─── 그룹 ─────────────────────────────────────────────────\n groupBy(fields: string[]): void {\n this._groupFields = fields;\n this._groupExpandedKeys.clear();\n this._isGroupMode = fields.length > 0;\n this.rebuildGroups();\n }\n\n clearGroup(): void {\n this._groupFields = [];\n this._groupExpandedKeys.clear();\n this._isGroupMode = false;\n this._groupFlatRows = [];\n const n = this._d.getData().length;\n this._d.getVs()?.setTotalRows(n);\n this._d.doRender();\n }\n\n expandAll(): void {\n if (!this._isGroupMode) return;\n const groups = buildGroups(this._d.getData(), this._groupFields, this._getSummaryDefs(), undefined, undefined, this._groupKeyFn());\n collectAllKeys(groups).forEach(k => this._groupExpandedKeys.add(k));\n this.rebuildGroups();\n }\n\n /** Phase 2 슬롯 #5: groupKeyFn resolver. default = undefined(→ GroupEngine 가 row[field] 사용). */\n private _groupKeyFn(): ((row: T, remainingFields: string[]) => any) | undefined {\n return this._d.getStrategy\n ? this._d.getStrategy('groupKeyFn', undefined as any)\n : undefined;\n }\n\n collapseAll(): void {\n this._groupExpandedKeys.clear();\n if (this._isGroupMode) this.rebuildGroups();\n }\n\n handleGroupToggle(groupKey: string): void {\n if (this._groupExpandedKeys.has(groupKey)) {\n this._groupExpandedKeys.delete(groupKey);\n } else {\n this._groupExpandedKeys.add(groupKey);\n }\n this.rebuildGroups();\n }\n\n rebuildGroups(): void {\n const data = this._d.getData();\n const dl = this._d.getDataLayer();\n const getState = (row: any): string => {\n const idx = data.indexOf(row);\n return idx >= 0 ? dl.getRowState(idx) : 'none';\n };\n const groups = buildGroups(data, this._groupFields, this._getSummaryDefs(), this._groupExpandedKeys, getState, this._groupKeyFn());\n this._groupFlatRows = flattenGroups(groups);\n this._d.getVs()?.setTotalRows(this._groupFlatRows.length);\n this._d.doRenderFull(this._groupFlatRows.length);\n }\n\n // ─── 트리 ─────────────────────────────────────────────────\n enableTree(): void {\n this._isTreeMode = true;\n this._isGroupMode = false;\n const opts = this._d.getOptions();\n if (opts.expandOnLoad) {\n const temp = buildTree(this._d.getData(), {\n idField: opts.treeId,\n parentIdField: opts.treeParentId,\n });\n collectAllTreeIds(temp).forEach(id => this._treeExpandedKeys.add(id));\n }\n this.rebuildTree();\n }\n\n disableTree(): void {\n this._isTreeMode = false;\n this._treeRoots = [];\n this._treeFlatRows = [];\n this._treeExpandedKeys.clear();\n const n = this._d.getData().length;\n this._d.getVs()?.setTotalRows(n);\n this._d.doRender();\n }\n\n expandNodes(ids: any | any[], open = true): void {\n const arr = Array.isArray(ids) ? ids : [ids];\n for (const id of arr) {\n if (open) this._treeExpandedKeys.add(id);\n else this._treeExpandedKeys.delete(id);\n }\n if (this._isTreeMode) this.rebuildTree();\n }\n\n expandAllNodes(): void {\n if (!this._isTreeMode) return;\n collectAllTreeIds(this._treeRoots).forEach(id => this._treeExpandedKeys.add(id));\n this.rebuildTree();\n }\n\n collapseAllNodes(): void {\n if (!this._isTreeMode) return;\n this._treeExpandedKeys.clear();\n this.rebuildTree();\n }\n\n handleTreeToggle(nodeId: any): void {\n toggleTreeNode(this._treeExpandedKeys, nodeId);\n this.rebuildTree();\n }\n\n rebuildTree(): void {\n const opts = this._d.getOptions();\n this._treeRoots = buildTree(this._d.getData(), {\n idField: opts.treeId,\n parentIdField: opts.treeParentId,\n expandOnLoad: opts.expandOnLoad,\n }, this._treeExpandedKeys);\n this._treeFlatRows = flattenTree(this._treeRoots);\n this._d.getVs()?.setTotalRows(this._treeFlatRows.length);\n this._d.doRenderFull(this._treeFlatRows.length);\n }\n\n // ─── 내부 헬퍼 ───────────────────────────────────────────\n private _getSummaryDefs(): SummaryDef[] {\n const s = this._d.getOptions().summary;\n if (!s) return [];\n if (s.rows && s.rows.length > 0) {\n return s.fields.flatMap((f: string) =>\n s.rows!.map((r: any) => ({ field: f, op: r.op, format: r.format }))\n );\n }\n const ops = Array.isArray(s.ops) ? s.ops : (s.ops ? [s.ops] : ['SUM']);\n return s.fields.map((f: string) => ({ field: f, op: ops[0] ?? 'SUM', format: (s as any).format }));\n }\n}\n","import type { DataLayer } from './DataLayer.js';\nimport type { ColumnLayout } from './ColumnLayout.js';\nimport type { VirtualScroll } from './VirtualScroll.js';\nimport type { Pagination } from './Pagination.js';\nimport type { SortItem, FilterItem } from './types.js';\n\nexport interface SortFilterDeps<T extends Record<string, any>> {\n getData: () => DataLayer<T>;\n getColLayout: () => ColumnLayout<T>;\n getFindFilter: () => string;\n getVs: () => VirtualScroll | null;\n getPagination: () => Pagination | null;\n getOptions: () => any;\n renderHeader: () => void;\n doRender: () => void;\n announce: (msg: string) => void;\n emit: (event: string, ...args: any[]) => void;\n}\n\nexport class SortFilterManager<T extends Record<string, any> = any> {\n private _sortList: SortItem[] = [];\n private _filters: Record<string, FilterItem[]> = {};\n private _d: SortFilterDeps<T>;\n\n constructor(deps: SortFilterDeps<T>) {\n this._d = deps;\n }\n\n // ─── 상태 접근자 ─────────────────────────────────────────\n get sortList(): SortItem[] { return this._sortList; }\n get filters(): Record<string, FilterItem[]> { return this._filters; }\n\n // ─── 정렬 ─────────────────────────────────────────────────\n handleSortClick(field: string, shiftKey: boolean): void {\n const opts = this._d.getOptions();\n if (!opts.sortable) return;\n const idx = this._sortList.findIndex(s => s.field === field);\n if (idx >= 0) {\n const cur = this._sortList[idx]!;\n if (cur.dir === 'asc') {\n cur.dir = 'desc';\n } else {\n this._sortList.splice(idx, 1);\n }\n } else {\n if (!shiftKey || !opts.multiSort) this._sortList = [];\n this._sortList.push({ field, dir: 'asc' });\n }\n this._d.getData().applySort(this._sortList);\n this._d.renderHeader();\n this._d.doRender();\n const sortedItem = this._sortList.find(s => s.field === field);\n const dirLabel = sortedItem ? (sortedItem.dir === 'asc' ? '오름차순' : '내림차순') : '정렬 해제';\n this._d.announce(`${field} ${dirLabel} 정렬`);\n this._d.emit('sortChange', { sortList: this._sortList });\n opts.onSortChange?.({ field, dir: sortedItem?.dir ?? 'asc', sortList: this._sortList });\n }\n\n sort(fieldOrList: string | SortItem[], dir: 'asc' | 'desc' = 'asc'): void {\n if (Array.isArray(fieldOrList)) {\n this._sortList = fieldOrList;\n } else {\n const i = this._sortList.findIndex(s => s.field === fieldOrList);\n if (i >= 0) this._sortList[i]!.dir = dir;\n else this._sortList = [{ field: fieldOrList, dir }];\n if (!this._d.getOptions().multiSort) this._sortList = this._sortList.slice(-1);\n }\n this._d.getData().applySort(this._sortList);\n this._d.renderHeader();\n this._d.doRender();\n this._d.emit('sortChange', { sortList: this._sortList });\n }\n\n resetSort(): void {\n this._sortList = [];\n this._d.getData().applySort([]);\n this._d.renderHeader();\n this._d.doRender();\n }\n\n initSort(sortList: SortItem[]): void {\n this._sortList = [...sortList];\n this._d.getData().applySort(this._sortList);\n }\n\n getSortState(): SortItem[] { return [...this._sortList]; }\n\n // ─── 필터 ─────────────────────────────────────────────────\n setFilter(field: string, filterItems: FilterItem[]): void {\n this._filters[field] = filterItems;\n this.applyFilters();\n this._d.renderHeader();\n this._d.doRender();\n this._d.emit('filterChange', { field, filterItems, allFilters: this._filters });\n this._d.getOptions().onFilterChange?.({ field, filterItems, allFilters: this._filters });\n }\n\n resetFilter(field?: string): void {\n if (field) delete this._filters[field];\n else this._filters = {};\n this.applyFilters();\n this._d.renderHeader();\n this._d.doRender();\n }\n\n getFilterState(): Record<string, FilterItem[]> { return { ...this._filters }; }\n\n restoreFilter(state: Record<string, FilterItem[]>): void {\n this._filters = { ...state };\n this.applyFilters();\n }\n\n applyFilters(): void {\n const data = this._d.getData();\n data.setFindFilter(this._d.getFindFilter(), this._d.getColLayout().visibleLeaves.map(c => c.field));\n data.applyFilter(this._filters);\n const n = data.rowCount;\n this._d.getVs()?.setTotalRows(n);\n this._d.getPagination()?.setTotalRows(n);\n }\n}\n","import type { DataLayer } from './DataLayer.js';\nimport type { ColumnLayout } from './ColumnLayout.js';\nimport type { CellEditManager } from './CellEditManager.js';\nimport type { RowManager } from './RowManager.js';\nimport { isToggleCol } from './CellTypeRegistry.js';\nimport { evaluateFormula } from './FormulaEngine.js';\nimport { OGDecimal } from './OGDecimal.js';\n\nexport interface CellEventDeps<T extends Record<string, any>> {\n getData: () => DataLayer<T>;\n getColLayout: () => ColumnLayout<T>;\n getOptions: () => any;\n getEditMgr: () => CellEditManager<T>;\n getRowMgr: () => RowManager<T>;\n emit: (event: string, ...args: any[]) => void;\n writeCell: (ri: number, field: string, value: any) => void;\n doRender: () => void;\n getContainer: () => HTMLElement;\n}\n\nexport class CellEventHandler<T extends Record<string, any> = any> {\n private _d: CellEventDeps<T>;\n\n constructor(deps: CellEventDeps<T>) {\n this._d = deps;\n }\n\n handleCellClick(rowIndex: number, colIndex: number, e: MouseEvent): void {\n const opts = this._d.getOptions();\n const rowMgr = this._d.getRowMgr();\n const editMgr = this._d.getEditMgr();\n\n if (opts.selection === 'single' || opts.selection === 'row') {\n rowMgr.selectSingle(rowIndex);\n } else if (opts.selection === 'multiple') {\n if (e.ctrlKey || e.metaKey) {\n rowMgr.selectToggle(rowIndex);\n } else {\n rowMgr.selectSingle(rowIndex);\n }\n }\n\n const row = this._d.getData().getRowByIndex(rowIndex);\n const col = this._d.getColLayout().visibleLeaves[colIndex];\n\n if (row && col) {\n const colEditable = col.editable !== false && (col.editable !== undefined || opts.editable);\n if (isToggleCol(col) && colEditable) {\n const curVal = (row as any)[col.field];\n this._d.writeCell(rowIndex, col.field as unknown as string, !curVal);\n }\n\n if ((col.type as string) === 'radio') {\n const grp = (col as any).group;\n for (const c of this._d.getColLayout().visibleLeaves) {\n if ((c.type as string) === 'radio' && c.field !== col.field &&\n (!grp || (c as any).group === grp)) {\n this._d.getData().updateCell(rowIndex, c.field, false);\n }\n }\n this._d.writeCell(rowIndex, col.field as any, true);\n }\n\n let cellValue = (row as any)[col.field];\n if (cellValue === undefined && (col as any).formula) {\n try {\n const prec = (col as any).formulaPrecision ?? 30;\n const result = evaluateFormula((col as any).formula, row as any, prec);\n cellValue = result instanceof OGDecimal\n ? ((col as any).precision != null ? result.toFixed((col as any).precision) : result.toString())\n : String(result);\n } catch {}\n }\n const evt = {\n type: 'cellClick', rowIndex, columnIndex: colIndex,\n field: col.field, value: cellValue, row, column: col,\n target: e.target as HTMLElement, originalEvent: e,\n };\n this._d.emit('cellClick', evt);\n opts.onCellClick?.(evt);\n\n const rowEvt = { type: 'rowClick', rowIndex, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowClick', rowEvt);\n opts.onRowClick?.(rowEvt);\n\n const isSelectCol = (col.type as string) === 'select';\n const alreadyEditing = editMgr.activeEditor != null &&\n editMgr.editCell?.ri === rowIndex && editMgr.editCell?.ci === colIndex;\n if (!alreadyEditing && (opts.editMode === 'click' || isSelectCol) && !isToggleCol(col)) {\n editMgr.startEdit(rowIndex, colIndex, e);\n }\n }\n\n if (editMgr.activeEditor && editMgr.editCell?.ri === rowIndex && editMgr.editCell?.ci === colIndex) {\n return;\n }\n\n this._d.doRender();\n this._d.emit('selectionChange', {\n rows: rowMgr.getSelections(),\n rowIndexes: [...rowMgr.selectedRows],\n });\n opts.onSelectionChange?.({ rows: rowMgr.getSelections(), rowIndexes: [...rowMgr.selectedRows], cells: [] });\n }\n\n handleCellDblClick(rowIndex: number, colIndex: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(rowIndex);\n const col = this._d.getColLayout().visibleLeaves[colIndex];\n if (!row || !col) return;\n\n const opts = this._d.getOptions();\n const evt = {\n type: 'cellDblClick', rowIndex, columnIndex: colIndex,\n field: col.field, value: row[col.field], row, column: col,\n target: e.target as HTMLElement, originalEvent: e,\n };\n this._d.emit('cellDblClick', evt);\n opts.onCellDblClick?.(evt);\n\n const rowEvt = { type: 'rowDblClick', rowIndex, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowDblClick', rowEvt);\n opts.onRowDblClick?.(rowEvt);\n\n if (opts.editMode === 'dblclick') this._d.getEditMgr().startEdit(rowIndex, colIndex, e);\n }\n\n handleCellMouseOver(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseOver', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseOver', cellEvt);\n opts.onCellMouseOver?.(cellEvt);\n const rowEvt = { type: 'rowMouseOver', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseOver', rowEvt);\n opts.onRowMouseOver?.(rowEvt);\n }\n\n handleCellMouseOut(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseOut', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseOut', cellEvt);\n opts.onCellMouseOut?.(cellEvt);\n const rowEvt = { type: 'rowMouseOut', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseOut', rowEvt);\n opts.onRowMouseOut?.(rowEvt);\n }\n\n handleCellMouseDown(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseDown', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseDown', cellEvt);\n opts.onCellMouseDown?.(cellEvt);\n const rowEvt = { type: 'rowMouseDown', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseDown', rowEvt);\n opts.onRowMouseDown?.(rowEvt);\n }\n\n handleCellMouseUp(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseUp', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseUp', cellEvt);\n opts.onCellMouseUp?.(cellEvt);\n const rowEvt = { type: 'rowMouseUp', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseUp', rowEvt);\n opts.onRowMouseUp?.(rowEvt);\n }\n\n handleCellMouseMove(ri: number, ci: number, e: MouseEvent): void {\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const cellEvt = { type: 'cellMouseMove', rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('cellMouseMove', cellEvt);\n opts.onCellMouseMove?.(cellEvt);\n const rowEvt = { type: 'rowMouseMove', rowIndex: ri, row, target: e.target as HTMLElement, originalEvent: e };\n this._d.emit('rowMouseMove', rowEvt);\n opts.onRowMouseMove?.(rowEvt);\n }\n\n handleCellKeyEvt(eventName: 'cellKeyDown' | 'cellKeyUp' | 'cellKeyPress', e: KeyboardEvent): void {\n const editMgr = this._d.getEditMgr();\n if (!editMgr.focusCell || editMgr.activeEditor) return;\n const { ri, ci } = editMgr.focusCell;\n const row = this._d.getData().getRowByIndex(ri);\n const col = this._d.getColLayout().visibleLeaves[ci];\n if (!row || !col) return;\n const opts = this._d.getOptions();\n const evt = { type: eventName, rowIndex: ri, columnIndex: ci, field: col.field, value: (row as any)[col.field], row, column: col as any, key: e.key, target: this._d.getContainer(), originalEvent: e };\n this._d.emit(eventName, evt);\n if (eventName === 'cellKeyDown') opts.onCellKeyDown?.(evt as any);\n else if (eventName === 'cellKeyUp') opts.onCellKeyUp?.(evt as any);\n else opts.onCellKeyPress?.(evt as any);\n }\n}\n","import type { TriggerContext, TriggerHandler, TriggerEvent } from './types.js';\n\nexport class TriggerManager {\n private _triggers = new Map<string, TriggerHandler[]>();\n\n add(event: TriggerEvent | string, handler: TriggerHandler): void {\n if (!this._triggers.has(event)) this._triggers.set(event, []);\n this._triggers.get(event)!.push(handler);\n }\n\n remove(event: TriggerEvent | string, handler: TriggerHandler): void {\n const arr = this._triggers.get(event);\n if (arr) {\n const idx = arr.indexOf(handler);\n if (idx >= 0) arr.splice(idx, 1);\n }\n }\n\n clear(event?: TriggerEvent | string): void {\n if (event) this._triggers.delete(event);\n else this._triggers.clear();\n }\n\n mkCtx(operation: string, args: any[]): TriggerContext {\n let _cancelled = false;\n return {\n operation, args, result: undefined, extra: {},\n timestamp: Date.now(),\n get cancelled() { return _cancelled; },\n cancel() { _cancelled = true; },\n };\n }\n\n exec(event: string, ctx: TriggerContext): boolean {\n const handlers = this._triggers.get(event) ?? [];\n for (const fn of handlers) {\n fn(ctx);\n if (ctx.cancelled) return false;\n }\n if (event.startsWith('after:')) {\n const completeHandlers = this._triggers.get('complete') ?? [];\n for (const fn of completeHandlers) fn(ctx);\n }\n return true;\n }\n}\n","// ============================================================\n// 그리드↔그리드 필드 매핑 UI + 스크립트 생성기\n// ------------------------------------------------------------\n// crossGrid 드롭 시 소스/타깃 스키마(필드)가 다를 때, 개발자가\n// \"타깃 필드 ← 소스 필드\"를 매칭하는 모달을 띄운다. 확인하면\n// ① 매핑(Record<타깃, 소스>)을 반환하고\n// ② 그대로 crossGridMapping 에 baking 할 수 있는 변환 스크립트를 출력한다.\n// 디자인타임 헬퍼 — 한 번 매핑을 확정하면 스크립트를 코드에 박아 모달 없이 운영한다.\n// ============================================================\n\nexport interface FieldInfo {\n field: string;\n header: string;\n}\n\nexport interface MappingResult {\n /** 타깃필드 → 소스필드 (빈 문자열이면 미매핑) */\n mapping: Record<string, string>;\n /** crossGridMapping 에 그대로 쓸 수 있는 변환 함수 소스 */\n script: string;\n}\n\nconst NONE = '';\n\n/** mapping → 변환 함수 스크립트 문자열 생성 */\nexport function buildMappingScript(mapping: Record<string, string>): string {\n const lines = Object.entries(mapping)\n .filter(([, src]) => src !== NONE)\n .map(([tgt, src]) => ` ${JSON.stringify(tgt)}: src[${JSON.stringify(src)}],`);\n return (\n '// crossGridMapping 옵션에 이 함수를 그대로 지정하세요.\\n' +\n 'function mapRow(src) {\\n' +\n ' return {\\n' +\n lines.join('\\n') + (lines.length ? '\\n' : '') +\n ' };\\n' +\n '}'\n );\n}\n\n/** mapping → 실제 행 변환 함수 */\nexport function buildTransform(mapping: Record<string, string>): (src: any) => any {\n return (src: any) => {\n const out: Record<string, any> = {};\n for (const [tgt, sf] of Object.entries(mapping)) {\n if (sf !== NONE) out[tgt] = src[sf];\n }\n return out;\n };\n}\n\n/** 같은 필드 집합인지 (순서 무관) */\nexport function sameSchema(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const sb = new Set(b);\n return a.every(f => sb.has(f));\n}\n\n/**\n * 매핑 모달을 띄우고 사용자가 확정한 매핑을 Promise 로 반환한다. (취소 시 null)\n * 모달은 document.body 에 오버레이로 붙는다(디자인타임 헬퍼).\n */\nexport function openCrossGridMapper(\n sourceFields: FieldInfo[],\n targetFields: FieldInfo[],\n): Promise<MappingResult | null> {\n return new Promise((resolve) => {\n // ── 기본 매핑: 같은 필드명 자동 매칭 ──\n const srcSet = new Set(sourceFields.map(f => f.field));\n const mapping: Record<string, string> = {};\n for (const tf of targetFields) mapping[tf.field] = srcSet.has(tf.field) ? tf.field : NONE;\n\n // ── 오버레이 ──\n const overlay = document.createElement('div');\n overlay.className = 'og-mapper-overlay';\n overlay.setAttribute('role', 'dialog');\n overlay.setAttribute('aria-modal', 'true');\n overlay.setAttribute('aria-label', '그리드 필드 매핑');\n overlay.style.cssText =\n 'position:fixed;inset:0;z-index:100000;background:rgba(0,0,0,0.45);' +\n 'display:flex;align-items:center;justify-content:center;' +\n 'font-family:var(--og-font-family,-apple-system,sans-serif);';\n\n const box = document.createElement('div');\n box.style.cssText =\n 'background:#fff;border-radius:10px;box-shadow:0 12px 40px rgba(0,0,0,0.3);' +\n 'width:min(620px,92vw);max-height:88vh;overflow:auto;color:#222;';\n overlay.appendChild(box);\n\n // ── 헤더 ──\n const head = document.createElement('div');\n head.style.cssText = 'padding:18px 20px 8px;';\n head.innerHTML =\n '<div style=\"font-size:16px;font-weight:700;\">필드 매핑</div>' +\n '<div style=\"font-size:12.5px;color:#666;margin-top:4px;line-height:1.5;\">' +\n '두 그리드의 필드 구조가 다릅니다. <b>타깃 필드</b>마다 어떤 <b>소스 필드</b>의 값을 가져올지 지정하세요. ' +\n '아래 스크립트를 복사해 <code>crossGridMapping</code> 에 baking 하면 다음부터는 이 창 없이 자동 변환됩니다.</div>';\n box.appendChild(head);\n\n // ── 매핑 테이블 ──\n const table = document.createElement('div');\n table.style.cssText = 'padding:6px 20px;';\n const optionHtml =\n `<option value=\"\">(비움)</option>` +\n sourceFields.map(f =>\n `<option value=\"${esc(f.field)}\">${esc(f.header)} &lt;${esc(f.field)}&gt;</option>`\n ).join('');\n\n for (const tf of targetFields) {\n const row = document.createElement('div');\n row.style.cssText =\n 'display:flex;align-items:center;gap:10px;padding:7px 0;border-bottom:1px solid #f0f0f0;';\n const label = document.createElement('div');\n label.style.cssText = 'flex:1;font-size:13px;min-width:0;';\n label.innerHTML =\n `<span style=\"font-weight:600;\">${esc(tf.header)}</span>` +\n `<span style=\"color:#999;font-size:11.5px;\"> &lt;${esc(tf.field)}&gt;</span>`;\n const arrow = document.createElement('span');\n arrow.textContent = '←';\n arrow.style.cssText = 'color:#888;flex-shrink:0;';\n const sel = document.createElement('select');\n sel.style.cssText =\n 'flex:1;min-width:0;padding:6px 8px;border:1px solid #ccc;border-radius:6px;font-size:13px;background:#fff;';\n sel.innerHTML = optionHtml;\n sel.value = mapping[tf.field] ?? NONE;\n sel.addEventListener('change', () => { mapping[tf.field] = sel.value; refreshScript(); });\n row.append(label, arrow, sel);\n table.appendChild(row);\n }\n box.appendChild(table);\n\n // ── 스크립트 미리보기 + 복사 ──\n const scriptWrap = document.createElement('div');\n scriptWrap.style.cssText = 'padding:10px 20px 4px;';\n const scriptHead = document.createElement('div');\n scriptHead.style.cssText = 'display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;';\n scriptHead.innerHTML = '<span style=\"font-size:12.5px;font-weight:600;color:#444;\">생성된 변환 스크립트</span>';\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.textContent = '복사';\n copyBtn.style.cssText =\n 'font-size:12px;padding:4px 10px;border:1px solid #ccc;border-radius:6px;background:#f7f7f7;cursor:pointer;';\n scriptHead.appendChild(copyBtn);\n const pre = document.createElement('pre');\n pre.style.cssText =\n 'margin:0;background:#0d1117;color:#c9d1d9;padding:12px;border-radius:8px;' +\n 'font-family:ui-monospace,Consolas,monospace;font-size:12px;line-height:1.5;overflow:auto;max-height:180px;';\n scriptWrap.append(scriptHead, pre);\n box.appendChild(scriptWrap);\n\n function currentScript(): string { return buildMappingScript(mapping); }\n function refreshScript(): void { pre.textContent = currentScript(); }\n refreshScript();\n\n copyBtn.addEventListener('click', () => {\n const txt = currentScript();\n navigator.clipboard?.writeText(txt).then(\n () => { copyBtn.textContent = '복사됨!'; setTimeout(() => (copyBtn.textContent = '복사'), 1200); },\n () => { copyBtn.textContent = '복사 실패'; setTimeout(() => (copyBtn.textContent = '복사'), 1200); },\n );\n });\n\n // ── 푸터 ──\n const foot = document.createElement('div');\n foot.style.cssText = 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px 18px;';\n const cancelBtn = document.createElement('button');\n cancelBtn.type = 'button';\n cancelBtn.textContent = '취소';\n cancelBtn.style.cssText =\n 'font-size:13px;padding:8px 16px;border:1px solid #ccc;border-radius:7px;background:#fff;cursor:pointer;';\n const okBtn = document.createElement('button');\n okBtn.type = 'button';\n okBtn.textContent = '적용 후 이동';\n okBtn.style.cssText =\n 'font-size:13px;padding:8px 16px;border:0;border-radius:7px;background:#1976d2;color:#fff;cursor:pointer;font-weight:600;';\n foot.append(cancelBtn, okBtn);\n box.appendChild(foot);\n\n // ── 닫기 처리 ──\n let done = false;\n function close(result: MappingResult | null): void {\n if (done) return;\n done = true;\n document.removeEventListener('keydown', onKey);\n overlay.remove();\n resolve(result);\n }\n function onKey(e: KeyboardEvent): void {\n if (e.key === 'Escape') close(null);\n }\n cancelBtn.addEventListener('click', () => close(null));\n overlay.addEventListener('mousedown', (e) => { if (e.target === overlay) close(null); });\n okBtn.addEventListener('click', () => close({ mapping: { ...mapping }, script: currentScript() }));\n document.addEventListener('keydown', onKey);\n\n document.body.appendChild(overlay);\n okBtn.focus();\n });\n}\n\nfunction esc(s: string): string {\n return String(s).replace(/[&<>\"]/g, c =>\n ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[c] as string));\n}\n","// ============================================================\n// 크로스그리드 레지스트리\n// 그리드 바디(.og-body-wrapper) 엘리먼트 → 그리드 인스턴스 매핑.\n// 드래그(좌표→타깃 그리드)와 화살표 셔틀이 공유한다.\n// ============================================================\nimport type { OpenGrid } from './OpenGrid.js'; // 타입 전용 (런타임 순환 없음)\n\nexport class CrossGridRegistry {\n private _map = new Map<HTMLElement, OpenGrid<any>>();\n\n register(bodyEl: HTMLElement, grid: OpenGrid<any>): void { this._map.set(bodyEl, grid); }\n unregister(bodyEl: HTMLElement): void { this._map.delete(bodyEl); }\n get(bodyEl: HTMLElement): OpenGrid<any> | undefined { return this._map.get(bodyEl); }\n get size(): number { return this._map.size; }\n\n /** 커서 좌표 아래의 다른(crossGrid 허용) 그리드 반환. 없으면 null */\n resolveAt(clientX: number, clientY: number, exclude: OpenGrid<any>): OpenGrid<any> | null {\n const el = document.elementFromPoint(clientX, clientY) as HTMLElement | null;\n const body = el?.closest('.og-body-wrapper') as HTMLElement | null;\n if (!body) return null;\n const g = this._map.get(body);\n if (!g || g === exclude) return null;\n return g;\n }\n}\n\n/** 전역 단일 레지스트리 */\nexport const crossGridRegistry = new CrossGridRegistry();\n","/**\n * OverrideKernel — `grid.override()` 확장 커널 (94 최종 종합본 반영)\n *\n * 핵심 원칙(94 §1 F1~F4):\n * - F2: FIFO 합성 = `reduce` 좌측폴드. 먼저 등록 = 안쪽(원본 근접), 나중 등록 = 바깥.\n * `[fn1,fn2,fn3]` → 실행 시 fn3(최후등록)이 최외곽, orig() 호출이 안쪽으로 전파.\n * - F3: 재진입 가드 = 깊이 제한(maxDepth 기본 32) + 호출경로 사이클 감지(_callPath, 동일 name\n * 재출현 시 차단) + 명시적 { reentrant:true } 옵트인. 정당한 cascade는 깊이 내 허용.\n * - F4: 에러 격리 = 기본 strict=true(예외 전파). { onError:'fallback' } 옵트인 시에만\n * 경고 후 orig fallback(멱등 가정, 롤백 불가).\n *\n * 본 커널은 단독 클래스로, OpenGrid 인스턴스를 host 로 받아 프로토타입 메서드를\n * 인스턴스 프로퍼티로 shadowing(순수 런타임 래핑, C1-clean) 한다. 소스 본문 0줄 수정.\n */\n\nexport interface OverrideKernelHost {\n [name: string]: any;\n}\n\n/** override() 호출 시 레이어가 받는 함수 시그니처: 첫 인자는 안쪽(원본 근접) 함수. */\nexport type OverrideLayer = (orig: (...args: any[]) => any, ...args: any[]) => any;\n\nexport interface OverrideOptions {\n /** 동일 name 재진입을 허용(정당한 재귀). 기본 false. */\n reentrant?: boolean;\n /** 'fallback' → 레이어 예외 시 경고 후 orig 실행(멱등 가정). 미지정 시 strict(전파). */\n onError?: 'fallback';\n}\n\ninterface LayerEntry {\n fn: OverrideLayer;\n opts: OverrideOptions;\n}\n\nexport class OverrideKernel {\n private _host: OverrideKernelHost;\n /** name → this-bound 원본 함수 (최초 1회 보존) */\n private _originals = new Map<string, (...args: any[]) => any>();\n /** name → 최초 override 직전 host 가 own 프로퍼티로 메서드를 가졌는지(복구 방식 결정) */\n private _hadOwn = new Map<string, boolean>();\n /** name → 레이어 목록(등록순, FIFO) */\n private _stack = new Map<string, LayerEntry[]>();\n /** slot → strategy 함수 */\n private _strategies = new Map<string, Function>();\n /** F3: 현재 호출 경로(메서드 name 스택) — 사이클 감지용 */\n private _callPath: string[] = [];\n /** F4: 기본 strict (예외 전파) */\n private _strict: boolean;\n /** F3: 재귀 깊이 제한 */\n private _maxDepth: number;\n\n constructor(host: OverrideKernelHost, opts?: { strict?: boolean; maxDepth?: number }) {\n this._host = host;\n this._strict = opts?.strict ?? true;\n this._maxDepth = opts?.maxDepth ?? 32;\n }\n\n /**\n * 메서드 override 등록.\n * 1. 최초 1회 원본을 this-bound 로 보존.\n * 2. 레이어 push (FIFO 등록순).\n * 3. reduce 좌측폴드로 합성(나중 등록 = 최외곽).\n * 4. 재진입 가드 + 에러 격리로 감싼 dispatcher 를 host[name] 인스턴스 프로퍼티에 할당.\n */\n override(name: string, fn: OverrideLayer, opts: OverrideOptions = {}): OverrideKernelHost {\n if (typeof fn !== 'function') {\n throw new TypeError(`OverrideKernel.override: fn for \"${name}\" must be a function`);\n }\n if (!this._originals.has(name)) {\n const orig = this._host[name];\n if (typeof orig !== 'function') {\n throw new TypeError(`OverrideKernel.override: host[\"${name}\"] is not a function`);\n }\n // 복구 방식 결정: own 프로퍼티였으면 원본 값을 되돌리고, 프로토타입 메서드면\n // 인스턴스 shadow 만 delete 하여 프로토타입을 재노출(순수 래핑 가역성).\n this._hadOwn.set(name, Object.prototype.hasOwnProperty.call(this._host, name));\n this._originals.set(name, orig.bind(this._host));\n }\n\n const layers = this._stack.get(name) ?? [];\n layers.push({ fn, opts });\n this._stack.set(name, layers);\n\n this._host[name] = this._buildDispatcher(name);\n return this._host;\n }\n\n /** 합성된 dispatcher 생성. override/restore 시점마다 재구성. */\n private _buildDispatcher(name: string): (...args: any[]) => any {\n const original = this._originals.get(name)!;\n const layers = this._stack.get(name) ?? [];\n\n // F2: reduce 좌측폴드. layers[0]=가장 안쪽(원본 근접), 마지막=최외곽.\n // acc 시작값 = original, 각 layer 는 acc(=innerOrig)를 첫 인자로 받는다.\n const composed = layers.reduce<(...args: any[]) => any>(\n (innerOrig, layer) => (...a: any[]) => layer.fn(innerOrig, ...a),\n original,\n );\n\n // 최외곽 레이어의 옵션이 재진입/에러 정책을 결정.\n const outer = layers[layers.length - 1]?.opts ?? {};\n const reentrant = outer.reentrant === true;\n const fallback = outer.onError === 'fallback';\n\n const self = this;\n return function (this: unknown, ...args: any[]): any {\n // F3: 사이클 감지 — 동일 name 이 이미 호출 경로에 있고 reentrant 옵트인이 아니면 원본으로.\n if (!reentrant && self._callPath.indexOf(name) !== -1) {\n return original(...args);\n }\n // F3: 깊이 제한.\n if (self._callPath.length >= self._maxDepth) {\n if (self._strict && !fallback) {\n throw new Error(\n `OverrideKernel: max override depth (${self._maxDepth}) exceeded at \"${name}\"`,\n );\n }\n return original(...args);\n }\n\n self._callPath.push(name);\n try {\n return composed(...args);\n } catch (e) {\n // F4: 기본 strict 전파. onError:'fallback' 옵트인 시에만 경고 후 orig.\n if (fallback && !self._strict) {\n console.warn(`[og.override:${name}]`, e);\n return original(...args);\n }\n if (fallback && self._strict) {\n // strict 모드라도 명시적 fallback 옵트인은 존중(멱등 가정, 롤백 불가).\n console.warn(`[og.override:${name}]`, e);\n return original(...args);\n }\n throw e;\n } finally {\n self._callPath.pop();\n }\n };\n }\n\n /** strategy 슬롯 등록 (Phase 2 매니저 배선용 API). */\n strategy(slot: string, fn: Function): OverrideKernelHost {\n if (typeof fn !== 'function') {\n throw new TypeError(`OverrideKernel.strategy: fn for \"${slot}\" must be a function`);\n }\n this._strategies.set(slot, fn);\n return this._host;\n }\n\n /** strategy 슬롯 조회 — 미등록 시 fallback 반환 (매니저 read API). */\n getStrategy<F extends Function>(slot: string, fallback: F): F {\n return (this._strategies.get(slot) as F) ?? fallback;\n }\n\n /** 슬롯 등록 여부. */\n hasStrategy(slot: string): boolean {\n return this._strategies.has(slot);\n }\n\n /** 단일 메서드 원본 복구. 없으면 no-op. */\n restore(name: string): OverrideKernelHost {\n if (!this._originals.has(name)) return this._host;\n if (this._hadOwn.get(name)) {\n // 원래 own 프로퍼티였음 → 보존한 원본(this-bound)을 되돌린다.\n this._host[name] = this._originals.get(name)!;\n } else {\n // 프로토타입 메서드였음 → 인스턴스 shadow 삭제로 프로토타입 재노출.\n delete this._host[name];\n }\n this._originals.delete(name);\n this._hadOwn.delete(name);\n this._stack.delete(name);\n return this._host;\n }\n\n /** 전체 복구 + strategy clear. destroy 시 호출. */\n restoreAll(): OverrideKernelHost {\n for (const n of [...this._originals.keys()]) this.restore(n);\n this._strategies.clear();\n this._callPath = [];\n return this._host;\n }\n\n /** override 등록 여부. */\n hasOverride(name: string): boolean {\n return this._originals.has(name);\n }\n\n /** override 등록된 메서드 이름 목록. */\n getOverrideNames(): string[] {\n return [...this._originals.keys()];\n }\n}\n","import { EventEmitter } from './EventEmitter.js';\r\nimport { DataLayer } from './DataLayer.js';\r\nimport { VirtualScroll } from './VirtualScroll.js';\r\nimport { ColumnLayout } from './ColumnLayout.js';\r\nimport { FilterPanel } from './FilterPanel.js';\r\nimport { GridRenderer } from './GridRenderer.js';\r\nimport type { RendererCallbacks } from './GridRenderer.js';\r\nimport { RowManager } from './RowManager.js';\r\nimport { CellEditManager } from './CellEditManager.js';\r\nimport { isToggleCol } from './CellTypeRegistry.js';\r\nimport { FilterSelectPanel } from './FilterSelect.js';\r\nimport type { FilterSelectConfig } from './FilterSelect.js';\r\nimport { Pagination } from './Pagination.js';\r\nimport { RowDragDrop } from './RowDragDrop.js';\r\nimport { MergeEngine, type MergeCell } from './MergeEngine.js';\r\nimport { createRenderer, setDisplayFormatterResolver } from './renderers/CellRenderer.js';\r\nimport { ContextMenuManager, DEFAULT_CONTEXT_ITEMS } from './ContextMenu.js';\r\nimport { WorksheetManager } from './WorksheetManager.js';\r\nimport { ExportManager } from './ExportManager.js';\r\nimport { FooterManager } from './FooterManager.js';\r\nimport { KeyboardManager } from './KeyboardManager.js';\r\nimport { FindBarManager } from './FindBarManager.js';\r\nimport { GroupTreeManager } from './GroupTreeManager.js';\r\nimport { SortFilterManager } from './SortFilterManager.js';\r\nimport { CellEventHandler } from './CellEventHandler.js';\r\nimport { TriggerManager } from './TriggerManager.js';\r\nimport {\r\n openCrossGridMapper, buildTransform, buildMappingScript, sameSchema,\r\n type FieldInfo,\r\n} from './CrossGridMapper.js';\r\nimport { crossGridRegistry } from './CrossGridRegistry.js';\r\nimport { OverrideKernel } from './OverrideKernel.js';\r\nimport type { OverrideLayer } from './OverrideKernel.js';\r\nimport type {\r\n GridOptions, OpenGridInstance, ColumnDef,\r\n SortItem, FilterItem, ExportOptions,\r\n EditEvent, Position, GridDropEvent, GridMappingEvent,\r\n TriggerContext, TriggerHandler, TriggerEvent,\r\n OverrideApi, OverrideCallOptions,\r\n} from './types.js';\r\n\r\nconst ROW_ID_FIELD = '_ogRowId';\r\n\r\nexport class OpenGrid<T extends Record<string, any> = any>\r\n extends EventEmitter\r\n implements OpenGridInstance<T>\r\n{\r\n private _container: HTMLElement;\r\n private _options: Required<GridOptions<T>>;\r\n private _data: DataLayer<T>;\r\n private _colLayout: ColumnLayout<T>;\r\n private _vs: VirtualScroll | null = null;\r\n private _ro: ResizeObserver | null = null;\r\n private _renderer: GridRenderer | null = null;\r\n private _sfMgr!: SortFilterManager<T>;\r\n private _rowMgr!: RowManager<T>;\r\n private _editMgr!: CellEditManager<T>;\r\n private _trigMgr = new TriggerManager();\r\n private _destroyed = false;\r\n private _autoHeightWarned = false;\r\n private _colWidths: number[] = [];\r\n /** 사용자가 헤더 드래그로 직접 조절한 컬럼 폭 (field 기준). _recalcWidths 가 덮어쓰지 않도록 보존 */\r\n private _userWidths = new Map<string, number>();\r\n private _filterPanel: FilterPanel | null = null;\r\n private _filterSelect: FilterSelectPanel | null = null;\r\n private _pagination: Pagination | null = null;\r\n private _dnd: RowDragDrop | null = null;\r\n private _mergeEngine: MergeEngine = new MergeEngine();\r\n private _liveRegion: HTMLElement | null = null;\r\n private _ctxMenu: ContextMenuManager | null = null;\r\n private _cmHandler: ((e: MouseEvent) => void) | null = null;\r\n private _cmKbdHandler: ((e: KeyboardEvent) => void) | null = null;\r\n private _wsManager: WorksheetManager<T> | null = null;\r\n // 분리된 매니저들\r\n private _exportMgr!: ExportManager<T>;\r\n private _footerMgr!: FooterManager<T>;\r\n private _kbdMgr!: KeyboardManager<T>;\r\n private _findMgr!: FindBarManager<T>;\r\n private _grpMgr!: GroupTreeManager<T>;\r\n private _cellEvt!: CellEventHandler<T>;\r\n\r\n // grid.override() 확장 커널 (생성자 말미에 초기화)\r\n private _ovk!: OverrideKernel;\r\n /** 공개 override API (호출가능 + .strategy). 생성자 말미에 부착. */\r\n override!: OverrideApi<T>;\r\n\r\n // ── grid.override() 정적 전역 레지스트리 ──────────────────\r\n /** 정적 전역 override 레이어 (모든 신규 인스턴스에 생성자 말미 적용). */\r\n private static _defaultOverrides: Array<[string, OverrideLayer, OverrideCallOptions]> = [];\r\n /** 정적 전역 strategy 슬롯. */\r\n private static _defaultStrategies: Array<[string, Function]> = [];\r\n\r\n /** 정적: 모든 신규 그리드에 적용될 override 레이어 등록. */\r\n static defaultOverride(name: string, fn: OverrideLayer, opts: OverrideCallOptions = {}): typeof OpenGrid {\r\n OpenGrid._defaultOverrides.push([name, fn, opts]);\r\n return OpenGrid;\r\n }\r\n\r\n /** 정적 전역 defaults 네임스페이스 (strategy 슬롯). */\r\n static defaults = {\r\n strategy(slot: string, fn: Function): typeof OpenGrid {\r\n OpenGrid._defaultStrategies.push([slot, fn]);\r\n return OpenGrid;\r\n },\r\n };\r\n\r\n constructor(container: string | HTMLElement, options: GridOptions<T>) {\r\n super();\r\n const el = typeof container === 'string'\r\n ? (document.querySelector(container) as HTMLElement)\r\n : container;\r\n if (!el) throw new Error(`OpenGrid: container not found: ${container}`);\r\n this._container = el;\r\n\r\n this._options = {\r\n height: '100%', width: '100%',\r\n rowHeight: 32, headerHeight: 34, footerHeight: 30,\r\n autoHeight: false, fillWidth: false, defaultColumnWidth: 100,\r\n editable: false, editMode: 'dblclick', history: true, historySize: 100,\r\n selection: 'single', clipboard: true,\r\n sortable: true, multiSort: true, filterable: true, defaultSort: [],\r\n frozenColumns: 0, frozenRows: 0,\r\n rowNumber: false, stateColumn: false, checkColumn: false, draggable: false, crossGrid: false, crossGridMapping: 'auto',\r\n mergeCells: false, groupBy: [], summary: undefined as any,\r\n treeMode: 'auto', treeId: 'id', treeParentId: 'parentId', expandOnLoad: false,\r\n pagination: false, pageSize: 50,\r\n footer: undefined as any, footerPosition: 'bottom',\r\n theme: 'default', cssVars: {}, ariaLabel: 'OPEN_GRID 데이터 그리드',\r\n ...options\r\n } as Required<GridOptions<T>>;\r\n\r\n this._data = new DataLayer<T>(ROW_ID_FIELD);\r\n this._rowMgr = new RowManager<T>(this._data);\r\n this._colLayout = new ColumnLayout<T>(this._options.columns, this._options.frozenColumns);\r\n this._editMgr = new CellEditManager<T>({\r\n data: this._data,\r\n colLayout: this._colLayout,\r\n getRenderer: () => this._renderer,\r\n getContainer: () => this._container,\r\n getOptions: () => this._options,\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n doRender: () => this._doRender(...this._visRange()),\r\n announce: (msg) => this._announce(msg),\r\n writeCell: (ri, field, value) => this.writeCell(ri, field, value),\r\n scrollToRow: (ri) => this._vs?.scrollToRow(ri),\r\n getVisibleLeaves: () => this._colLayout.visibleLeaves,\r\n });\r\n\r\n this._exportMgr = new ExportManager<T>({\r\n getData: () => this._data.getData(),\r\n getColLayout: () => this._colLayout,\r\n getColWidths: () => this._colWidths,\r\n getOptions: () => this._options,\r\n getContainer: () => this._container,\r\n getMaskEnabled: (field) => this.getMaskEnabled(field),\r\n getWsManager: () => this._wsManager,\r\n getStrategy: (slot, fb) => this._ovk.getStrategy(slot, fb),\r\n });\r\n this._footerMgr = new FooterManager<T>({\r\n getData: () => this._data.getData(),\r\n getColLayout: () => this._colLayout,\r\n getColWidths: () => this._colWidths,\r\n getOptions: () => this._options,\r\n getContainer: () => this._container,\r\n getStrategy: (slot, fb) => this._ovk.getStrategy(slot, fb),\r\n });\r\n this._kbdMgr = new KeyboardManager<T>({\r\n getEditMgr: () => this._editMgr,\r\n getRowMgr: () => this._rowMgr,\r\n getData: () => this._data,\r\n getColLayout: () => this._colLayout,\r\n getOptions: () => this._options,\r\n setFocusCell: (ri, ci) => this._setFocusCell(ri, ci),\r\n handleRowDrop: (from, to) => this._handleRowDrop(from, to),\r\n doRender: () => this._doRender(...this._visRange()),\r\n announce: (msg) => this._announce(msg),\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n visRange: () => this._visRange(),\r\n handleCellKeyEvt: (name, e) => this._handleCellKeyEvt(name, e),\r\n });\r\n this._sfMgr = new SortFilterManager<T>({\r\n getData: () => this._data,\r\n getColLayout: () => this._colLayout,\r\n getFindFilter: () => this._findMgr.findFilter,\r\n getVs: () => this._vs,\r\n getPagination: () => this._pagination,\r\n getOptions: () => this._options,\r\n renderHeader: () => this._renderHeader(),\r\n doRender: () => this._doRender(...this._visRange()),\r\n announce: (msg) => this._announce(msg),\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n });\r\n this._findMgr = new FindBarManager<T>({\r\n getColLayout: () => this._colLayout,\r\n getData: () => this._data,\r\n getFilters: () => this._sfMgr.filters,\r\n getVs: () => this._vs,\r\n getPagination: () => this._pagination,\r\n doRender: () => this._doRender(...this._visRange()),\r\n });\r\n this._cellEvt = new CellEventHandler<T>({\r\n getData: () => this._data,\r\n getColLayout: () => this._colLayout,\r\n getOptions: () => this._options,\r\n getEditMgr: () => this._editMgr,\r\n getRowMgr: () => this._rowMgr,\r\n emit: (ev, ...args) => this.emit(ev, ...args),\r\n writeCell: (ri, field, val) => this.writeCell(ri, field, val),\r\n doRender: () => this._doRender(...this._visRange()),\r\n getContainer: () => this._container,\r\n });\r\n this._grpMgr = new GroupTreeManager<T>({\r\n getData: () => this._data.getData(),\r\n getDataLayer: () => this._data,\r\n getOptions: () => this._options,\r\n getVs: () => this._vs,\r\n doRenderFull: (n) => this._doRender(0, n - 1),\r\n doRender: () => this._doRender(...this._visRange()),\r\n getStrategy: (slot, fb) => this._ovk.getStrategy(slot, fb),\r\n });\r\n\r\n // ── grid.override() 확장 커널 부착 (★mount 전 — 초기 렌더의 footer/그룹/strategy 슬롯이\r\n // 매니저 deps의 getStrategy 클로저를 통해 this._ovk 를 참조하므로, _ovk 선생성이 필수다.\r\n // 이전엔 mount 이후 생성하여 summary 푸터가 있는 그리드가 초기화 중\r\n // \"Cannot read properties of undefined (reading 'getStrategy')\" 로 깨졌다.) ──\r\n this._ovk = new OverrideKernel(this, { strict: this._options.overrideStrict ?? true });\r\n // Phase 2: DataLayer(슬롯 sortComparator/filterPredicate) + 렌더러(displayFormatter) strategy 배선.\r\n this._data.setStrategyResolver((slot, fb) => this._ovk.getStrategy(slot, fb));\r\n setDisplayFormatterResolver((v, f, row) =>\r\n this._ovk.getStrategy('displayFormatter', null as any)?.(v, f, row) ?? null,\r\n );\r\n\r\n this._mount();\r\n this._bindOptionEvents();\r\n\r\n if (this._options.defaultSort?.length) {\r\n this._sfMgr.initSort(this._options.defaultSort);\r\n }\r\n\r\n this.override = Object.assign(\r\n (name: string, fn: OverrideLayer, opts?: OverrideCallOptions) => this._ovk.override(name, fn, opts) as any,\r\n { strategy: (slot: string, fn: Function) => this._ovk.strategy(slot, fn) as any },\r\n ) as OverrideApi<T>;\r\n\r\n // destroy 순수 래핑(94 §2.2 채택안2): 원본 본문 0줄 수정, 최외곽에서 restoreAll 보장.\r\n const _origDestroy = this.destroy.bind(this);\r\n this.destroy = () => { try { _origDestroy(); } finally { this._ovk.restoreAll(); } };\r\n\r\n // 정적 전역 defaults 1회 적용(첫 렌더 후, 깜빡임 방지).\r\n for (const [slot, fn] of OpenGrid._defaultStrategies) this._ovk.strategy(slot, fn);\r\n for (const [name, fn, opts] of OpenGrid._defaultOverrides) this._ovk.override(name, fn, opts);\r\n\r\n requestAnimationFrame(() => {\r\n this.emit('ready', this);\r\n this._options.onReady?.(this);\r\n });\r\n }\r\n\r\n // ── grid.override() 위임 메서드 ──────────────────────────\r\n restore(name: string): this { this._ovk.restore(name); return this; }\r\n restoreAll(): this { this._ovk.restoreAll(); return this; }\r\n hasOverride(name: string): boolean { return this._ovk.hasOverride(name); }\r\n getOverrideNames(): string[] { return this._ovk.getOverrideNames(); }\r\n getStrategy<F extends Function>(slot: string, fallback: F): F { return this._ovk.getStrategy(slot, fallback); }\r\n private _mount(): void {\r\n this._container.classList.add('og-container');\r\n const h = this._options.height;\r\n const w = this._options.width;\r\n this._container.style.height = typeof h === 'number' ? `${h}px` : String(h);\r\n this._container.style.width = typeof w === 'number' ? `${w}px` : String(w);\r\n this._container.style.display = 'flex';\r\n this._container.style.flexDirection = 'column';\r\n this._container.style.overflow = 'hidden';\r\n this._container.style.boxSizing = 'border-box';\r\n this._container.style.border = '1px solid var(--og-border-color, #e0e0e0)';\r\n this._container.style.fontFamily = 'var(--og-font-family, -apple-system, sans-serif)';\r\n this._container.style.fontSize = 'var(--og-font-size, 13px)';\r\n this._container.setAttribute('data-og-theme', this._options.theme);\r\n\r\n for (const [k, v] of Object.entries(this._options.cssVars))\r\n this._container.style.setProperty(k, v);\r\n\r\n this._renderer = new GridRenderer(this._container, this._options, {\r\n onHeaderClick: (field, shiftKey) => this._handleSortClick(field, shiftKey),\r\n onCellClick: (ri, ci, e) => this._handleCellClick(ri, ci, e),\r\n onCellDblClick: (ri, ci, e) => this._handleCellDblClick(ri, ci, e),\r\n onCellMouseOver: (ri, ci, e) => this._handleCellMouseOver(ri, ci, e),\r\n onCellMouseOut: (ri, ci, e) => this._handleCellMouseOut(ri, ci, e),\r\n onCellMouseDown: (ri, ci, e) => this._handleCellMouseDown(ri, ci, e),\r\n onCellMouseUp: (ri, ci, e) => this._handleCellMouseUp(ri, ci, e),\r\n onCellMouseMove: (ri, ci, e) => this._handleCellMouseMove(ri, ci, e),\r\n onRowCheck: (ri, checked) => this._handleRowCheck(ri, checked),\r\n onAllCheck: (checked) => this._handleAllCheck(checked),\r\n onColResize: (ci, w) => this._handleColResize(ci, w),\r\n onFilterIconClick: (field, anchorEl) => this._handleFilterIconClick(field, anchorEl),\r\n getDndManager: () => this._dnd,\r\n onColDragStart: (ci) => { this._editMgr.dragColIdx = ci; },\r\n onColDrop: (toIdx) => {\r\n if (this._editMgr.dragColIdx !== null && this._editMgr.dragColIdx !== toIdx) {\r\n this._reorderColumn(this._editMgr.dragColIdx, toIdx);\r\n }\r\n this._editMgr.dragColIdx = null;\r\n },\r\n getColDragIdx: () => this._editMgr.dragColIdx,\r\n });\r\n\r\n this._filterPanel = new FilterPanel(\r\n this._container,\r\n (field, items) => this.setFilter(field, items),\r\n (field) => this.resetFilter(field)\r\n );\r\n // 웹 접근성 속성 설정 (role, aria 레이블, 행/열 수 알림)\r\n // ?묎렐?? role, aria-label, aria-rowcount, aria-colcount\r\n this._container.setAttribute('role', 'grid');\r\n this._container.setAttribute('aria-label', this._options.ariaLabel ?? this._options.cssVars?.['aria-label'] ?? 'OPEN_GRID 데이터 그리드');\r\n this._container.setAttribute('aria-rowcount', '0');\r\n this._container.setAttribute('aria-colcount', String(this._options.columns.filter(c => !c.hidden).length));\r\n // aria-live 영역: 스크린리더에게 상태 변화를 알린다\r\n this._liveRegion = document.createElement('div');\r\n this._liveRegion.setAttribute('aria-live', 'polite');\r\n this._liveRegion.setAttribute('aria-atomic', 'true');\r\n this._liveRegion.className = 'og-live-region';\r\n this._container.insertAdjacentElement('beforebegin', this._liveRegion);\r\n // 키보드로 그리드를 조작할 수 있도록 tabIndex 설정\r\n this._container.tabIndex = 0;\r\n this._container.addEventListener('keydown', (e) => this._handleKeyDown(e));\r\n this._container.addEventListener('keyup', (e) => this._handleCellKeyEvt('cellKeyUp', e));\r\n this._container.addEventListener('keypress', (e) => this._handleCellKeyEvt('cellKeyPress', e));\r\n\r\n this._vs = new VirtualScroll(this._renderer.bodyWrapper, {\r\n rowHeight: this._options.rowHeight,\r\n onRender: (s, e) => this._doRender(s, e),\r\n });\r\n\r\n // 그리드↔그리드 드래그용 레지스트리 등록 (bodyWrapper 기준)\r\n crossGridRegistry.register(this._renderer.bodyWrapper, this);\r\n\r\n if (this._options.draggable) {\r\n this._dnd = new RowDragDrop(\r\n this._renderer.bodyWrapper,\r\n this._options.rowHeight,\r\n (from, to) => this._handleRowDrop(from, to),\r\n this._options.crossGrid ? {\r\n resolveTarget: (x, y) => {\r\n const g = crossGridRegistry.resolveAt(x, y, this);\r\n if (!g || !g._options.crossGrid) return null;\r\n return { bodyEl: g._crossBodyEl(), rowHeight: g._options.rowHeight, totalRows: g._data.rowCount };\r\n },\r\n onCrossDrop: (fromIndex, targetBodyEl, targetIndex) =>\r\n this._handleCrossGridDrop(fromIndex, targetBodyEl, targetIndex),\r\n } : undefined,\r\n (fromIndex) => this._dragRowSet(fromIndex).length,\r\n );\r\n }\r\n // 스크롤 영역, 페이징 바 등 하단 UI 초기화\r\n // ?섏씠吏?UI (?듭뀡?먯꽌 pagination:true???뚮쭔)\r\n if (this._options.pagination) {\r\n this._pagination = new Pagination(\r\n this._container,\r\n this._options.pageSize,\r\n (e) => {\r\n this.emit('pageChange', e);\r\n this._doRender(...this._visRange());\r\n }\r\n );\r\n }\r\n // 찾기 바 초기화 (헤더 위에 삽입)\r\n this._findMgr.init(this._container);\r\n // 오른쪽 클릭 메뉴 초기화\r\n this._initContextMenu();\r\n // 워크시트(탭) 초기화\r\n if (this._options.worksheets?.length) {\r\n this._initWorksheets();\r\n }\r\n\r\n this._ro = new ResizeObserver(() => this._onResize());\r\n this._ro.observe(this._container);\r\n this._onResize();\r\n }\r\n\r\n private _initContextMenu(): void {\r\n const opt = this._options.contextMenu;\r\n if (opt === false) return;\r\n\r\n // 기존 핸들러 제거 — setOptions 재호출 시 중복 등록 방지\r\n if (this._cmHandler) this._container.removeEventListener('contextmenu', this._cmHandler);\r\n if (this._cmKbdHandler) this._container.removeEventListener('keydown', this._cmKbdHandler);\r\n this._cmHandler = this._cmKbdHandler = null;\r\n\r\n this._ctxMenu = new ContextMenuManager(this._container, {\r\n onSortAsc: () => {\r\n const active = this._colLayout.visibleLeaves[0];\r\n if (active) this.orderBy(active.field, 'asc');\r\n },\r\n onSortDesc: () => {\r\n const active = this._colLayout.visibleLeaves[0];\r\n if (active) this.orderBy(active.field, 'desc');\r\n },\r\n onFind: () => this._findMgr.open(),\r\n onExcel: () => this.exportExcel(),\r\n onCsv: () => this.exportCsv(),\r\n onPrint: () => this.print(),\r\n });\r\n\r\n this._cmHandler = (e: MouseEvent) => {\r\n const cell = (e.target as HTMLElement).closest<HTMLElement>('.og-cell');\r\n if (!cell) return;\r\n e.preventDefault();\r\n\r\n const colIdx = Number(cell.dataset.colIndex ?? -1);\r\n const col = this._colLayout.visibleLeaves[colIdx];\r\n\r\n if (col && this._ctxMenu) {\r\n this._ctxMenu['_actions'].onSortAsc = () => this.orderBy(col.field, 'asc');\r\n this._ctxMenu['_actions'].onSortDesc = () => this.orderBy(col.field, 'desc');\r\n }\r\n\r\n // 사용자 정의 메뉴는 단독 표시 (기본 메뉴와 합치지 않음)\r\n const customItems = Array.isArray(opt) ? opt : undefined;\r\n this._ctxMenu?.open(e, customItems);\r\n };\r\n this._container.addEventListener('contextmenu', this._cmHandler);\r\n\r\n this._cmKbdHandler = (e: KeyboardEvent) => {\r\n if (e.shiftKey && e.key === 'F10') {\r\n e.preventDefault();\r\n const rect = this._container.getBoundingClientRect();\r\n const fakeEvent = { clientX: rect.left + 80, clientY: rect.top + 40 } as MouseEvent;\r\n this._ctxMenu?.open(fakeEvent);\r\n }\r\n };\r\n this._container.addEventListener('keydown', this._cmKbdHandler);\r\n }\r\n // openContextMenu / closeContextMenu 공개 API\r\n openContextMenu(e: MouseEvent, items?: import('./types').ContextMenuItem[]): void {\r\n this._ctxMenu?.open(e, items);\r\n }\r\n closeContextMenu(): void {\r\n this._ctxMenu?.close();\r\n }\r\n setFilterSelect(config: FilterSelectConfig | null): void {\r\n this._filterSelect?.destroy();\r\n this._filterSelect = null;\r\n if (!config) return;\r\n if (!this._container.id) {\r\n this._container.id = `og-${Math.random().toString(36).slice(2, 7)}`;\r\n }\r\n this._filterSelect = new FilterSelectPanel(\r\n this._container, config,\r\n (field, items) => this.setFilter(field, items),\r\n (field?) => this.resetFilter(field),\r\n this._container.id\r\n );\r\n }\r\n // 옵션을 런타임에 바꿀 때 호출 (contextMenu 재초기화, groupBy 재구성 등)\r\n setOptions(opts: Partial<GridOptions<T>>): void {\r\n Object.assign(this._options, opts);\r\n if ('contextMenu' in opts) {\r\n this._ctxMenu?.destroy();\r\n this._ctxMenu = null;\r\n this._initContextMenu();\r\n }\r\n // groupBy / summary 변경 시 그룹 재구성\r\n if ('groupBy' in opts || 'summary' in opts) {\r\n const fields = (opts.groupBy ?? []) as string[];\r\n if (fields.length > 0) {\r\n this._grpMgr.groupBy(fields);\r\n } else {\r\n this.clearGroup();\r\n }\r\n return;\r\n }\r\n this._renderHeader();\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n /**\r\n * 컬럼 마스킹 ON/OFF 전환.\r\n * enabled=true → 마스킹 적용 (기본 상태)\r\n * enabled=false → 컬럼 전체 마스킹 해제 (원문 표시)\r\n */\r\n setMaskEnabled(field: string, enabled: boolean): void {\r\n const col = this._colLayout.getColumnByField(field) as any;\r\n if (!col) return;\r\n if (enabled) {\r\n // 마스킹 재활성화: 해제 상태 초기화\r\n col._maskRevealed = false;\r\n (col._maskRevealedRows as Set<number> | undefined)?.clear();\r\n } else {\r\n // 전체 해제\r\n col._maskRevealed = true;\r\n }\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n /** 현재 컬럼 마스킹 활성 여부 반환. true=마스킹 중, false=해제됨 */\r\n getMaskEnabled(field: string): boolean {\r\n const col = this._colLayout.getColumnByField(field) as any;\r\n if (!col) return false;\r\n return col._maskRevealed !== true;\r\n }\r\n private _initWorksheets(): void {\r\n const sheets = this._options.worksheets!;\r\n this._wsManager = new WorksheetManager<T>(\r\n this._container,\r\n (_name, state) => {\r\n // 탭을 전환할 때 데이터와 컬럼을 업데이트한다\r\n this._data.setData(state.data);\r\n this._colLayout = new ColumnLayout<T>(\r\n state.columns.length ? state.columns : this._options.columns,\r\n this._options.frozenColumns,\r\n );\r\n this._doRender(...this._visRange());\r\n this._renderHeader();\r\n }\r\n );\r\n for (const sheet of sheets) {\r\n this._wsManager.add(sheet.name, sheet.columns ?? this._options.columns, sheet.data ?? []);\r\n }\r\n }\r\n\r\n addWorksheet(name: string, columns?: import('./types').ColumnDef<T>[], data?: T[]): void {\r\n if (!this._wsManager) {\r\n this._wsManager = new WorksheetManager<T>(\r\n this._container,\r\n (_n, state) => {\r\n this._data.setData(state.data);\r\n this._colLayout = new ColumnLayout<T>(\r\n state.columns.length ? state.columns : this._options.columns,\r\n this._options.frozenColumns,\r\n );\r\n this._doRender(...this._visRange());\r\n this._renderHeader();\r\n }\r\n );\r\n }\r\n this._wsManager.add(name, columns ?? this._options.columns, data ?? []);\r\n }\r\n\r\n removeWorksheet(name: string): void {\r\n this._wsManager?.remove(name);\r\n }\r\n\r\n switchWorksheet(name: string): void {\r\n this._wsManager?.switch(name);\r\n }\r\n\r\n renameWorksheet(oldName: string, newName: string): void {\r\n this._wsManager?.rename(oldName, newName);\r\n }\r\n\r\n getWorksheet(name: string): import('./types').WorksheetState<T> | undefined {\r\n return this._wsManager?.get(name);\r\n }\r\n\r\n getWorksheetNames(): string[] {\r\n return this._wsManager?.getNames() ?? [];\r\n }\r\n\r\n exportSheetsExcel(filename?: string): void { this._exportMgr.exportSheetsExcel(filename); }\r\n\r\n private _paginationHeight(): number {\r\n return this._options.pagination ? 38 : 0;\r\n }\r\n\r\n private _onResize(): void {\r\n const { width } = this._container.getBoundingClientRect();\r\n if (!width) return;\r\n this._recalcWidths(width);\r\n // _renderHeader() 가 헤더를 그린 뒤 실제 헤더 높이를 측정해 본문/뷰포트 높이를 동기화한다\r\n // (headerWrap/'\\n' 로 헤더가 늘어나도 본문 영역이 침범당하지 않도록).\r\n this._renderHeader();\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n private _recalcWidths(totalWidth: number): void {\r\n this._colWidths = this._colLayout.computeWidths(\r\n totalWidth\r\n - (this._options.stateColumn ? 24 : 0)\r\n - (this._options.draggable ? 18 : 0)\r\n - (this._options.rowNumber ? 44 : 0)\r\n - (this._options.checkColumn ? 36 : 0),\r\n this._options.defaultColumnWidth\r\n );\r\n // 사용자가 직접 조절한 폭은 보존 (리사이즈 후 재계산으로 원복되는 문제 방지)\r\n if (this._userWidths.size) {\r\n this._colLayout.visibleLeaves.forEach((leaf, i) => {\r\n const w = this._userWidths.get(leaf.field);\r\n if (w != null) this._colWidths[i] = w;\r\n });\r\n }\r\n }\r\n // 헤더(컬럼 제목 행)를 다시 그린다\r\n private _renderHeader(): void {\r\n this._renderer?.renderHeader(\r\n this._colLayout.buildHeaderCells(),\r\n this._colLayout.visibleLeaves,\r\n this._colWidths,\r\n this._sfMgr.sortList,\r\n { ...this._options, _activeFilters: this._sfMgr.filters, _frozenCount: this._colLayout.frozenCount }\r\n );\r\n // 헤더 줄바꿈(headerWrap/'\\n')으로 헤더가 늘어나면 본문 영역 높이를 다시 맞춰 침범을 막는다.\r\n this._syncHeaderLayout();\r\n }\r\n\r\n /**\r\n * 렌더된 헤더의 실제 높이를 측정해 본문(bodyWrap) 높이와 뷰포트 높이에 반영한다.\r\n * 줄바꿈이 없는 헤더는 측정 높이가 headerHeight 이하라 기존 고정 동작과 동일하다.\r\n */\r\n private _syncHeaderLayout(): void {\r\n if (!this._renderer || !this._vs) return;\r\n const { height } = this._container.getBoundingClientRect();\r\n if (!height) return;\r\n const measured = this._renderer.getHeaderHeight();\r\n const headerH = measured > this._options.headerHeight ? measured : this._options.headerHeight;\r\n this._renderer.updateSize(height - this._paginationHeight(), headerH);\r\n this._vs.setViewportHeight(height - headerH - this._paginationHeight());\r\n }\r\n private _doRender(startIndex: number, endIndex: number): void {\r\n if (!this._renderer || !this._vs) return;\r\n const range = this._vs.getVisibleRange();\r\n // autoHeight(비가상): 행을 플로우로 쌓으므로 offsetY/totalHeight 절대배치를 쓰지 않는다.\r\n // 스크롤 등으로 부분 범위가 들어와도 전체를 렌더(가상화 안 함)해 행 누락을 막는다.\r\n const auto = this._options.autoHeight === true;\r\n if (auto) {\r\n [startIndex, endIndex] = this._visRange();\r\n // 대용량 가드: autoHeight 는 전 행을 렌더(비가상)하므로 행이 많으면 느려진다(1회 경고).\r\n if (!this._autoHeightWarned && endIndex - startIndex + 1 > 2000) {\r\n this._autoHeightWarned = true;\r\n console.warn(\r\n `[OpenGrid] autoHeight 는 가상 스크롤이 아니라 전 행(${endIndex - startIndex + 1}행)을 렌더합니다. ` +\r\n '행이 많으면 고정 rowHeight(가상 스크롤) 사용을 권장합니다.');\r\n }\r\n }\r\n this._renderer.renderBody(\r\n startIndex, endIndex,\r\n this._data,\r\n this._colLayout.visibleLeaves,\r\n this._colWidths,\r\n this._options,\r\n auto ? 0 : range.offsetY,\r\n auto ? 0 : this._vs.getTotalHeight(),\r\n this._rowMgr.selectedRows,\r\n this._rowMgr.checkedRows,\r\n this._grpMgr.isGroupMode ? this._grpMgr.groupFlatRows : (this._grpMgr.isTreeMode ? this._grpMgr.treeFlatRows : null),\r\n (groupKey) => this._grpMgr.handleGroupToggle(groupKey),\r\n this._grpMgr.isTreeMode ? (nodeId) => this._grpMgr.handleTreeToggle(nodeId) : undefined,\r\n { _totalRows: this._data.rowCount, _frozenCount: this._colLayout.frozenCount, _focusCell: this._editMgr.focusCell },\r\n this._mergeEngine\r\n );\r\n // 데이터가 바뀌면 푸터 합계도 다시 계산한다\r\n if (this._options.footer?.length) this._renderFooterEl();\r\n }\r\n\r\n private _handleGroupToggle(groupKey: string): void { this._grpMgr.handleGroupToggle(groupKey); }\r\n\r\n // 현재 화면에 보이는 행 범위를 반환한다\r\n private _visRange(): [number, number] {\r\n if (this._options.pagination && this._pagination) {\r\n const { start, end } = this._pagination.getRange();\r\n return [start, end];\r\n }\r\n // autoHeight(비가상): 가상화하지 않고 전체 행을 렌더 (높이가 행마다 다르므로 범위 계산 불가)\r\n if (this._options.autoHeight) {\r\n const total = this._grpMgr.isGroupMode ? this._grpMgr.groupFlatRows.length\r\n : this._grpMgr.isTreeMode ? this._grpMgr.treeFlatRows.length\r\n : this._data.rowCount;\r\n return [0, total - 1];\r\n }\r\n const r = this._vs?.getVisibleRange();\r\n return [r?.startIndex ?? 0, Math.min((r?.endIndex ?? 30) + this._visCount() + 5, this._data.rowCount - 1)];\r\n }\r\n\r\n private _visCount(): number {\r\n const h = this._container.getBoundingClientRect().height;\r\n return Math.ceil((h - this._options.headerHeight - this._paginationHeight()) / this._options.rowHeight) + 5;\r\n }\r\n private _handleSortClick(field: string, shiftKey: boolean): void { this._sfMgr.handleSortClick(field, shiftKey); }\r\n\r\n private _isToggleCol(col: ColumnDef<T>): boolean { return isToggleCol(col); }\r\n private _handleCellClick(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellClick(ri, ci, e); }\r\n private _handleCellDblClick(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellDblClick(ri, ci, e); }\r\n private _handleCellMouseOver(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseOver(ri, ci, e); }\r\n private _handleCellMouseOut(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseOut(ri, ci, e); }\r\n private _handleCellMouseDown(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseDown(ri, ci, e); }\r\n private _handleCellMouseUp(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseUp(ri, ci, e); }\r\n private _handleCellMouseMove(ri: number, ci: number, e: MouseEvent): void { this._cellEvt.handleCellMouseMove(ri, ci, e); }\r\n private _handleCellKeyEvt(name: 'cellKeyDown' | 'cellKeyUp' | 'cellKeyPress', e: KeyboardEvent): void { this._cellEvt.handleCellKeyEvt(name, e); }\r\n\r\n private _handleRowCheck(rowIndex: number, checked: boolean): void {\r\n this._rowMgr.check(rowIndex, checked);\r\n this._doRender(...this._visRange());\r\n this.emit('rowCheck', { rowIndex, checked, row: this._data.getRowByIndex(rowIndex) });\r\n }\r\n\r\n private _handleFilterIconClick(field: string, anchorEl: HTMLElement): void {\r\n if (this._filterPanel?.isOpen) {\r\n this._filterPanel.close();\r\n return;\r\n }\r\n const current = this._sfMgr.filters[field] ?? [];\r\n this._filterPanel?.open(field, anchorEl, current);\r\n }\r\n\r\n private _handleAllCheck(checked: boolean): void {\r\n this._rowMgr.checkAll(checked, this._data.rowCount);\r\n this._doRender(...this._visRange());\r\n this.emit('allCheck', { checked });\r\n }\r\n private _handleRowDrop(fromIndex: number, toIndex: number): void {\r\n this._data.moveRow(fromIndex, toIndex);\r\n this._doRender(...this._visRange());\r\n this.emit('rowDrop', { fromIndex, toIndex });\r\n this._options.onRowDrop?.({ fromIndex, toIndex });\r\n }\r\n\r\n // ── 크로스그리드 내부 헬퍼 ──\r\n /** 드래그/셔틀이 참조하는 바디 엘리먼트 (레지스트리 해석용) */\r\n _crossBodyEl(): HTMLElement { return this._renderer!.bodyWrapper; }\r\n /** fromIndex 를 잡고 드래그할 때 함께 이동할 행 집합 (다중선택에 포함되면 선택 전체) */\r\n private _dragRowSet(fromIndex: number): number[] {\r\n const sel = [...this._rowMgr.selectedRows];\r\n return (sel.length > 1 && sel.includes(fromIndex))\r\n ? sel.sort((a, b) => a - b)\r\n : [fromIndex];\r\n }\r\n\r\n /** 드래그 드롭 어댑터 → 공개 moveRowsTo 로 위임 */\r\n private _handleCrossGridDrop(fromIndex: number, targetBodyEl: HTMLElement, targetIndex: number): void {\r\n const targetGrid = crossGridRegistry.get(targetBodyEl) as OpenGrid<T> | undefined;\r\n if (!targetGrid || targetGrid === this) return;\r\n void this.moveRowsTo(targetGrid, this._dragRowSet(fromIndex), targetIndex);\r\n }\r\n\r\n /**\r\n * 이 그리드의 행들을 다른 그리드로 이동(move)한다. 드래그·화살표 셔틀 공통 경로.\r\n * 3단계 이벤트(before→after→complete)와 crossGridMapping(필드 매핑)을 적용한다.\r\n * @param targetGrid 대상 그리드\r\n * @param sourceIndexes 이동할 (표시)행 인덱스들\r\n * @param targetIndex 대상에서 삽입 위치 (생략 시 맨 끝에 추가)\r\n * @returns 이동 성공 true, 취소/무효 false\r\n */\r\n async moveRowsTo(\r\n target: OpenGridInstance<T>,\r\n sourceIndexes: number[],\r\n targetIndex?: number,\r\n ): Promise<boolean> {\r\n const targetGrid = target as OpenGrid<T>;\r\n if (!targetGrid || targetGrid === this || !sourceIndexes.length) return false;\r\n const idxAsc = [...new Set(sourceIndexes)].sort((a, b) => a - b);\r\n const at = targetIndex ?? targetGrid._data.rowCount;\r\n\r\n // 행 데이터 복사 (내부 id 제거 → 타깃이 새 id 부여)\r\n let rows = idxAsc.map(i => {\r\n const r = { ...(this._data.getRowByIndex(i) as any) };\r\n delete r[ROW_ID_FIELD];\r\n return r as T;\r\n });\r\n\r\n // 필드 매핑 (스키마가 다른 그리드 간 이동)\r\n const transform = await this._resolveCrossTransform(targetGrid);\r\n if (transform === false) return false; // 매핑 모달 취소\r\n if (transform) rows = rows.map(r => transform(r) as T);\r\n\r\n const evt: GridDropEvent<T> = {\r\n sourceGrid: this, targetGrid, rows, sourceIndexes: idxAsc, targetIndex: at,\r\n };\r\n\r\n // ① 변경전 (양쪽). false 반환 또는 cancel=true 면 중단\r\n if (this._fireGridDropBefore(evt) === false || evt.cancel) return false;\r\n if (targetGrid._fireGridDropBefore(evt) === false || evt.cancel) return false;\r\n\r\n // 이동: 타깃에 순서대로 삽입 → 소스에서 내림차순 제거\r\n rows.forEach((row, k) => targetGrid.insertRow(row as Partial<T>, at + k));\r\n [...idxAsc].sort((a, b) => b - a).forEach(i => this.deleteRow(i));\r\n\r\n // ② 변경후\r\n this._fireGridDropAfter(evt);\r\n targetGrid._fireGridDropAfter(evt);\r\n // ③ 완료시 (insert/delete 가 이미 양쪽 재렌더)\r\n this._fireGridDropComplete(evt);\r\n targetGrid._fireGridDropComplete(evt);\r\n return true;\r\n }\r\n\r\n /** 체크된 행을 다른 그리드로 이동 (화살표 셔틀용). 체크 없으면 무시. */\r\n async moveCheckedTo(target: OpenGridInstance<T>): Promise<boolean> {\r\n const indexes = this._rowMgr.getChecked().map(c => c.rowIndex);\r\n if (!indexes.length) return false;\r\n this._rowMgr.uncheckAll();\r\n return this.moveRowsTo(target, indexes);\r\n }\r\n\r\n /**\r\n * 크로스그리드 이동의 행 변환 함수를 결정한다.\r\n * 반환: null=변환 불필요(그대로) / 함수=변환 적용 / false=매핑 모달 취소(이동 중단)\r\n */\r\n private async _resolveCrossTransform(targetGrid: OpenGrid<T>): Promise<((src: any) => any) | null | false> {\r\n const mode = this._options.crossGridMapping;\r\n if (typeof mode === 'function') return mode as (src: any) => any;\r\n if (mode !== 'interactive') return null; // 'auto' → 그대로 복사\r\n\r\n const srcInfos: FieldInfo[] = this._colLayout.visibleLeaves.map(c => ({ field: c.field, header: c.header }));\r\n const tgtInfos: FieldInfo[] = targetGrid._colLayout.visibleLeaves.map(c => ({ field: c.field, header: c.header }));\r\n if (sameSchema(srcInfos.map(f => f.field), tgtInfos.map(f => f.field))) return null; // 스키마 동일 → 모달 불필요\r\n\r\n const result = await openCrossGridMapper(srcInfos, tgtInfos);\r\n if (!result) return false; // 취소\r\n const mapEvt: GridMappingEvent<T> = {\r\n sourceGrid: this, targetGrid,\r\n mapping: result.mapping, script: result.script,\r\n };\r\n this.emit('gridDropMapping', mapEvt);\r\n this._options.onGridDropMapping?.(mapEvt);\r\n // 콘솔에도 출력 — 개발자가 바로 복사해 baking 하도록\r\n console.log('[OpenGrid] cross-grid mapping script:\\n' + buildMappingScript(result.mapping));\r\n return buildTransform(result.mapping);\r\n }\r\n\r\n private _fireGridDropBefore(e: GridDropEvent<T>): boolean | void {\r\n this.emit('gridDropBefore', e);\r\n return this._options.onGridDropBefore?.(e);\r\n }\r\n private _fireGridDropAfter(e: GridDropEvent<T>): void {\r\n this.emit('gridDropAfter', e);\r\n this._options.onGridDropAfter?.(e);\r\n }\r\n private _fireGridDropComplete(e: GridDropEvent<T>): void {\r\n this.emit('gridDropComplete', e);\r\n this._options.onGridDropComplete?.(e);\r\n }\r\n /** 행을 드롭으로 이동할 때 실행된다 */\r\n /** ???꾩튂 ?대룞 */\r\n reorderRow(fromIndex: number, toIndex: number): void {\r\n this._data.moveRow(fromIndex, toIndex);\r\n this._doRender(...this._visRange());\r\n }\r\n private _handleColResize(colIndex: number, newWidth: number): void {\r\n if (this._colWidths[colIndex] !== undefined) {\r\n this._colWidths[colIndex] = newWidth;\r\n }\r\n // 사용자가 조절한 폭을 field 기준으로 기억 → 이후 재계산(_recalcWidths)에서 보존\r\n const leaf = this._colLayout.visibleLeaves[colIndex];\r\n if (leaf) this._userWidths.set(leaf.field, newWidth);\r\n this._renderHeader(); // 헤더 폭도 즉시 동기화\r\n this._doRender(...this._visRange());\r\n }\r\n private _handleKeyDown(e: KeyboardEvent): void { this._kbdMgr.handleKeyDown(e); }\r\n\r\n private _setFocusCell(ri: number, ci: number): void {\r\n this._rowMgr.selectSingle(ri);\r\n this._editMgr.setFocusCell(ri, ci);\r\n }\r\n // 스크린리더에게 텍스트를 읽어준다 (aria-live)\r\n private _announce(msg: string): void {\r\n if (!this._liveRegion) return;\r\n this._liveRegion.textContent = '';\r\n setTimeout(() => { if (this._liveRegion) this._liveRegion.textContent = msg; }, 50);\r\n }\r\n\r\n private _bindOptionEvents(): void {\r\n if (this._options.onCellClick) this.on('cellClick', this._options.onCellClick);\r\n if (this._options.onCellDblClick) this.on('cellDblClick', this._options.onCellDblClick);\r\n if (this._options.onRowClick) this.on('rowClick', this._options.onRowClick);\r\n if (this._options.onEditStart) this.on('editStart', this._options.onEditStart);\r\n if (this._options.onEditEnd) this.on('editEnd', this._options.onEditEnd);\r\n if (this._options.onSortChange) this.on('sortChange', this._options.onSortChange);\r\n if (this._options.onFilterChange) this.on('filterChange', this._options.onFilterChange);\r\n if (this._options.onScroll) this.on('scroll', this._options.onScroll);\r\n if (this._options.onDataChange) this.on('dataChange', this._options.onDataChange);\r\n if (this._options.onSelectionChange) this.on('selectionChange', this._options.onSelectionChange);\r\n // Sprint 35 ?좉퇋\r\n if (this._options.onRowDblClick) this.on('rowDblClick', this._options.onRowDblClick);\r\n if (this._options.onRowMouseOver) this.on('rowMouseOver', this._options.onRowMouseOver);\r\n if (this._options.onRowMouseOut) this.on('rowMouseOut', this._options.onRowMouseOut);\r\n if (this._options.onRowMouseDown) this.on('rowMouseDown', this._options.onRowMouseDown);\r\n if (this._options.onRowMouseUp) this.on('rowMouseUp', this._options.onRowMouseUp);\r\n if (this._options.onRowMouseMove) this.on('rowMouseMove', this._options.onRowMouseMove);\r\n if (this._options.onCellMouseOver) this.on('cellMouseOver', this._options.onCellMouseOver);\r\n if (this._options.onCellMouseOut) this.on('cellMouseOut', this._options.onCellMouseOut);\r\n if (this._options.onCellMouseDown) this.on('cellMouseDown', this._options.onCellMouseDown);\r\n if (this._options.onCellMouseUp) this.on('cellMouseUp', this._options.onCellMouseUp);\r\n if (this._options.onCellMouseMove) this.on('cellMouseMove', this._options.onCellMouseMove);\r\n if (this._options.onCellKeyDown) this.on('cellKeyDown', this._options.onCellKeyDown);\r\n if (this._options.onCellKeyUp) this.on('cellKeyUp', this._options.onCellKeyUp);\r\n if (this._options.onCellKeyPress) this.on('cellKeyPress', this._options.onCellKeyPress);\r\n }\r\n setData(data: T[]): void {\r\n const ctx = this._trigMgr.mkCtx('setData', [data]);\r\n if (!this._trigMgr.exec('before:setData', ctx)) return;\r\n this._rowMgr.reset();\r\n this._data.setData(data);\r\n this._applyFilters();\r\n if (this._grpMgr.isTreeMode) {\r\n this._grpMgr.rebuildTree();\r\n } else if (this._grpMgr.isGroupMode) {\r\n this._grpMgr.rebuildGroups();\r\n } else {\r\n this._vs?.setTotalRows(this._data.rowCount);\r\n }\r\n this._container.setAttribute('aria-rowcount', String(this._data.rowCount));\r\n this._container.setAttribute('aria-colcount', String(this._colLayout.visibleLeaves.length));\r\n this._announce(`${this._data.rowCount}행 데이터 로드됨`);\r\n this.emit('dataChange', this._data.getData());\r\n ctx.result = data.length;\r\n this._trigMgr.exec('after:setData', ctx);\r\n }\r\n\r\n getData(): T[] { return this._data.getData(); }\r\n getSourceRows(): T[] { return this._data.getOriginalData(); }\r\n\r\n pushData(data: T[]): void {\r\n const combined = [...this._data.getAllData(), ...data];\r\n this._data.setData(combined);\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n }\r\n\r\n prefixData(data: T[]): void {\r\n const combined = [...data, ...this._data.getAllData()];\r\n this._data.setData(combined);\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n }\r\n\r\n clearData(): void {\r\n this._rowMgr.reset();\r\n this._data.clearData();\r\n this._vs?.setTotalRows(0);\r\n this._pagination?.setTotalRows(0);\r\n this._doRender(0, -1);\r\n this.emit('dataChange', []);\r\n }\r\n\r\n insertRow(item: Partial<T>, position: Position = 'last'): void {\r\n const ctx = this._trigMgr.mkCtx('insertRow', [item, position]);\r\n if (!this._trigMgr.exec('before:insertRow', ctx)) return;\r\n const pos = position === 'before' ? 0\r\n : position === 'after' ? this._data.rowCount\r\n : position as any;\r\n this._data.addRow(item, pos);\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n ctx.result = { rowCount: n, item };\r\n this._trigMgr.exec('after:insertRow', ctx);\r\n }\r\n\r\n pushRow(items: Partial<T> | Partial<T>[]): void {\r\n const arr = Array.isArray(items) ? items : [items];\r\n arr.forEach(it => this._data.addRow(it, 'last'));\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n }\r\n\r\n /** @deprecated 하위호환 alias → pushRow */\r\n appendRows(items: Partial<T> | Partial<T>[]): void { this.pushRow(items); }\r\n\r\n unshiftRow(items: Partial<T> | Partial<T>[]): void {\r\n const arr = Array.isArray(items) ? items : [items];\r\n arr.forEach(it => this._data.addRow(it, 'first'));\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n }\r\n\r\n /** @deprecated 하위호환 alias → unshiftRow */\r\n prependRows(items: Partial<T> | Partial<T>[]): void { this.unshiftRow(items); }\r\n\r\n deleteRow(rowIndex: number | number[]): void {\r\n const ctx = this._trigMgr.mkCtx('deleteRow', [rowIndex]);\r\n const idxArr = Array.isArray(rowIndex) ? [...rowIndex] : [rowIndex];\r\n ctx.extra = { rows: idxArr.map(i => this._data.getRowByIndex(i)) };\r\n if (!this._trigMgr.exec('before:deleteRow', ctx)) return;\r\n const idxs = idxArr.sort((a, b) => b - a);\r\n idxs.forEach(i => this._data.removeRow(i));\r\n const n = this._data.rowCount;\r\n this._vs?.setTotalRows(n);\r\n this._pagination?.setTotalRows(n);\r\n this._doRender(...this._visRange());\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n ctx.result = { deleted: idxs.length, rowCount: n };\r\n this._trigMgr.exec('after:deleteRow', ctx);\r\n }\r\n\r\n deleteById(_ids: string[]): void { /* 異뷀썑 援ы쁽 */ }\r\n\r\n readCell(rowIndex: number, field: string): any {\r\n return this._data.getCellValue(rowIndex, field);\r\n }\r\n getDisplayValue(rowIndex: number, field: string): string {\r\n const val = this.readCell(rowIndex, field);\r\n // Phase 2 슬롯 #3: displayFormatter(본문 1줄 — C1 최소 침습 예외). default = 현행(null→'', else String).\r\n const fmt = this._ovk.getStrategy(\r\n 'displayFormatter',\r\n (v: any, _f: string, _row: any): string => (v == null ? '' : String(v)),\r\n );\r\n return fmt(val, field, this._data.getRowByIndex(rowIndex));\r\n }\r\n\r\n writeCell(rowIndex: number, field: string, value: any): void {\r\n const old = this.readCell(rowIndex, field);\r\n const ctx = this._trigMgr.mkCtx('writeCell', [rowIndex, field, value]);\r\n ctx.extra = { oldValue: old, rowIndex, field };\r\n if (!this._trigMgr.exec('before:writeCell', ctx)) return;\r\n this._data.updateCell(rowIndex, field, value);\r\n const row = this._data.getRowByIndex(rowIndex);\r\n const col = this._colLayout.getColumnByField(field);\r\n const ci = this._colLayout.getColumnIndex(field);\r\n const evt: EditEvent<T> = { type: 'editEnd', rowIndex, columnIndex: ci, field, oldValue: old, newValue: value, row: row as T, column: col as any };\r\n this.emit('editEnd', evt);\r\n this._options.onEditEnd?.(evt);\r\n this.emit('dataChange', this._data.getData());\r\n this._options.onDataChange?.(this._data.getData());\r\n this._doRender(...this._visRange());\r\n ctx.result = { rowIndex, field, oldValue: old, newValue: value };\r\n this._trigMgr.exec('after:writeCell', ctx);\r\n }\r\n\r\n getRowAt(rowIndex: number): T { return this._data.getRowByIndex(rowIndex) as T; }\r\n\r\n getChanges(): { added: T[]; edited: T[]; removed: T[] } { return this._data.getChanges(); }\r\n getEditedRows(): T[] { return this._data.getEditedRows(); }\r\n getChangedRows(): T[] { return this._data.getChangedRows(); } // ?섏쐞 ?명솚\r\n getChangedColumns(): Array<{ row: T; fields: string[]; diff: Array<{ field: string; oldValue: any; newValue: any }> }> {\r\n return this._data.getChangedColumns();\r\n }\r\n getAddedRows(): T[] { return this._data.getAddedRows(); }\r\n getRemovedRows(): T[] { return this._data.getRemovedRows(); }\r\n getOriginalRow(rowIndex: number): T | undefined { return this._data.getOriginalRow(rowIndex); }\r\n getRowsWithState(stateField: string): T[] { return this._data.getRowsWithState(stateField); }\r\n undo(): void {}\r\n redo(): void {}\r\n clearHistory(): void {}\r\n getColumnDefs(): ColumnDef<T>[] { return this._colLayout.visibleLeaves; }\r\n getAllColumnDefs(): ColumnDef<T>[] { return this._colLayout.leaves; }\r\n getColumnCount(): number { return this._colLayout.visibleLeaves.length; }\r\n applyColumns(columns: ColumnDef<T>[]): void {\r\n const ctx = this._trigMgr.mkCtx('applyColumns', [columns]);\r\n if (!this._trigMgr.exec('before:applyColumns', ctx)) return;\r\n this._colLayout.setColumns(columns);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader();\r\n this._doRender(...this._visRange());\r\n ctx.result = { columnCount: columns.length };\r\n this._trigMgr.exec('after:applyColumns', ctx);\r\n }\r\n insertColumn(colDef: ColumnDef<T>, position?: Position): void {\r\n this._colLayout.addColumn(colDef, position as any);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n deleteColumn(field: string): void {\r\n this._colLayout.removeColumn(field);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n\r\n private _reorderColumn(fromIdx: number, toIdx: number): void {\r\n const leaves = this._colLayout.visibleLeaves.map(l => l as ColumnDef<T>);\r\n if (fromIdx < 0 || toIdx < 0 || fromIdx >= leaves.length || toIdx >= leaves.length) return;\r\n const reordered = [...this._options.columns];\r\n const [moved] = reordered.splice(fromIdx, 1);\r\n reordered.splice(toIdx, 0, moved);\r\n this._options.columns = reordered;\r\n this.applyColumns(reordered);\r\n this._options.onColumnReorder?.({ fromIndex: fromIdx, toIndex: toIdx, field: moved.field ?? '' });\r\n }\r\n hideColumn(field: string | string[]): void {\r\n this._colLayout.hideColumn(field);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n showColumn(field: string | string[]): void {\r\n this._colLayout.showColumn(field);\r\n this._recalcWidths(this._container.getBoundingClientRect().width);\r\n this._renderHeader(); this._doRender(...this._visRange());\r\n }\r\n getColumnIndex(field: string): number { return this._colLayout.getColumnIndex(field); }\r\n getFieldAt(idx: number): string { return this._colLayout.getColumnByIndex(idx)?.field ?? ''; }\r\n getColValues(field: string, _all = false): any[] { return this._data.getData().map(r => r[field]); }\r\n getUniqueValues(field: string, all = false): any[] { return [...new Set(this.getColValues(field, all))]; }\r\n setColWidths(_widths: number[]): void {}\r\n calcColWidths(_fitToGrid = false): number[] { return []; }\r\n getSelections(): T[] { return this._rowMgr.getSelections(); }\r\n getActiveRow(): number { return this._rowMgr.getActiveRow(); }\r\n activate(index: number): void { this._rowMgr.activate(index); this._doRender(...this._visRange()); }\r\n deselect(): void { this._rowMgr.deselect(); this._doRender(...this._visRange()); }\r\n getChecked(): Array<{ row: T; rowIndex: number }> { return this._rowMgr.getChecked(); }\r\n getAllChecked(): T[] { return this._rowMgr.getAllChecked(); }\r\n checkById(_ids: string[]): void {}\r\n addCheckById(_ids: string[]): void {}\r\n checkByValue(field: string, values: any[]): void {\r\n this._rowMgr.checkByValue(field, values);\r\n this._doRender(...this._visRange());\r\n }\r\n uncheckById(_ids: string[]): void {}\r\n uncheckAll(): void { this._rowMgr.uncheckAll(); this._doRender(...this._visRange()); }\r\n orderBy(fieldOrList: string | SortItem[], dir: 'asc' | 'desc' = 'asc'): void {\r\n const ctx = this._trigMgr.mkCtx('orderBy', [fieldOrList, dir]);\r\n if (!this._trigMgr.exec('before:orderBy', ctx)) return;\r\n this._sfMgr.sort(fieldOrList, dir);\r\n ctx.result = { sortList: this._sfMgr.sortList };\r\n this._trigMgr.exec('after:orderBy', ctx);\r\n }\r\n resetOrder(): void { this._sfMgr.resetSort(); }\r\n setFilter(field: string, filterItems: FilterItem[]): void {\r\n const ctx = this._trigMgr.mkCtx('setFilter', [field, filterItems]);\r\n if (!this._trigMgr.exec('before:setFilter', ctx)) return;\r\n this._sfMgr.setFilter(field, filterItems);\r\n ctx.result = { field, filteredCount: this._data.rowCount };\r\n this._trigMgr.exec('after:setFilter', ctx);\r\n }\r\n resetFilter(field?: string): void { this._sfMgr.resetFilter(field); }\r\n getFilterState(): Record<string, FilterItem[]> { return this._sfMgr.getFilterState(); }\r\n restoreFilter(state: Record<string, FilterItem[]>): void { this._sfMgr.restoreFilter(state); }\r\n private _applyFilters(): void { this._sfMgr.applyFilters(); }\r\n freeze(n: number): void { this._colLayout.setFrozen(n); this._renderHeader(); this._doRender(...this._visRange()); }\r\n /** ?섎룞 蹂묓빀: [{row, col, rowSpan?, colSpan?}] */\r\n mergeCells(cells: MergeCell[]): void {\r\n this._mergeEngine.applyMergeCells(cells);\r\n this._doRender(...this._visRange());\r\n }\r\n /** 자동 병합: 지정 필드 컬럼에서 연속 같은 값을 rowSpan으로 묶는다 */\r\n /** ?먮룞 蹂묓빀: 吏€??field 而щ읆?먯꽌 ?곗냽 媛숈? 媛믪쓣 rowSpan */\r\n autoMerge(fields: string[]): void {\r\n const leaves = this._colLayout.visibleLeaves;\r\n const colIndexes: number[] = [];\r\n const fieldNames: string[] = [];\r\n for (const f of fields) {\r\n const ci = leaves.findIndex(l => l.field === f);\r\n if (ci >= 0) { colIndexes.push(ci); fieldNames.push(f); }\r\n }\r\n this._mergeEngine.applyAutoMerge(this._data.getData(), colIndexes, fieldNames);\r\n this._doRender(...this._visRange());\r\n }\r\n\r\n /** 蹂묓빀 ?댁젣 */\r\n clearMerge(): void {\r\n this._mergeEngine.clear();\r\n this._doRender(...this._visRange());\r\n }\r\n freezeRows(_n: number): void {}\r\n groupBy(fields: string[]): void {\r\n const ctx = this._trigMgr.mkCtx('groupBy', [fields]);\r\n if (!this._trigMgr.exec('before:groupBy', ctx)) return;\r\n this._grpMgr.groupBy(fields);\r\n ctx.result = { fields };\r\n this._trigMgr.exec('after:groupBy', ctx);\r\n }\r\n clearGroup(): void { this._grpMgr.clearGroup(); }\r\n expandAll(): void { this._grpMgr.expandAll(); }\r\n collapseAll(): void { this._grpMgr.collapseAll(); }\r\n enableTree(): void { this._grpMgr.enableTree(); }\r\n disableTree(): void { this._grpMgr.disableTree(); }\r\n expandNodes(ids: any | any[], open = true): void { this._grpMgr.expandNodes(ids, open); }\r\n expandAllNodes(): void { this._grpMgr.expandAllNodes(); }\r\n collapseAllNodes(): void { this._grpMgr.collapseAllNodes(); }\r\n addTreeRow(_item: Partial<T>, _pid: string, _pos?: Position): void {}\r\n exportExcel(options?: ExportOptions | string): void { this._exportMgr.exportExcel(options); }\r\n exportCsv(options?: ExportOptions | string): void { this._exportMgr.exportCsv(options); }\r\n exportJson(options?: ExportOptions | string): void { this._exportMgr.exportJson(options); }\r\n print(options?: { title?: string; excludeFields?: string[] }): void { this._exportMgr.print(options); }\r\n\r\n toArray(keyValue = true): any[] {\r\n const data = this._data.getData();\r\n if (keyValue) return data;\r\n const cols = this._colLayout.visibleLeaves;\r\n return data.map(row => cols.map(c => row[c.field]));\r\n }\r\n jumpToRow(rowIndex: number): void {\r\n this._rowMgr.selectSingle(rowIndex);\r\n this._vs?.scrollToRow(rowIndex);\r\n this._doRender(...this._visRange());\r\n }\r\n jumpToCol(_field: string): void {}\r\n getScrollPos(): { x: number; y: number } {\r\n return { x: this._renderer?.bodyWrapper.scrollLeft ?? 0, y: this._renderer?.bodyWrapper.scrollTop ?? 0 };\r\n }\r\n setFooter(fd: any[]): void {\r\n this._options.footer = fd as any;\r\n this._renderFooterEl();\r\n }\r\n getFooterData(): any[] { return this._footerMgr.computeValues(); }\r\n getFooterValue(field: string): any {\r\n return this._footerMgr.computeValues().find((r: any) => r._field === field)?._value ?? null;\r\n }\r\n private _renderFooterEl(): void { this._footerMgr.render(); }\r\n\r\n resize(w?: number, h?: number): void {\r\n if (w) this._container.style.width = `${w}px`;\r\n if (h) this._container.style.height = `${h}px`;\r\n this._onResize();\r\n }\r\n setTheme(theme: string): void { this._container.setAttribute('data-og-theme', theme); }\r\n setThemeVar(k: string, v: string): void { this._container.style.setProperty(k, v); }\r\n addTrigger(event: TriggerEvent | string, handler: TriggerHandler): this {\r\n this._trigMgr.add(event, handler); return this;\r\n }\r\n removeTrigger(event: TriggerEvent | string, handler: TriggerHandler): this {\r\n this._trigMgr.remove(event, handler); return this;\r\n }\r\n clearTriggers(event?: TriggerEvent | string): this {\r\n this._trigMgr.clear(event); return this;\r\n }\r\n private _mkCtx(operation: string, args: any[]): TriggerContext { return this._trigMgr.mkCtx(operation, args); }\r\n private _trig(event: string, ctx: TriggerContext): boolean { return this._trigMgr.exec(event, ctx); }\r\n\r\n destroy(): void {\r\n if (this._destroyed) return;\r\n this._destroyed = true;\r\n if (this._renderer) crossGridRegistry.unregister(this._renderer.bodyWrapper);\r\n this._trigMgr.clear();\r\n this._ro?.disconnect();\r\n this._vs?.destroy();\r\n this._filterPanel?.destroy();\r\n this._dnd?.destroy();\r\n if (this._cmHandler) this._container.removeEventListener('contextmenu', this._cmHandler);\r\n if (this._cmKbdHandler) this._container.removeEventListener('keydown', this._cmKbdHandler);\r\n this._cmHandler = this._cmKbdHandler = null;\r\n this._ctxMenu?.destroy();\r\n this._wsManager?.destroy();\r\n this._renderer?.destroy();\r\n this._liveRegion?.remove();\r\n this._liveRegion = null;\r\n this._container.innerHTML = '';\r\n this._container.classList.remove('og-container');\r\n this.removeAllListeners();\r\n }\r\n}\r\n\r\n\r\n"],"names":["EventEmitter","event","handler","list","filtered","e","args","remaining","entry","_a","_rowIdSeq","nextRowId","DataLayer","idField","_slot","fallback","resolver","data","row","id","item","r","_","i","position","idx","dispPos","dataIdx","rowIndex","meta","fromDisplayIdx","toDisplayIdx","fromDataIdx","toDataIdx","insertAt","field","value","added","edited","removed","state","orig","changedFields","k","diff","key","d","stateField","sortList","notRemoved","_b","keyed","s","cmpStrategy","a","b","_field","_dir","sa","sb","si","dir","av","bv","cmp","filters","fields","predicate","fi","matchFilter","val","q","f","v","query","fv","VirtualScroll","container","options","range","visibleCount","startIndex","endIndex","offsetY","count","height","targetTop","targetBottom","viewBottom","newTop","spacer","ColumnLayout","columns","frozenCount","leaves","colIndex","walk","cols","depth","col","c","colDef","removeFromList","index","rows","span","childSpan","totalWidth","defaultWidth","visible","flexCols","fixedTotal","sum","flexTotal","FilterPanel","onApply","onClear","anchorEl","currentFilters","title","condRow","condSel","conditions","opt","valueInput","applyBtn","btnRow","clearBtn","rect","containerRect","DEFAULT_PREC","round","precision","factor","OGDecimal","coefficient","scale","str","isNeg","abs","dot","coeff","frac","other","ac","bc","o","result","dp","divisor","half","abs_c","rem","rounded","digits","intPart","fracPart","arr","acc","evaluateFormula","expr","ctx","divisionPrecision","_FormulaParser","src","_ctx","_prec","left","ch","right","start","numStr","applyMask","maskDef","def","char","_maskSSN","_maskPhone","_maskEmail","_maskCredit","_maskAccount","_maskName","_maskIP","_maskPartial","clean","sep","frontEnd","front","backFirst","maskLen","atIdx","local","domain","visLen","first4","last4","midLen","mid","parts","chunk","prefixLen","suffixLen","prefix","suffix","t","maskOctet","octet","_displayFormatterResolver","setDisplayFormatterResolver","resolveFormula","prec","formatNumber","format","currency","custom","num","semi","negFmt","useFmt","m","token","useGrouping","decimals","body","formatDate","y","day","_renderMasked","original","masked","wrap","text","eye","TextRenderer","formulaResult","column","displayText","colRevealed","rowRevealed","SelectRenderer","opts","fn","rawVal","vs","found","NumberRenderer","DateRenderer","CheckboxRenderer","chk","ButtonRenderer","_c","btn","label","BadgeRenderer","colorMap","labelMap","badge","color","LinkRenderer","hrefFn","target","TemplateRenderer","templateFn","ImageRenderer","_d","_e","img","w","h","alt","ProgressRenderer","max","raw","pct","track","fill","lbl","SparklineRenderer","values","W","H","chartType","canvas","min","n","bw","bh","pts","p","SwitchRenderer","on","sw","knob","RatingRenderer","star","RadioRenderer","radio","ImgRenderer","_sanitizeHtml","html","div","el","attr","href","HtmlRenderer","doSanitize","_C128W","_C128_STOP","_c128Bits","out","bar","_encodeC128B","codes","BarcodeRenderer","_barcodeSvg","bits","MW","QZ","TW","rects","x","createRenderer","renderer","GridRenderer","root","cbs","_el","totalHeight","headerHeight","headerRows","widths","_extraW","totalColWidth","table","extraRows","extraHeaderLeft","addExtraCol","tr","extraClass","th","_style","ri","allChk","cell","leafIdx","l","sortInfo","sortable","next","prev","leftOff","headerText","hasExplicitBreak","headerWrap","part","icon","filterIcon","hasFilter","resizer","capturedLeafIdx","_addResizer","fromIdx","selectedRows","checkedRows","groupFlatRows","onGroupToggle","onTreeToggle","extraOpts","mergeEngine","auto","_ew","_totalCW","frag","flatItem","isGroupRow","isTreeRow","g","groupKey","rowEl","top","extraW","stCell","st","labelPlaced","ci","hasSummary","fmt","arrow","treeNode","rowData","rowState","bg","localRowRi","colMap","extraBodyLeft","icons","colors","dnd","handle","numCell","chkCell","isEditable","isFirstCol","mergeInfo","ph","cellEl","rs","cs","mergedHeight","mergedWidth","dc","isFrozenCell","frozenLeftOff","_rawVal","_treeRenderTarget","treeCell","hasMoreChain","guide","conn","toggleWrap","nodeIcon","iconCls","_resolveTreeIcon","rendered","localRi","localCi","pc","rowTop","empty","hasChildren","expanded","tag","className","styles","_downloadText","content","filename","mime","blob","url","onChange","startX","startW","onMove","ev","onUp","RowManager","checked","totalRows","_ids","DateEditor","onCommit","onCancel","normalizeOptions","SelectEditor","optionsFn","resolved","cur","TextEditor","NumberEditor","CheckboxEditor","_onCancel","createEditor","editor","isToggleCol","rendType","CellEditManager","deps","startEvt","cancel","old","evt","FilterSelectPanel","config","onFilter","onReset","gridId","legend","uid","select","parentValue","vk","tk","enabled","all","fk","parentField","sel","Pagination","pageSize","size","page","end","total","sizeWrap","sizeLabel","sizeSel","info","mkBtn","disabled","_pageRange","current","pages","DragGhost","grabX","grabY","clientX","clientY","DropIndicator","cap","side","parent","clamp","lo","hi","RowDragDrop","_bodyEl","_rowHeight","_onDrop","_cross","_getDragCount","fromIndex","hit","tRect","tRelY","tIdx","bodyRect","relY","currentTarget","ghost","crossTarget","MergeEngine","cells","mc","colIndexes","spanStart","prevVal","curVal","DEFAULT_CONTEXT_ITEMS","ContextMenuManager","_anchor","_actions","customItems","items","menu","hr","ic","themeEl","theme","focused","onPositioned","width","vw","vh","btns","WorksheetManager","onSwitch","name","wasActive","oldName","newName","entries","tab","addBtn","input","commit","ExportManager","hex","rgbMatch","fname","sheetName","includeHeader","serialize","_s","fb","_row","utils","writeFile","ws","colWidths","colLayout","styleMode","hdrBgRgb","hdrFgRgb","rowBgRgb","rowAltRgb","rowFgRgb","borderRgb","fontSize","toRgb","fsStr","noStyle","S","isHdr","isEven","_v","addr","isNum","hAlign","wb","hdr","footerText","headerRow","bodyRows","footerHtml","win","wsManager","FooterManager","tok","numFmt","useComma","dpMatch","fixed","decPart","intStr","footerDefs","allData","op","nums","opUC","customOp","cv","cnt","numVal","formatted","valMap","leafCursor","colspan","cellW","targetLeaf","displayVal","KeyboardManager","editMgr","totalCols","nextRi","step","rowMgr","lines","dr","targetRi","targetCi","FindBarManager","closeBtn","_isGroup","buildGroups","summaryDefs","expandedKeys","getRowState","getKey","_groupByFields","parentKey","map","children","summary","summaryFmt","_calcSummary","states","_calcStates","defs","vals","_fmtNum","flattenGroups","groups","child","collectAllKeys","keys","nested","buildTree","parentIdField","expandOnLoad","nodeMap","roots","node","pid","assignDepth","nodes","_countDescendants","assignLineMeta","parentHasMoreChain","isLast","flattenTree","toggleTreeNode","nodeId","collectAllTreeIds","ids","GroupTreeManager","dl","getState","temp","open","ops","SortFilterManager","shiftKey","sortedItem","dirLabel","fieldOrList","filterItems","CellEventHandler","_f","_g","colEditable","grp","cellValue","rowEvt","isSelectCol","cellEvt","eventName","TriggerManager","operation","_cancelled","handlers","completeHandlers","NONE","buildMappingScript","mapping","tgt","buildTransform","sf","sameSchema","openCrossGridMapper","sourceFields","targetFields","resolve","srcSet","tf","overlay","box","head","optionHtml","esc","refreshScript","scriptWrap","scriptHead","copyBtn","pre","currentScript","txt","foot","cancelBtn","okBtn","done","close","onKey","CrossGridRegistry","bodyEl","grid","exclude","crossGridRegistry","OverrideKernel","host","layers","composed","innerOrig","layer","outer","reentrant","self","slot","ROW_ID_FIELD","_OpenGrid","msg","from","to","_origDestroy","toIdx","targetBodyEl","targetIndex","active","colIdx","fakeEvent","sheets","_name","sheet","_n","leaf","measured","headerH","toIndex","targetGrid","sourceIndexes","idxAsc","at","transform","indexes","mode","srcInfos","tgtInfos","mapEvt","newWidth","combined","pos","it","idxArr","idxs","reordered","moved","_all","_widths","_fitToGrid","fieldNames","_item","_pid","_pos","keyValue","fd","_h","OpenGrid"],"mappings":"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"}