@ninebone/table 0.1.39 → 0.1.41
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nine-table.umd.js","sources":["../src/core/protype.js","../src/external/NoPeer.js","../src/core/constants.js","../src/data/ngData.js","../src/data/ngDataManager.js","../src/data/Fields.js","../src/ui/layout/nine-table-sheets.js","../src/ui/layout/nine-table-sheets-footer.js","../src/ui/layout/nine-table-toolbar.js","../src/ui/layout/nine-table-hscrollbar.js","../src/ui/layout/nine-table-vscrollbar.js","../src/data/Grouping.js","../src/ui/layout/core/RowManager.js","../src/ui/layout/core/TableCompiler.js","../src/ui/cell-manager/CellSelection.js","../src/ui/cell-manager/CellNavigation.js","../src/ui/col/ColResizer.js","../src/ui/col/ColMover.js","../src/ui/col/ColFixManager.js","../src/data/Filtering.js","../src/data/Sorting.js","../src/data/SheetView.js","../src/ui/layout/core/PreCompiler.js","../src/ui/layout/nine-table-sheet.js","../src/ui/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/core/nine-table.js","../src/ui/cell/core/BasicCellElement.js","../src/ui/cell/core/CellElement.js","../src/ui/cell/cell-input-text.js","../src/ui/cell/cell-input-number.js","../src/ui/cell/cell-input-color.js","../src/ui/cell/cell-input-date.js","../src/ui/cell/cell-checkbox.js","../src/ui/cell/cell-radio.js","../src/ui/cell/cell-combo-panel.js","../src/ui/cell/cell-combo.js","../src/ui/cell/cell-renderer.js","../src/ui/cell/cell-button.js","../src/ui/cell/cell-row-indicator.js","../src/ui/col/col-expand.js","../src/ui/menu/nine-table-menu.js","../src/ui/menu/nine-table-menu-panel.js"],"sourcesContent":["Array.prototype.nineBinarySearch = function(target) {\n //this.sort((a, b) => { return a > b ? 1 : -1; });\n\n let start = 0;\n let end = this.length - 1;\n let mid;\n\n while (start <= end) {\n mid = parseInt((start + end) / 2);\n\n if (target === this[mid]) {\n return mid;\n } else {\n if (target < this[mid]) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n }\n\n return -1;\n};\n\n// 엘리먼트별 디바운스/취소 상태를 격리하기 위한 WeakMap\nconst elementDebounceState = new WeakMap();\n\nHTMLElement.prototype.addDebounseEventListener = function(\n dblClickEvent,\n dblClickFn,\n pointerEvent,\n pointerFn,\n debounceTime = 500\n) {\n const el = this;\n\n if (!elementDebounceState.has(el)) {\n elementDebounceState.set(el, { timer: null, cancelFn: null });\n }\n const state = elementDebounceState.get(el);\n\n // 1. 포인터(다운) 이벤트: 즉시 실행하지 않고 debounceTime 동안 지연시킴\n el.addEventListener(pointerEvent, (e) => {\n e.actualTarget = e.target;\n\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n // 💡 500ms 동안 대기한 뒤에야 실제 pointerFn이 실행됨\n state.timer = setTimeout(() => {\n state.timer = null;\n state.cancelFn = pointerFn.call(el, e);\n }, debounceTime);\n });\n\n // 2. 더블클릭 이벤트: 대기 시간 내에 들어오면 예약되어 있던 pointerdown 자체를 원천 차단\n el.addEventListener(dblClickEvent, (e) => {\n //trace.log(e);\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null; // 💡 pointerdown 실행 예약이 아예 취소됨!\n }\n\n // 혹시 이미 실행되어 버린 경우의 안전장치 롤백\n if (state.cancelFn) {\n state.cancelFn();\n state.cancelFn = null;\n }\n\n dblClickFn.call(el, e);\n });\n};\n\n\nnine.measureTextSize = (_text, _font = '12px sans-serif') => {\n if (typeof _text === 'number') _text = _text + \"\";\n if (!_text) return { width: null, height: null };\n\n // 🎯 브라우저 DOM 파싱을 이용한 완벽한 HTML 태그 제거 함수\n const stripHtml = (html) => {\n const tmp = document.createElement(\"DIV\");\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || \"\";\n };\n\n // 줄바꿈 처리 전 HTML 정제 또는 줄바꿈 단위별 정제\n _text = _text.replaceAll(\"\\n\", \"<br>\");\n\n // 🎯 공용 숨김 캔버스를 querySelector로 찾거나 없으면 생성\n let canvas = document.body.querySelector('canvas#_nine_measure_canvas_');\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = '_nine_measure_canvas_';\n canvas.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; left: -9999px;';\n document.body.appendChild(canvas);\n }\n\n const context = canvas.getContext('2d');\n context.font = _font;\n\n let w = 0;\n let h = 0;\n\n for (let v of _text.split(\"<br>\")) {\n // 브라우저 파서로 HTML 태그를 완전히 제거한 순수 텍스트 획득\n const cleanText = stripHtml(v);\n const metrics = context.measureText(cleanText);\n\n //trace.log(cleanText);\n\n w = Math.max(w, metrics.width);\n\n const ascent = metrics.fontBoundingBoxAscent || 10;\n const descent = metrics.fontBoundingBoxDescent || 3;\n h += ascent + descent;\n }\n\n return {\n width: w,\n height: h\n };\n};","import { trace as traceOrigin } from '@ninebone/util';\n\n/**\n// 1. 내부 프라이빗 필드 문제를 피하기 위해 래퍼 객체 생성\nexport const trace = {\n init(prefix, color) {\n // 필요하다면 여기서 초기화 로직 수행 가능\n if (traceOrigin.init) {\n try { traceOrigin.init(prefix, color); } catch (e) {}\n }\n },\n log(...args) {\n return traceOrigin.log(...args);\n },\n warn(...args) {\n return traceOrigin.warn(...args);\n },\n error(...args) {\n return traceOrigin.error(...args);\n }\n};\n\n// 2. 모듈 로드 시점에 네임스페이스 초기화 시도\ntry {\n traceOrigin.init(\"nine-table\", \"green\");\n} catch (e) {}\n*/\n\n\nexport class Trace extends traceOrigin.constructor {\n constructor() {\n super();\n this.init(\"nine-table\", \"green\");\n }\n}\n\nexport const trace = new Trace();\n\n\n//trace.init(\"nine-table\", \"green\");","export const NINE_TABLE = {\n META: {\n INDEX: {\n ROWID: 0,\n FILTER: 1, // 멀티뷰 필터 통과 여부 (true/false)\n GROUP: 2,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 'EMPTY',\n NORMAL: 'NORMAL',\n INSERT: 'INSERT',\n UPDATE: 'UPDATE',\n DELETE: 'DELETE'\n },\n EVENT: {\n LOAD: \"load\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\n\r\nexport class ngRow {\r\n\t#parent;\r\n\t#newrow = -1;\r\n\r\n\tconstructor(parent) {\r\n\t\tthis.#parent = parent;\r\n\t}\r\n\r\n\tget at() {\r\n\t\treturn this.#newrow;\r\n\t}\r\n\tset at(v) {\r\n\t\tthis.#newrow = parseInt(v, 10);\r\n\t}\r\n\r\n\tcount = () => this.#parent.rawRecords.length;\r\n}\r\n\r\nexport class ngData {\r\n\t#host;\r\n\t#parent;\r\n\t#nextId = 0;\r\n\t#defaultHeight = [];\r\n\r\n\tstatic META_INDEX = {\r\n\t\tFILTER: 0, // 멀티뷰 필터 통과 여부 (true/false)\r\n\t\t// ── 추후 확장 예시 ──\r\n\t\t// GROUP: 1,\r\n\t\t// SELECT: 2,\r\n\t\t// EXPAND: 3\r\n\t};\r\n\r\n\t// 🎯 행 상태 정의 상수 내재화\r\n\tstatic ROW_STATE = {\r\n\t\tEMPTY: 'EMPTY',\r\n\t\tNORMAL: 'NORMAL',\r\n\t\tINSERT: 'INSERT',\r\n\t\tUPDATE: 'UPDATE',\r\n\t\tDELETE: 'DELETE'\r\n\t};\r\n\r\n\tconstructor(host, parent) {\r\n\t\tthis.#host = host;\r\n\t\tthis.#parent = parent;\r\n\t\tthis.#initialize();\r\n\t}\r\n\r\n\r\n\r\n\t/**\r\n\t * 🎯 [내부 공통] 삭제되지 않은 유효 레코드 목록 반환 (중복 제거 및 캡슐화)\r\n\t */\r\n\t#getValidRecords = () => {\r\n\t\tconst rawRecords = this.#parent.rawRecords || [];\r\n\t\treturn rawRecords.filter(o => !o.__ng?.deleted);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 행 개수 반환 (속성 및 메서드 형태 모두 지원)\r\n\t */\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tcount = () => {\r\n\t\treturn this.length;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [내부 엔진/고성능용] 변환 오버헤드 없이 순수 데이터(v 배열 등) 그대로 반환\r\n\t * - data.getArray() : 유효한 전체 내부 레코드 배열 반환\r\n\t * - data.getArray(at) : 특정 행의 내부 레코드 객체({ v: [...] }) 반환\r\n\t * - data.getArray(at, colnm) : 특정 행의 특정 컬럼 원시 값 반환\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn validRecords; // 변환 없이 배열 그대로 반환 (렌더링 최적화)\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord; // { v: [...], __ng: {...} } 원본 형태 반환\r\n\t};\r\n\r\n\tsetArray = (rowIndex, colIndex, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\r\n\t\tconst oldValue = rowData.v[colIndex];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\t// 변경 전 값 보존 우선 주석처리\r\n\t\t\t//rowData.o[colIndex] = value;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[colIndex] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\r\n\t/**\r\n\t * 🎯 [외부 개발자/비즈니스 로직용] 개발자가 활용하기 편한 JSON 객체 형태로 변환하여 반환\r\n\t * - data.get() : 전체 유효 데이터를 JSON 객체 배열로 변환\r\n\t * - data.get(at) : 특정 행을 JSON 객체로 변환\r\n\t * - data.get(at, colnm) : 특정 컬럼 값 반환\r\n\t */\r\n\tget = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn this.#conv(validRecords);\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#conv(targetRecord);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [저장/서버 전송용] 삭제된 행을 포함한 전체 원본 배열 반환\r\n\t */\r\n\tgetAll = () => {\r\n\t\treturn this.#parent.rawRecords || [];\r\n\t};\r\n\r\n\tgetHostFields = () => {\r\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\r\n\t};\r\n\r\n\t#initialize = () => {\r\n\t\tthis.#defaultHeight = [];\r\n\t\tconst templateElements = this.#host.template || [];\r\n\t\tArray.from(templateElements).forEach(el => {\r\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\r\n\t\t});\r\n\r\n\t\t(this.#parent.rawRecords || []).forEach(v => {\r\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\r\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\r\n\t\t});\r\n\t};\r\n\r\n\tget source() {\r\n\t\treturn this.#conv(this.#parent.rawRecords);\r\n\t}\r\n\tset source(v) {\r\n\t\tthis.set(v);\r\n\t\t//this.clear();\r\n\t\t//this.add(v, false);\r\n\t}\r\n\r\n\t#invalidate = () => {\r\n\t\tconst $sheets = this.#host.shadowRoot.querySelector(\"nine-table-sheets\");\r\n\t\t$sheets?.classList.toggle(\"nodata\", this.length === 0);\r\n\r\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\r\n\t\t\t$el.invalidate();\r\n\t\t});\r\n\r\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\r\n\t};\r\n\r\n\tset = (dataSource) => {\r\n\r\n\t\tconst loadData = () => {\r\n\t\t\tthis.clear();\r\n\t\t\tthis.add(dataSource, false);\r\n\t\t\tthis.#invalidate();\r\n\t\t}\r\n\r\n\t\tif (this.#host.loaded) {\r\n\t\t\tloadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\r\n\t\t\t\tloadData();\r\n\t\t\t}, { once: true });\r\n\t\t}\r\n\t};\r\n\r\n\tget nextId() {\r\n\t\treturn this.#nextId++;\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.#getValidRecords().length;\r\n\t}\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tgetRowCount() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\t#getDefaultMeta = (rowid = 0) => {\r\n\t\treturn {\r\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\r\n\t\t\tdeleted: false,\r\n\t\t\tfiltered: false,\r\n\t\t\theight: this.#defaultHeight.slice(),\r\n\t\t\to: {},\r\n\t\t\tc: {},\r\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\r\n\t\t\t_: [rowid, [], ],\r\n\t\t};\r\n\t};\r\n\r\n\treset = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tclear = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tif (this.#parent.viewRecords?.reset) {\r\n\t\t\tthis.#parent.viewRecords.reset();\r\n\t\t}\r\n\r\n\t\tthis.#nextId = 0;\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\t#json2Array = (jsonArray) => {\r\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\r\n\r\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\r\n\t\tconst arr = [];\r\n\r\n\t\tjsonArray.forEach(json => {\r\n\t\t\tconst o = { v: [] };\r\n\t\t\tfields.forEach(colnm => {\r\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\r\n\t\t\t});\r\n\t\t\tarr.push(o);\r\n\t\t});\r\n\r\n\t\treturn arr;\r\n\t};\r\n\r\n\t#defaultInsert = (arr) => {\r\n\t\tif (!Array.isArray(arr)) arr = [arr];\r\n\t\tarr.forEach(o => {\r\n\t\t\tconst rowid = this.nextId;\r\n\r\n\t\t\to.m = this.#getDefaultMeta(rowid);\r\n\t\t\to.__ng = o.m;\r\n\t\t\to.__ng.rowid = rowid;\r\n\t\t\to.__ng.rowState = ngData.ROW_STATE.INSERT;\r\n\t\t\to.__ng._[0] = rowid;\r\n\t\t});\r\n\t\treturn arr;\r\n\t};\r\n\r\n\tadd = (dataSource, updateState = true) => {\r\n\t\tif (dataSource === undefined) dataSource = {};\r\n\t\tconst arr = this.#json2Array(dataSource);\r\n\r\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(this.#defaultInsert(arr));\r\n\r\n\t\tconst row = this.count() - 1;\r\n\t\tif (!updateState) {\r\n\t\t\tarr.forEach((_, idx) => {\r\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\r\n\t\t\t\tif (target) target.__ng.rowState = ngData.ROW_STATE.EMPTY;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#invalidate();\r\n\t\treturn row;\r\n\t};\r\n\r\n\tdelete = (at) => {\r\n\t\tlet arr = [];\r\n\t\tif (Array.isArray(at)) {\r\n\t\t\tarr = at;\r\n\t\t} else if (typeof at === \"undefined\") {\r\n\t\t\tarr = [this.#parent.host.row.at];\r\n\t\t} else {\r\n\t\t\tarr = [parseInt(at, 10)];\r\n\t\t}\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tarr.sort((a, b) => b - a).forEach(rowidx => {\r\n\t\t\tif (validRecords[rowidx]) {\r\n\t\t\t\tconst targetId = validRecords[rowidx].__ng.rowid;\r\n\t\t\t\tif (validRecords[rowidx].__ng.rowState === ngData.ROW_STATE.INSERT) {\r\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.__ng.rowid !== targetId);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\r\n\t\t\t\t\t\tif (item.__ng.rowid === targetId) {\r\n\t\t\t\t\t\t\titem.__ng.deleted = true;\r\n\t\t\t\t\t\t\titem.__ng.rowState = ngData.ROW_STATE.DELETE;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tsetValue = (rowIndex, colnm, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\trowIndex = parseInt(rowIndex, 10);\r\n\t\tconst fields = this.getHostFields();\r\n\t\tconst COL_IDX = fields.indexOf(colnm);\r\n\t\tif (COL_IDX < 0) return;\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\t\tif (!rowData) return;\r\n\r\n\r\n\r\n\t\tconst oldValue = rowData.v[COL_IDX];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\tif (!rowData.__ng.o.hasOwnProperty(colnm)) rowData.__ng.o[colnm] = oldValue;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[COL_IDX] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\t#conv = (arr) => {\r\n\t\tif (!arr) return arr;\r\n\r\n\t\tconst isSingle = !Array.isArray(arr);\r\n\t\tconst targetArr = isSingle ? [arr] : arr;\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\r\n\t\t\tconst t = {};\r\n\t\t\tfields.forEach((colnm, i) => {\r\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t\t});\r\n\t\t\tt.__ng = o.__ng;\r\n\t\t\treturn t;\r\n\t\t});\r\n\r\n\t\treturn isSingle ? result[0] : result;\r\n\t};\r\n}\r\n","import { ngRow, ngData } from \"./ngData.js\";\r\n\r\nexport class ngDataManager {\r\n\t#host;\r\n\r\n\tconstructor(host) {\r\n\t\tthis.#host = host;\r\n\r\n\t\tthis.row = new ngRow(this);\r\n\t\tthis.data = new ngData(this.#host, this);\r\n\r\n\t\tthis.rawRecords = [];\r\n\t\tthis.viewRecords = [];\r\n\t\tthis.delRecords = [];\r\n\t\tthis.pageCnt = 25;\r\n\r\n\t\tthis.viewRecords.reset = () => {\r\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\r\n\t\t};\r\n\r\n\t\tthis.setDataSource = (ds) => {\r\n\t\t\tif (this.data) this.data.reset();\r\n\r\n\t\t\tthis.rawRecords = [];\r\n\t\t\tthis.viewRecords = [];\r\n\t\t\tthis.delRecords = [];\r\n\r\n\t\t\tthis.data.set(ds || []);\r\n\t\t};\r\n\r\n\t\tthis.getRowState = (nRow) => {\r\n\t\t\tconst rowIdx = parseInt(nRow, 10);\r\n\t\t\tif (rowIdx >= this.data.count()) return;\r\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\r\n\t\t};\r\n\r\n\t\tthis.getRowPosition = () => this.row.at;\r\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\r\n\r\n\t\tthis.scrollTo_V1 = (nRow) => {\r\n\t\t\tif (nRow < 0) nRow = 0;\r\n\t\t\tif (nRow >= this.rawRecords.length) nRow = this.rawRecords.length - 1;\r\n\r\n\t\t\tthis.viewRecords.rawIndex = nRow;\r\n\t\t\tif (this.viewRecords.reset) this.viewRecords.reset();\r\n\r\n\t\t\treturn (nRow <= 0 || nRow >= this.rawRecords.length - 1) ? false : true;\r\n\t\t};\r\n\r\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\r\n\r\n\t\tthis.setColumn = (rowidx, colnm, v) => {\r\n\t\t\trowidx = parseInt(rowidx, 10);\r\n\t\t\tthis.data.setValue(rowidx, colnm, v);\r\n\t\t};\r\n\r\n\t\t// 초기 빈 데이터 바인딩\r\n\t\tthis.setDataSource([]);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\n\nexport class fields {\n\t#host;\n\t#fields = []; // 🎯 이제 { name: string, type: string } 객체들의 배열로 관리합니다.\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\t\tthis.#init();\n\t};\n\n\t// 🎯 기존에 필드 이름만 쓰던 곳들과의 호환을 위해 이름 배열만 리턴하는 메서드 유지\n\tget() {\n\t\treturn this.#fields.map(f => f.name);\n\t};\n\n\t// 🎯 내부 객체 통째로 얻기\n\tgetFields() {\n\t\treturn this.#fields;\n\t}\n\n\t// 🎯 특정 필드의 데이터 타입 조회\n\tgetType(fieldName) {\n\t\tconst found = this.#fields.find(f => f.name === fieldName);\n\t\treturn found ? found.type : 'string';\n\t}\n\n\tadd = (arr, type = 'string') => {\n\t\tarr.forEach(fName => {\n\t\t\tif (!this.#fields.some(f => f.name === fName)) {\n\t\t\t\tthis.#fields.push({ name: fName, type: type });\n\t\t\t}\n\t\t});\n\t\tthis.#adjust();\n\t};\n\n\tindexOf(v) {\n\t\treturn this.#fields.findIndex(f => f.name === v);\n\t};\n\n\tincludes(v) {\n\t\treturn this.#fields.some(f => f.name === v);\n\t};\n\n\t#adjust = () => {\n\t\t// 🎯 이름 기준으로 중복 제거 (Map을 활용하여 마지막에 들어온 타입 유지)\n\t\tconst map = new Map();\n\t\tthis.#fields.forEach(f => {\n\t\t\tmap.set(f.name, f.type);\n\t\t});\n\n\t\tthis.#fields = Array.from(map, ([name, type]) => ({ name, type }));\n\n\t\t// 🎯 빈 문자열이나 __ng 필터링\n\t\tthis.#fields = this.#fields.filter(f => f.name !== \"\" && f.name !== \"__ng\");\n\n\t\t// 🎯 긴 이름순 정렬\n\t\tthis.#fields.sort((a, b) => { return (a.name.length < b.name.length) ? 1 : -1; });\n\t};\n\n\t#init = () => {\n\t\tthis.#fields = [];\n\n\t\ttrace.log(this.#host.querySelectorAll(\"table\"));\n\n\t\tconst rawTables = Array.from(this.#host.querySelectorAll(\"table\"));\n\n\t\tif (!rawTables || rawTables.length === 0) return;\n\n\t\tfor (const tbl of rawTables) {\n\t\t\ttrace.log(tbl);\n\n\t\t\t// 1. [data-bind] 속성 탐색 및 타입 수집\n\t\t\ttbl.querySelectorAll('[data-bind]').forEach((el) => {\n\t\t\t\tconst fieldName = el.dataset.bind;\n\t\t\t\tconst fieldType = el.getAttribute(\"data-type\") || 'string';\n\n\t\t\t\tif (fieldName) {\n\t\t\t\t\tthis.#fields.push({ name: fieldName, type: fieldType });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// 2. 표현식 속성들 탐색 (순수 자바스크립트로 변환)\n\t\t\tconst exprAttrs = [\n\t\t\t\t\"data-expr\", \"background-color\", \"color\", \"tooltip\",\n\t\t\t\t\"visible\", \"readonly\", \"enable-button\", \"enable-check\",\n\t\t\t\t\"class-expr\", \"icon-color\", \"icon-src\"\n\t\t\t];\n\n\t\t\texprAttrs.forEach(attr => {\n\t\t\t\t// 💡 jQuery의 $([attr], tbl).each(...)를 순수 querySelectorAll로 대체\n\t\t\t\ttbl.querySelectorAll(`[${attr}]`).forEach((el) => {\n\t\t\t\t\tlet expr = el.getAttribute(attr);\n\t\t\t\t\tif (!expr) return;\n\n\t\t\t\t\tif (expr.indexOf(\"data.\") < 0) {\n\t\t\t\t\t\tconst lastIndex = expr.search(/[(]/g);\n\n\t\t\t\t\t\tif (lastIndex > 0) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\texpr = String(window[expr.substring(0, lastIndex).trim()]);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texpr = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\texpr.split(\"data.\").forEach(v => {\n\t\t\t\t\t\tif (v.trim() != \"\") {\n\t\t\t\t\t\t\tconst lastIndex = v.search(/[^_A-Za-z0-9]/g);\n\t\t\t\t\t\t\tlet targetField = '';\n\n\t\t\t\t\t\t\tif (lastIndex >= 0) {\n\t\t\t\t\t\t\t\ttargetField = v.substring(0, lastIndex);\n\t\t\t\t\t\t\t} else if (expr.startsWith(\"data.\")) {\n\t\t\t\t\t\t\t\ttargetField = v.replace(\"data.\", \"\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (targetField) {\n\t\t\t\t\t\t\t\tthis.#fields.push({ name: targetField, type: 'string' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tthis.#adjust();\n\t};\n};","export class NineTableSheets extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n #init = () => {\n\n };\n\n}\n\nif (!customElements.get('nine-table-sheets')) {\n customElements.define('nine-table-sheets', NineTableSheets);\n}","export class NineTableSheetsFooter extends HTMLElement {\n #host;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n refresh = () => {\n this.querySelector(\"#row-count\").innerHTML = this.#host.data.count().toLocaleString();\n };\n\n #init = () => {\n this.#host = this.getRootNode().host;\n\n this.#render();\n\n this.querySelector('.nine-tab-bar')?.addEventListener('click', (e) => {\n const isMultiSelect = e.ctrlKey || e.metaKey || e.shiftKey;\n const tabItem = e.target.closest('nt-sheets-tab-item');\n\n if (!tabItem) return;\n\n const index = parseInt(tabItem.dataset.index, 10);\n this.#switchSheet(index, isMultiSelect);\n });\n\n this.#switchSheet(0, false);\n };\n\n #switchSheet = (index, isMultiSelect = false) => {\n\n const updateSplitters = () => {\n const sheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet'));\n const splitters = Array.from(this.#host.shadowRoot.querySelectorAll('nine-splitter'));\n\n // 1. 모든 스플리터 일단 숨김 처리\n splitters.forEach(s => s.style.setProperty('display', 'none'));\n\n // 2. 현재 active 상태인 시트들을 인덱스 오름차순으로 정렬\n const activeSheets = sheets\n .map((sheet, idx) => ({ sheet, idx }))\n .filter(({ sheet }) => sheet.classList.contains('active'));\n\n if (activeSheets.length < 2) return;\n\n // 3. 인접한 활성화 시트 쌍 사이에 정확히 하나의 스플리터만 노출\n for (let i = 0; i < activeSheets.length - 1; i++) {\n const currentIdx = activeSheets[i].idx;\n\n const targetSplitter = this.#host.shadowRoot.querySelector(`nine-splitter[data-split-index=\"${currentIdx}\"]`);\n if (targetSplitter) {\n targetSplitter.style.setProperty('display', '');\n }\n }\n };\n\n const tabBar = this.querySelector('.nine-tab-bar');\n const body = this.#host.shadowRoot.querySelector('nine-table-sheets-body');\n const tabItems = tabBar.querySelectorAll('nt-sheets-tab-item');\n const sheetElements = body.querySelectorAll('nine-table-sheet');\n\n if (!tabItems[index]) return;\n\n if (!isMultiSelect) {\n tabItems.forEach((tab, idx) => {\n tab.setActive(idx === index);\n });\n\n sheetElements.forEach((sheet, idx) => {\n const isActive = idx === index;\n sheet.classList.toggle('active', isActive);\n sheet.style.flex = isActive ? '1 1 100%' : '';\n });\n } else {\n const clickedTab = tabItems[index];\n const activeTabs = tabBar.querySelectorAll('nt-sheets-tab-item.active');\n\n if (clickedTab.classList.contains('active') && activeTabs.length <= 1) {\n return;\n }\n\n clickedTab.classList.toggle('active');\n const targetSheet = body.querySelector(`nine-table-sheet[data-index=\"${index}\"]`);\n if (targetSheet) {\n targetSheet.classList.toggle('active');\n if (!targetSheet.classList.contains('active')) {\n targetSheet.style.flex = '';\n }\n }\n }\n\n const activeSheets = body.querySelectorAll('nine-table-sheet.active');\n\n activeSheets?.forEach(sheet => {\n sheet.style.flex = (activeSheets.length > 1) ? '1 1 0%' : '1 1 100%';\n\n if (typeof sheet.refreshLayout === 'function') {\n sheet.refreshLayout();\n } else {\n sheet.invalidate?.();\n }\n });\n\n updateSplitters();\n };\n\n #render() {\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE'));\n\n const tabsHtml = rawTables.map((table, idx) => {\n const className = idx === 0 ? 'active' : '';\n const tabName = table.getAttribute('caption') || `Sheet ${idx + 1}`;\n\n return `<nt-sheets-tab-item class=\"${className}\" data-index=\"${idx}\">${tabName}</nt-sheets-tab-item>`;\n }).join('');\n\n this.innerHTML = `\n <div class=\"nine-tab-bar\">${tabsHtml}</div>\n <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n `;\n };\n}\n\nexport class SheetTabItem extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n }\n\n setActive(isActive) {\n this.classList.toggle('active', isActive);\n }\n}\n\nif (!customElements.get('nt-sheets-tab-item')) {\n customElements.define('nt-sheets-tab-item', SheetTabItem);\n}\n\nif (!customElements.get('nine-table-sheets-footer')) {\n customElements.define('nine-table-sheets-footer', NineTableSheetsFooter);\n}","import { trace } from \"@nopeer\";\n\nexport class Toolbar extends HTMLElement {\n #host;\n #customContainer;\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#render();\n this.#bindEvents();\n }\n\n #render() {\n this.innerHTML = `\n <div class=\"ng-toolbar-left\">\n <button type=\"button\" class=\"ng-toolbar-menu-btn\" title=\"Menu\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#374151\" stroke-width=\"2\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n </button>\n <span class=\"ng-toolbar-title\"></span>\n </div>\n\n <div class=\"ng-toolbar-custom\" id=\"custom-container\"></div>\n `;\n\n this.#customContainer = this.querySelector('#custom-container');\n this.#syncStateFromHost();\n }\n\n #syncStateFromHost() {\n const isSimple = this.#host.getAttribute('theme') === 'simple' || this.#host.classList.contains('simple');\n const showToolbar = this.#host.getAttribute('show-toolbar') !== 'false';\n const showMenu = this.#host.getAttribute('show-menu') !== 'false';\n const caption = this.#host.getAttribute('caption') || '';\n\n if (isSimple || !showToolbar) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n\n this.setAttribute('show-menu', showMenu ? 'true' : 'false');\n this.updateCaption(caption);\n }\n\n #bindEvents() {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) {\n titleEl.addEventListener('dblclick', () => {\n const link = '<font color=\"green\">https://www.ninegrid.net</font>';\n const currentCaption = this.#host.getAttribute('caption') || '';\n titleEl.innerHTML = titleEl.innerHTML === link ? currentCaption : link;\n });\n }\n\n const menuBtn = this.querySelector('.ng-toolbar-menu-btn');\n if (menuBtn) {\n menuBtn.addEventListener('click', () => {\n this.#host.dispatchEvent(new CustomEvent('toolbar-menu-click', {\n bubbles: true,\n composed: true,\n detail: { targetTable: this.#host }\n }));\n });\n }\n }\n\n addCustomElement(element) {\n if (this.#customContainer) {\n this.#customContainer.append(element);\n }\n }\n\n updateCaption(text) {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) titleEl.textContent = text;\n }\n}\n\nif (!customElements.get('nine-table-toolbar')) {\n customElements.define('nine-table-toolbar', Toolbar);\n}","// ui/nine-table-hscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableHScrollBar extends HTMLElement {\n #owner;\n #dragging = false;\n #elements;\n #interval1;\n #interval2;\n #resizeObserver;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#owner = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n if (!this.#owner) return;\n\n this.innerHTML = `\n <style>\n nine-table-hscrollbar {\n display: flex;\n flex-direction: row;\n width: 100%;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-hscrollbar button {\n width: 16px;\n height: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-hscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-hscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-hscrollbar .ng-scroll-left .ng-scroll-icon { transform: rotate(-135deg); }\n nine-table-hscrollbar .ng-scroll-right .ng-scroll-icon { transform: rotate(45deg); }\n nine-table-hscrollbar .ng-scroll-track {\n flex: 1;\n height: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-hscrollbar .ng-scroll-thumb {\n position: absolute;\n top: 2px;\n bottom: 2px;\n left: 0px;\n width: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-hscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-left' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-right' disabled><div class='ng-scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container : body,\n track : this.querySelector(\".ng-scroll-track\"),\n thumb : this.querySelector(\".ng-scroll-thumb\"),\n left : this.querySelector(\".ng-scroll-left\"),\n right : this.querySelector(\".ng-scroll-right\"),\n };\n\n this.#init();\n this.#observeResize();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n disconnectedCallback() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n }\n\n #observeResize = () => {\n if (!this.#owner) return;\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) return;\n\n this.#resizeObserver = new ResizeObserver(() => {\n this.refresh();\n });\n this.#resizeObserver.observe(body);\n };\n\n refresh = () => {\n\n if (!this.#owner || !this.#elements || this.#dragging) return;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return;\n\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n\n //trace.log(bodyWidth, tableWidth, bodyWidth);\n\n // 🎯 [순수 클래스 연동] 인라인 스타일 조작 없이 오직 클래스 토글만 수행\n const needsHScroll = (bodyWidth !== 0 && tableWidth > bodyWidth);\n this.#owner.classList.toggle('hscroll-visible', needsHScroll);\n\n if (!needsHScroll) {\n return;\n }\n\n const trackWidth = track.clientWidth;\n if (trackWidth <= 0) return;\n\n const thumbWidth = Math.max(Math.min(trackWidth * (bodyWidth / tableWidth), trackWidth), 20);\n thumb.style.width = `${thumbWidth}px`;\n\n const currentLeft = body.scrollLeft;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n let l = 0;\n if (maxScrollLeft > 0) {\n l = parseInt((currentLeft / maxScrollLeft) * (trackWidth - thumbWidth), 10);\n }\n if (l < 0) l = 0;\n\n const maxThumbLeft = trackWidth - thumbWidth;\n if (l > maxThumbLeft) l = maxThumbLeft;\n\n thumb.style.left = `${l}px`;\n\n this.#elements.left.disabled = (l === 0);\n this.#elements.right.disabled = (l >= maxThumbLeft - 1);\n };\n\n #thumbMoveTo = (x) => {\n if (!this.#elements) return false;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return false;\n\n const trackBound = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n\n let targetX = x;\n if (targetX < 0) targetX = 0;\n const maxThumbLeft = trackBound.width - thumbWidth;\n if (targetX > maxThumbLeft) targetX = maxThumbLeft;\n targetX = parseInt(targetX, 10);\n\n this.#elements.thumb.style.left = `${targetX}px`;\n\n this.#elements.left.disabled = (targetX === 0);\n this.#elements.right.disabled = (targetX >= maxThumbLeft - 1);\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n if (maxThumbLeft > 0 && maxScrollLeft > 0) {\n const newScrollLeft = (targetX / maxThumbLeft) * maxScrollLeft;\n body.scrollLeft = newScrollLeft;\n\n const headerBody = this.#owner.querySelector(\".ng-sheet-header .ng-container-body\");\n const footerBody = this.#owner.querySelector(\".ng-sheet-footer .ng-container-body\");\n if (headerBody) headerBody.scrollLeft = newScrollLeft;\n if (footerBody) footerBody.scrollLeft = newScrollLeft;\n }\n\n return (targetX > 0 && targetX < maxThumbLeft - 1);\n };\n\n #init = () => {\n const delayScroll = (pos) => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n\n const thumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n this.#thumbMoveTo(thumbLeft + pos);\n\n this.#interval1 = setInterval(() => {\n clearInterval(this.#interval1);\n\n this.#interval2 = setInterval(() => {\n const currentThumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n if (!this.#thumbMoveTo(currentThumbLeft + pos)) {\n clearInterval(this.#interval2);\n }\n }, 50);\n }, 500);\n };\n\n const clearTimer = () => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n };\n\n ['mouseup', 'mouseleave', 'touchend'].forEach(evt => {\n this.#elements.left.addEventListener(evt, clearTimer);\n this.#elements.right.addEventListener(evt, clearTimer);\n this.#elements.track.addEventListener(evt, clearTimer);\n });\n\n this.#elements.left.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(-20); });\n this.#elements.right.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(20); });\n this.#elements.left.addEventListener(\"touchstart\", () => delayScroll(-20));\n this.#elements.right.addEventListener(\"touchstart\", () => delayScroll(20));\n\n this.#elements.track.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.preventDefault();\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n this.#thumbMoveTo(e.clientX - trackRect.left - (thumbWidth / 2));\n });\n\n this.#elements.thumb.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n this.shiftX = e.clientX - this.#elements.thumb.getBoundingClientRect().left;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n this.#thumbMoveTo(moveEvent.clientX - trackRect.left - this.shiftX);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n clearTimer();\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n };\n}\n\nif (!customElements.get('nine-table-hscrollbar')) {\n customElements.define(\"nine-table-hscrollbar\", NineTableHScrollBar);\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableVScrollBar extends HTMLElement {\n #host;\n #sheet;\n #dragging = false;\n #elements;\n #startY = 0;\n #startScrollTop = 0;\n #startThumbTop = 0;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#sheet = this.closest(\"nine-table-sheet\");\n\n this.innerHTML = `\n <style>\n nine-table-vscrollbar {\n display: flex;\n flex-direction: column;\n width: 16px;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-vscrollbar button {\n height: 16px;\n width: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-vscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-vscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-vscrollbar .ng-scroll-top .ng-scroll-icon { transform: rotate(-45deg); margin-top: 2px; }\n nine-table-vscrollbar .ng-scroll-bottom .ng-scroll-icon { transform: rotate(135deg); margin-bottom: 2px; }\n \n nine-table-vscrollbar .ng-scroll-track {\n flex: 1;\n width: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-vscrollbar .ng-scroll-thumb {\n position: absolute;\n left: 2px;\n right: 2px;\n top: 0px;\n height: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-vscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-top' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-bottom' disabled><div class='ng-scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#sheet.querySelector(\".ng-sheet-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container: body,\n track: this.querySelector(\".ng-scroll-track\"),\n thumb: this.querySelector(\".ng-scroll-thumb\"),\n top: this.querySelector(\".ng-scroll-top\"),\n bottom: this.querySelector(\".ng-scroll-bottom\"),\n };\n\n this.#init();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n #getScaleInfo = () => {\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords ? viewRecords.length : 0;\n\n // 🎯 [핵심] 그룹핑이든 일반이든 스크롤홀더(scrollHolder)가 가진 실제 가상 총 높이를 최우선으로 반영\n const scrollHolder = this.#sheet.elements?.scrollHolder;\n let rawContentHeight = scrollHolder ? parseFloat(scrollHolder.style.height) || 0 : 0;\n\n if (!rawContentHeight || rawContentHeight <= 0) {\n const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n if (isGrouped && this.#sheet.rowManager) {\n // RowManager가 관리하는 누적 높이 활용 또는 fallback\n rawContentHeight = (body.scrollHeight > body.clientHeight) ? body.scrollHeight : (totalCount * 30);\n } else {\n const rowHeight = this.#sheet.getRowHeight() || 1;\n rawContentHeight = totalCount * rowHeight;\n }\n }\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawContentHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let contentHeight = rawContentHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawContentHeight;\n contentHeight = MAX_BROWSER_HEIGHT;\n }\n\n return { rawContentHeight, contentHeight, scaleFactor, useScaling, totalCount };\n };\n\n #getViewHeight = () => {\n const body = this.#elements.container;\n if (!body) return 0;\n\n const thead = this.#sheet.elements?.body?.thead?.offsetHeight || 0;\n const tfoot = this.#sheet.elements?.body?.tfoot?.offsetHeight || 0;\n const tbodyHead = this.#sheet.elements?.body?.tbody?.head?.offsetHeight || 0;\n const fixedHeight = thead + tfoot + tbodyHead;\n\n return body.clientHeight - fixedHeight;\n };\n\n refresh = () => {\n trace.log(\"=================\", \"vscrollbar.refresh\");\n // 💡 드래그 중에는 refresh에 의한 썸 위치 덮어쓰기 차단\n if (this.#dragging) return;\n\n if (!this.#sheet || !this.#sheet.elements || !this.#elements) return;\n\n const body = this.#elements.container;\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n /**\n * const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n * (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n * this.#sheet.elements.body.tbody.head.offsetHeight;\n *\n * const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n * // 1. 전체 실제 데이터의 높이 계산\n * const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + rowHeight + fixedHeight - viewHeight, 0);\n * @type {number|*}\n */\n\n const bodyHeight = this.#getViewHeight();\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n\n const needsVScroll = (rawContentHeight > bodyHeight && rawContentHeight > 0 && bodyHeight > 0);\n this.#sheet.classList.toggle('vscroll-visible', needsVScroll);\n\n if (!needsVScroll) {\n return;\n }\n\n const trackHeight = track.clientHeight;\n if (trackHeight <= 0) return;\n\n const thumbHeight = Math.max(Math.min(trackHeight * (bodyHeight / contentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n //const maxScrollTop = Math.max(contentHeight - bodyHeight, 1);\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\n\n const maxThumbTop = trackHeight - thumbHeight;\n if (thumbTop < 0) thumbTop = 0;\n if (thumbTop > maxThumbTop) thumbTop = maxThumbTop;\n\n thumb.style.top = `${thumbTop}px`;\n\n /**\n // 🎯 [디버깅 로그] 스크롤바가 리프레시될 때 현재 상태 로깅\n trace.log(\"🔍 [VScroll Refresh]\", {\n isGrouped: this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false,\n totalCount,\n bodyScrollTop: currentScrollTop,\n maxScrollTop,\n thumbTop,\n maxThumbTop\n }); */\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #init = () => {\n trace.log(\"nine-table-vscrollbar.#init\");\n\n const body = this.#elements.container;\n\n this.#elements.thumb.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n\n this.#startY = e.clientY;\n this.#startThumbTop = parseFloat(this.#elements.thumb.style.top) || 0;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const trackHeight = trackRect.height;\n const thumbHeight = this.#elements.thumb.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\n\n //this.#elements.container.scrollTop = 0;\n\n const deltaY = moveEvent.clientY - this.#startY;\n let targetThumbTop = this.#startThumbTop + deltaY;\n\n if (targetThumbTop < 0) targetThumbTop = 0;\n if (targetThumbTop > maxThumbTop) targetThumbTop = maxThumbTop;\n\n // 썸 위치 즉시 고정\n this.#elements.thumb.style.top = `${targetThumbTop}px`;\n\n const ratio = targetThumbTop / maxThumbTop;\n\n const rowHeight =this.#sheet.getRowHeight();\n const viewHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0) -\n (this.#sheet.elements.body.thead?.offsetHeight || 0) -\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) -\n (this.#sheet.elements.body.tbody.head.offsetHeight || 0);\n\n const visibleRowCount = Math.floor(viewHeight / rowHeight);\n\n const { totalCount } = this.#getScaleInfo();\n //const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n const targetRow = Math.floor(ratio * (totalCount - visibleRowCount + 1));\n // 1000010 - 6\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n const currentScrollTop = this.#elements.container.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 0);\n\n //trace.log(\"*****************\", visibleRowCount, ratio, totalCount, targetRow);\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n //this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n\n this.#elements.track.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0 || e.target === this.#elements.thumb) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbHeight = this.#elements.thumb.clientHeight;\n const trackHeight = this.#elements.track.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n if (maxThumbTop > 0) {\n const clickY = e.clientY - trackRect.top - (thumbHeight / 2);\n const ratio = Math.max(0, Math.min(1, clickY / maxThumbTop));\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n\n trace.log(\"🎯 [VScroll Track Click]\", { ratio, clickY, totalCount, targetRow });\n\n if (targetRow >= 0 && this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n }\n this.refresh();\n });\n\n this.#elements.top.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = Math.max(0, currentTopRow - 1);\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n\n this.#elements.bottom.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = currentTopRow + 1;\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n };\n}\n\nif (!customElements.get('nine-table-vscrollbar')) {\n customElements.define(\"nine-table-vscrollbar\", NineTableVScrollBar);\n}","import { trace } from \"@nopeer\";\r\n\r\n// 💡 배열 인덱스 상수 정의\r\nexport const GROUP_IDX = {\r\n\tID: 0,\r\n\tDEPTH: 1,\r\n\tNAME: 2,\r\n\tCHILDREN: 3,\r\n};\r\n\r\nexport class GroupingManager {\r\n\t#sheet;\r\n\t#host;\r\n\t#groupColumns = [];\r\n\t#groupMap = new Map(); // 그룹별 자식 ID 매핑 관리용\r\n\t#isApplying = false;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t}\r\n\r\n\tget columns() {\r\n\t\treturn this.#groupColumns;\r\n\t}\r\n\r\n\tget groupMap() {\r\n\t\treturn this.#groupMap;\r\n\t}\r\n\r\n\tinitialize = () => {\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\t};\r\n\r\n\tapply() {\r\n\r\n\t\ttrace.log(\"==================\", \"Grouping.Apply\");\r\n\r\n\t\tif (this.#isApplying) return;\r\n\t\tthis.#isApplying = true;\r\n\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\r\n\t\t// 💡 데이터 캐시와 렌더링 아이템은 이제 SheetView 단일 파이프라인에서 관리하므로\r\n\t\t// 그룹핑 설정이 바뀌면 SheetView.refresh()를 호출해 전체 흐름을 일괄 재계산합니다.\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh(); // 🎯 SheetView에서 필터/정렬/그룹핑 일괄 처리\r\n\t}\r\n\r\n\tclear() {\r\n\t\tthis.#groupColumns = [];\r\n\t\tthis.#groupMap.clear();\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\t// SheetView가 그룹핑 연산 후 groupMap을 공유할 수 있도록 설정 메서드 제공\r\n\tsetGroupMap(map) {\r\n\t\tthis.#groupMap = map;\r\n\t}\r\n\r\n\tgetChildrenRowIds(groupId) {\r\n\t\treturn this.#groupMap.get(groupId) || [];\r\n\t}\r\n\r\n\tgetChildrenRecords(groupId) {\r\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\r\n\t\tconst dataManager = this.#host.data;\r\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\r\n\t}\r\n}\r\n\r\nexport class Grouping {\r\n\r\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\r\n\t\tif (!groupColumns || groupColumns.length === 0) {\r\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\r\n\t\t}\r\n\r\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\r\n\t\tconst groupMap = new Map();\r\n\r\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\r\n\t\tconst flatResult = [];\r\n\t\tconst renderItems = [];\r\n\r\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\r\n\r\n\t\treturn { headers: flatResult, renderItems, groupMap };\r\n\t}\r\n\r\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\r\n\t\tlet counter = 0;\r\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // 💡 연산자 수정 반영\r\n\r\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\r\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\r\n\r\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\r\n\t\t\tgroupMap.set(groupId, rowIds);\r\n\r\n\t\t\tconst groupRecord = [];\r\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\r\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\r\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\r\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\r\n\r\n\t\t\tgroupRecord.__isGroupHeader = true;\r\n\t\t\tgroupRecord.__groupId = groupId;\r\n\r\n\t\t\tresultArr.push(groupRecord);\r\n\r\n\t\t\trenderItems.push({\r\n\t\t\t\ttype: 'group',\r\n\t\t\t\trecord: groupRecord,\r\n\t\t\t\tgroupId: groupId\r\n\t\t\t});\r\n\r\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\r\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\r\n\t\t\t} else {\r\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\r\n\t\t\t\tleafRecords.forEach(record => {\r\n\t\t\t\t\trecord.__isGroupHeader = false;\r\n\t\t\t\t\trecord.__groupId = groupId;\r\n\t\t\t\t\tresultArr.push(record);\r\n\r\n\t\t\t\t\trenderItems.push({\r\n\t\t\t\t\t\ttype: 'data',\r\n\t\t\t\t\t\trecord: record,\r\n\t\t\t\t\t\tgroupId: groupId\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic #buildNestedMap(records, groupColumns, fields) {\r\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\r\n\t\tconst remainingCols = groupColumns.slice(1);\r\n\t\tconst map = new Map();\r\n\r\n\t\trecords.forEach(record => {\r\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\r\n\t\t\tif (!map.has(key)) map.set(key, []);\r\n\t\t\tmap.get(key).push(record);\r\n\t\t});\r\n\r\n\t\tif (remainingCols.length > 0) {\r\n\t\t\tconst result = new Map();\r\n\t\t\tfor (let [key, subRecords] of map.entries()) {\r\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n\tstatic #collectLeafRowIds(subMapOrRecords) {\r\n\t\tlet rowIds = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\r\n\t\t}\r\n\t\treturn rowIds;\r\n\t}\r\n\r\n\tstatic #collectLeafRecords(subMapOrRecords) {\r\n\t\tlet records = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trecords = records.concat(subMapOrRecords);\r\n\t\t}\r\n\t\treturn records;\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\n\nexport class RowManager {\n #BUFFER_ROW_COUNT = 3;\n\n #host;\n #sheet;\n #element;\n\n #containerTemplates = new Map();\n\n #templateRowHeights = []; // 💡 [추가] 템플릿 행별 개별 높이 보관 ([그룹1, 그룹2, 데이터])\n #cachedTemplateHeight = null;\n\n #resizeObserver = null;\n #sheetHeight = 0;\n #cachedRowCount;\n\n #isProgrammaticScroll = false;\n #isGrouped = false;\n\n constructor(sheet) {\n this.#host = sheet.getRootNode().host;\n this.#sheet = sheet;\n\n this.#initResizeObserver();\n }\n\n // ==========================================\n // 🎯 Public APIs & Getters\n // ==========================================\n\n getRowHeight() {\n return this.#templateRowHeights.reduce((sum, h) => sum + h, 0);//this.#cachedTemplateHeight;\n }\n\n\n refresh = (force = false) => {\n //trace.log(\"rowManager.refresh\", { force });\n\n //this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[group='true']\") ? true : false;\n\n if (!this.#sheet.classList.contains('active')) return;\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n const wasInvalidHeight = !this.#cachedTemplateHeight || this.#cachedTemplateHeight <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#cachedTemplateHeight && this.#cachedTemplateHeight > 0) {\n this.#renderAllContainers();\n }\n }\n\n\n //this.#updateFooterSpacing();\n\n this.#handleScroll(bodyViewport.scrollTop, force);\n\n this.#sheet.querySelector('nine-table-vscrollbar')?.refresh();\n };\n\n #handleScroll = (scrollTop, force = false) => {\n\n //this.#sheet.querySelector('.ng-sheet-body').scrollTop = 0;\n\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\n\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) return;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n if (totalCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n // 🎯 [핵심] 브라우저 DOM 최대 높이 제한 대응 (약 1,500만 픽셀 상한선)\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let totalVirtualHeight = rawTotalVirtualHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n totalVirtualHeight = MAX_BROWSER_HEIGHT;\n }\n //trace.log(totalCount, rowHeight, rawTotalVirtualHeight, MAX_BROWSER_HEIGHT);\n // 스크롤홀더에는 브라우저가 소화할 수 있는 최대 높이만 부여\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n //trace.log(\"*************\",this.#sheet.querySelector('.ng-sheet-body').clientHeight, this.#sheet.querySelector('.ng-sheet-body').offsetHeight, viewHeight, fixedHeight, rawTotalVirtualHeight, totalVirtualHeight);\n\n //trace.log(totalVirtualHeight);\n // 🎯 스크롤바 위치(scrollTop)를 실제 데이터 좌표계로 역환산\n const actualScrollTop = useScaling ? (scrollTop / scaleFactor) : scrollTop;\n\n const maxStartIndex = Math.max(0, totalCount - 1);\n const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n\n // 실제 데이터 좌표 기준으로 시작 인덱스 산출 (원하시는 -1 보정 유지)\n const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight) - 1, maxStartIndex));\n // 🎯 -1 보정을 제거하여 최하단까지 정확히 매핑되도록 수정\n //const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n //trace.log(startIndex, clampedScrollTop, totalVirtualHeight, fixedHeight, rowHeight);\n\n // 🎯 화면 렌더링 오프셋도 '실제 데이터 좌표(clampedScrollTop)' 기준의 모듈러 연산 적용\n const renderOffsetTop = clampedScrollTop % rowHeight;\n this.#sheet.elements.left.tbody.body.style.top =\n this.#sheet.elements.body.tbody.body.style.top =\n this.#sheet.elements.right.tbody.body.style.top = `-${renderOffsetTop}px`;\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.row !== undefined ? parseInt(firstTr.dataset.row, 10) : -1;\n\n if (!force && currentStartIndex === startIndex) {\n //trace.log(`[Perf ${getTimestamp()}] ⏭️ 인덱스 동일로 스킵! 총 소요: ${(performance.now() - startTime).toFixed(2)}ms`);\n return;\n }\n\n //trace.log(`${getTimestamp()}`);\n\n\n // [범인 구간 추적]\n [\n this.#sheet.elements.left.tbody.body,\n this.#sheet.elements.body.tbody.body,\n this.#sheet.elements.right.tbody.body\n ].forEach(($tbody, tbodyIdx) => {\n if (!$tbody) return;\n\n const rows = $tbody.querySelectorAll('tbody.body tr');\n\n //trace.log(`${getTimestamp()}`);\n\n rows.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / templateLength);\n\n if (dataIndex >= totalCount) {\n $tr.style.display = 'none';\n $tr.dataset.matrixRow = null;\n $tr.dataset.row = null;\n return;\n }\n\n // trace.log(`${getTimestamp()}`);\n const record = viewRecords[dataIndex];//this.#sheet.view.getArray(dataIndex);\n //trace.log(`${getTimestamp()}`);\n\n if (!record) {\n $tr.style.display = 'none';\n return;\n }\n\n const rowid = record.m._[NINE_TABLE.META.INDEX.ROWID];\n\n $tr.style.display = '';\n\n // 💡 만약 개별 바인딩 안에서 느린지 확인하려면 여기서 측정 가능\n this.#bindRowData($tr, record, rowid, dataIndex);\n });\n });\n\n // 셀렉션 갱신\n this.#sheet.selection.refresh();\n };\n\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n trace.log(\"handleGroupdScroll() start\")\n\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n //trace.log(allRenderItems);\n\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.templateLength || 1;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH] || 0;\n // 💡 해당 뎁스 그룹 행의 높이가 정확히 잡히는지 확인 (없으면 첫 번째 템플릿 높이)\n const groupHeight = this.#templateRowHeights[depth] || this.#cachedTemplateHeight / templateLength;\n return groupHeight;\n } else {\n // 💡 데이터 행은 전체 템플릿 높이에서 그룹 TR들을 제외한 순수 데이터 TR들의 높이 합산이어야 합니다.\n // 만약 templateLength가 1이고 일반 행이라면 아래와 같이 처리\n let dataRowsHeight = 0;\n // templateRowHeights 전체 중에서 그룹이 아닌 데이터 행들의 높이만 합산하거나,\n // 단일 데이터 템플릿 높이를 정확히 반환해야 합니다.\n const templateLength = this.#sheet.templateLength || 1;\n\n // 간단하게 전체 캐시된 템플릿 높이에서 그룹 높이들을 뺀 나머지를 데이터 높이로 산정\n let groupHeightsTotal = 0;\n for(let i = 0; i < templateLength - 1; i++) {\n groupHeightsTotal += this.#templateRowHeights[i] || 0;\n }\n dataRowsHeight = this.#cachedTemplateHeight - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#cachedTemplateHeight;\n }\n };\n\n\n let totalVirtualHeight = 0;\n const itemHeights = new Array(totalVirtualCount);\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = getItemHeight(allRenderItems[i]);\n itemHeights[i] = h;\n totalVirtualHeight += h;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n trace.log(\"*************\", totalVirtualHeight);\n\n const viewportClientHeight = this.#sheet.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = 0;\n\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = itemHeights[i];\n if (accumulatedHeight + h > scrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n //trace.log(startIndex);\n\n const offsetY = scrollTop - accumulatedHeight;\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.virtualIndex !== undefined\n ? parseInt(firstTr.dataset.virtualIndex, 10)\n : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n const visibleRowsCount = Math.ceil(viewportClientHeight / (this.#cachedTemplateHeight / templateLength));\n const dynamicBuffer = (this.#sheet.grouping.columns?.length || 1) * 15;\n const targetStart = startIndex;\n const targetEnd = Math.min(totalVirtualCount, startIndex + visibleRowsCount + dynamicBuffer);\n\n\n\n\n const renderedItems = allRenderItems.slice(targetStart, targetEnd);\n\n //trace.log(\"handleGroupdScroll() 22\", renderedItems);\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const trs = Array.from(container.querySelectorAll('tbody.body tr'));\n\n for (let i = 0; i < trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = trs.slice(i, i + templateLength);\n\n if (!item || itemIndex >= renderedItems.length) {\n chunkTrs.forEach(tr => {\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.style.display = 'none';\n });\n continue;\n }\n\n const dataIndex = startIndex + itemIndex;\n\n chunkTrs.forEach((tr, subIdx) => {\n const virtualIndex = startIndex + itemIndex;\n tr.dataset.virtualIndex = virtualIndex;\n tr.dataset.row = (item.type === 'data') ? dataIndex : '';\n\n const isTrGroup = tr.getAttribute('grouping') === 'true';\n\n if (item.type === 'group') {\n if (isTrGroup) {\n const depth = item.record[GROUP_IDX.DEPTH];\n if (subIdx === depth) {\n tr.style.display = '';\n this.#bindGroupRowData(tr, allRenderItems, item.record, virtualIndex);\n } else {\n tr.style.display = 'none';\n }\n } else {\n tr.style.display = 'none';\n }\n } else {\n if (isTrGroup) {\n tr.style.display = 'none';\n } else {\n tr.style.display = '';\n\n //trace.log(item.record)\n const rowid = item.record.m?.rowid ?? 0;\n this.#bindRowData(tr, item.record, rowid, virtualIndex);\n }\n }\n });\n }\n });\n\n this.#sheet.selection.refresh();\n\n trace.log(\"handleGroupdScroll() end\")\n };\n\n #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n const indices = groupRecord[GROUP_IDX.CHILDREN]; // 인덱스 배열이 들어있는 위치 (정확한 인덱스는 구조에 맞게 조절)\n const allRecords = this.#host.data.getArray();\n const childrenRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n // 필요하다면 groupRecord나 tr에 자식 레코드들을 캐싱해 둘 수도 있습니다.\n //groupRecord.childrenRecords = childrenRecords;\n\n //trace.log(allRecords, childrenRecords);\n\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.row = '';\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = childrenRecords;//groupRecord;\n $tr.dataset.groupId = groupRecord[GROUP_IDX.ID];\n\n //trace.log(tr, groupRecord)\n\n Array.from($tr.cells).forEach(($cell) => {\n\n $cell.dataset.row = virtualIndex;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') || typeof $el.refresh === 'function'\n );\n\n //trace.log(customComp)\n\n if (customComp !== undefined && typeof customComp.refresh === 'function') {\n customComp?.refresh();\n }\n });\n };\n\n #bindRowData = ($tr, record, rowid, dataIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (dataIndex * templateLength) + subRowIndex;\n\n $tr.dataset.index = dataIndex;\n $tr.dataset.row = rowid;\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = record;\n\n Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = dataIndex;\n $cell.dataset.row = rowid;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.refresh === 'function'\n );\n\n customComp?.refresh();\n });\n };\n\n initialize = () => {\n //trace.log(\"rowManager.initialize\");\n\n this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n\n this.#cachedTemplateHeight = null;\n this.#containerTemplates.clear();\n\n this.#element = {\n scrollTables: this.#sheet.querySelectorAll('.ng-sheet-body table'),\n firstTr: this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body tr'),\n };\n\n // 컨테이너 템플릿 수집 부분도 tbody.body 기준으로 변경\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const tableEl = container.querySelector('table');\n if (!tableEl) return;\n\n const tbody = tableEl.querySelector('tbody.body'); // 👈 .bindable-tbody 대신 tbody.body\n if (!tbody) return;\n\n const trs = Array.from(tbody.querySelectorAll('tr'));\n const templateTrs = trs.map(tr => tr.cloneNode(true));\n this.#containerTemplates.set(selector, templateTrs);\n });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n if (bodyViewport) {\n this.#sheetHeight = bodyViewport.clientHeight;\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', () => {\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#cachedTemplateHeight || 0;\n const totalCount = this.#sheet.view.getArray()?.length || 0;\n const rawTotalVirtualHeight = totalCount * rowHeight;\n\n if (rawTotalVirtualHeight <= bodyViewport.clientHeight) {\n return;\n }\n\n this.#handleScroll(bodyViewport.scrollTop);\n\n this.#sheet.querySelector('nine-table-vscrollbar').refresh();\n //this.#sheet.querySelector('nine-table-hscrollbar').refresh();\n }, { passive: true });\n }\n };\n\n scrollToDataRow(dataRow, align = 'top', onRendered) {\n //trace.log(\"🔍 [scrollToDataRow ENTER]\", { dataRow, isGrouped: this.#isGrouped });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords?.length || 0;\n if (totalCount === 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const targetRow = Math.max(0, Math.min(dataRow, totalCount - 1));\n let targetScrollTop = 0;\n\n // 🎯 [핵심] 그룹핑 모드일 때는 실제 scrollHeight(또는 렌더링된 총 높이)를 기준으로 비율 계산\n if (this.#isGrouped) {\n const maxScrollTop = Math.max(bodyViewport.scrollHeight - bodyViewport.clientHeight, 1);\n // targetRow가 전체 totalCount에서 차지하는 비율(ratio)만큼 실제 스크롤 최대 높이에 곱해줌\n const ratio = targetRow / Math.max(totalCount - 1, 1);\n targetScrollTop = ratio * maxScrollTop;\n } else {\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n let rawTargetScrollTop = targetRow * rowHeight;\n\n /**\n if (align === 'bottom') {\n const viewportHeight = bodyViewport.clientHeight;\n const visibleRowsCount = Math.floor(viewportHeight / rowHeight);\n const adjustedRow = Math.max(0, targetRow - visibleRowsCount + 1);\n rawTargetScrollTop = adjustedRow * rowHeight;\n } */\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n //const rawTotalVirtualHeight = totalCount * rowHeight;\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n }\n\n //trace.log(\"🔍 [scrollToDataRow CALC FIXED]\", { targetRow, totalCount, targetScrollTop });\n\n this.#isProgrammaticScroll = true;\n bodyViewport.scrollTop = targetScrollTop;\n this.#handleScroll(targetScrollTop);\n //trace.log(targetScrollTop);\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.#isProgrammaticScroll = false;\n if (typeof onRendered === 'function') onRendered();\n });\n });\n }\n\n\n\n destroy = () => {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n };\n\n #measureAndCacheHeight = () => {\n if (!this.#sheet.classList.contains('active')) return;\n\n if (!this.#sheet.sourceTable) return;\n\n const trTemplates = this.#sheet.sourceTable?.querySelectorAll('tbody.body tr');\n //trace.log(\"[DEBUG #measureAndCacheHeight] bodyTemplates count:\", trTemplates?.length);\n //if (!trTemplates || trTemplates.length === 0) return;\n\n const $tbody = this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body');\n //if (!tbody) return -1;\n\n $tbody.querySelectorAll('tr').forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n trTemplates.forEach($tr => fragment.appendChild($tr.cloneNode(true)));\n $tbody.appendChild(fragment);\n\n //let totalHeight = 0;\n const renderedTrs = $tbody.querySelectorAll('tr');\n\n this.#templateRowHeights = [];\n renderedTrs.forEach($tr => {\n //const h = $tr.offsetHeight;\n //trace.log(`[DEBUG #measureAndCacheHeight] tr[${idx}] height:`, h);\n //totalHeight += h;\n\n this.#templateRowHeights.push($tr.offsetHeight);\n });\n\n renderedTrs.forEach(tr => tr.remove());\n\n this.#cachedTemplateHeight = this.#templateRowHeights.reduce((sum, h) => sum + h, 0);\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n trace.log(\"[DEBUG #updateRowCount] sheetHeight:\", this.#sheetHeight, \"cachedTemplateHeight:\", this.#cachedTemplateHeight);\n if (this.#sheetHeight > 0 && this.#cachedTemplateHeight > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#cachedTemplateHeight);\n\n // 💡 [유연한 개선] 그룹화가 켜져 있다면 그룹 컬럼 깊이(다단 레벨)에 따라 버퍼를 동적으로 확장\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped && this.#sheet.grouping) {\n const groupDepth = this.#sheet.grouping.columns?.length || 1;\n // 그룹 단계가 깊을수록 헤더 행이 많이 차지하므로 여유분을 비례해서 늘림 (예: 기본 버퍼 + (뎁스당 추가 여유))\n dynamicBuffer += (groupDepth * 15);\n }\n\n this.#cachedRowCount = visibleRows + dynamicBuffer;\n trace.log(\"[DEBUG #updateRowCount] calculated cachedRowCount:\", this.#cachedRowCount);\n }\n };\n\n #renderAllContainers = () => {\n trace.log(\"rowManager.#renderAllContainers\");\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (container && container.querySelector('tbody')) {\n this.#renderRows(container); // selector 인자 제거!\n }\n });\n\n this.#syncRowHeights();\n };\n\n #renderRows = (container) => {\n let targetFixedType = null;\n if (container.classList.contains('ng-container-left')) targetFixedType = 'left';\n else if (container.classList.contains('ng-container-right')) targetFixedType = 'right';\n\n // 🎯 [수정] 원본 테이블에서 tbody.body에 해당하는 tr들만 복제\n const templateTrs = Array.from(this.#sheet.sourceTable.querySelectorAll('tbody.body tr')).map(tr => {\n const clonedTr = tr.cloneNode(true);\n\n if (targetFixedType === 'left') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'left') $cell.remove();\n });\n } else if (targetFixedType === 'right') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'right') $cell.remove();\n });\n } else {\n clonedTr.querySelectorAll('[fixed=left], [fixed=right]').forEach($cell => {\n $cell.remove();\n });\n }\n\n return clonedTr;\n });\n\n if (templateTrs.length === 0) return;\n\n // 🎯 [수정] targetTbody도 일반 tbody가 아니라 tbody.body를 정확히 타겟팅\n const targetTbody = container.querySelector('tbody.body');\n if (!targetTbody) return;\n\n targetTbody.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < this.#cachedRowCount; i++) {\n templateTrs.forEach(tmpl => fragment.appendChild(tmpl.cloneNode(true)));\n }\n\n\n targetTbody.appendChild(fragment);\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n };\n\n\n\n #syncRowHeights = () => {\n const leftTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-left table');\n const bodyTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-body table');\n const rightTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-right table');\n\n if (bodyTable) {\n const leftRows = leftTable ? Array.from(leftTable.querySelectorAll('tbody tr')) : [];\n const bodyRows = Array.from(bodyTable.querySelectorAll('tbody tr'));\n const rightRows = rightTable ? Array.from(rightTable.querySelectorAll('tbody tr')) : [];\n\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n }\n };\n\n #initResizeObserver = () => {\n\n if (!this.#sheet || !(this.#sheet instanceof HTMLElement)) return;\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const sheetEl = entry.target;\n if (!sheetEl.classList.contains('active')) continue;\n\n const height = entry.contentRect.height;\n const width = entry.contentRect.width;\n\n if (width > 0 && this.#sheet.isAutoFitCol) {\n this.#sheet.autoFit(true);\n }\n\n if (height > 0 && this.#sheetHeight !== height) {\n this.#sheetHeight = height;\n this.#updateRowCount();\n\n if (this.#cachedTemplateHeight !== null) {\n this.#renderAllContainers();\n this.refresh();\n }\n }\n }\n });\n\n this.#resizeObserver.observe(this.#sheet);\n };\n}","import { trace } from \"@nopeer\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class TableCompiler {\n\n static compile($srcTable) {\n\n const $table = $srcTable.cloneNode(true);\n\n // 1. 헤더 컴파일\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n // 4. colgroup과 인덱스/fixed 속성 동기화\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n static recompile($table) {\n\n /** 너비조정은 필요없을듯 */\n /**\n const cols = Array.from($table.querySelectorAll('colgroup col'));\n cols.forEach((col, idx) => {\n //trace.log(col.cloneNode(true));\n\n col.setAttribute('data-col', idx);\n\n let w = col.getAttribute('width');\n if (!w || isNaN(parseFloat(w))) {\n w = parseFloat(col.style.width);\n }\n if (w && !isNaN(parseFloat(w))) {\n const numericWidth = Math.round(parseFloat(w));\n //trace.log(w, numericWidth);\n\n col.setAttribute('width', numericWidth);\n col.style.width = `${numericWidth}px`;\n }\n }); */\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n\n\n static #syncColAttributes($table) {\n\n $table.querySelectorAll('colgroup col').forEach(($col, i) => {\n $col.setAttribute('data-col', i);\n const fixed = $col.getAttribute('fixed');\n\n $table.querySelectorAll(`[data-col=\"${i}\"]`).forEach($el => {\n fixed ? $el.setAttribute('fixed', fixed) : $el.removeAttribute('fixed');\n });\n });\n }\n\n static resetColIndex($table, trs) {\n\n const cols = $table.querySelectorAll('colgroup col');\n const grid = Array.from({ length: trs.length }, () => Array(cols.length).fill(null));\n\n trs.forEach(($tr, index) => {\n\n $tr.dataset.subrow = index;\n\n let colIndex = 0;\n\n $tr.querySelectorAll('th, td').forEach($cell => {\n\n while (colIndex < cols.length && grid[index][colIndex] !== null) {\n colIndex++;\n }\n\n $cell.dataset.col = colIndex;\n\n const rowSpan = $cell.rowSpan || 1;\n const colSpan = $cell.colSpan || 1;\n\n for (let r = 0; r < rowSpan; r++) {\n for (let c = 0; c < colSpan; c++) {\n if (index + r < trs.length && colIndex + c < cols.length) {\n grid[index + r][colIndex + c] = $cell;\n }\n }\n }\n\n colIndex += colSpan;\n });\n });\n }\n\n\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellSelection {\r\n\t#sheet;\r\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#initEvents();\r\n\r\n\t\t/**\r\n\t\t// 🎯 [신규 구조 대응] .ng-sheet-body 및 내부 컨테이너 스크롤 감지\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (bodyViewport) {\r\n\t\t\tbodyViewport.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t} */\r\n\r\n\t\t/**\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}); */\r\n\r\n\t\ttrace.log(\"🎯 [CellSelection] Initialized (New Structure Compatible)\");\r\n\t}\r\n\r\n\t#getMatrixRow(tr) {\r\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10);\r\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr:not(.nodata)'));\r\n\r\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.row, 10) === dataRow);\r\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\r\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\r\n\r\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\r\n\r\n\t\treturn { dataRow, subRowIndex, matrixRow };\r\n\t}\r\n\r\n\tsetFocus(matrixRow, col) {\r\n\t\t// 1. 기존 포커스 클래스 제거\r\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {$tr.classList.remove(\"selected-start\");\r\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {$td.classList.remove(\"selected-start\");\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 [신규 구조 대응] data-matrix-row 탐색 경로 수정 (.ng-sheet-body-content 기준)\r\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!$td) return;\r\n\r\n\t\t$td.classList.add(\"selected-start\");\r\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\r\n\t}\r\n\r\n\tsetRange(startRow, startCol, endRow, endCol) {\r\n\t\tlet r1 = Math.min(startRow, endRow);\r\n\t\tlet r2 = Math.max(startRow, endRow);\r\n\t\tlet c1 = Math.min(startCol, endCol);\r\n\t\tlet c2 = Math.max(startCol, endCol);\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tlet expanded = true;\r\n\t\tlet loopCount = 0;\r\n\r\n\t\twhile (expanded && loopCount < 5) {\r\n\t\t\texpanded = false;\r\n\t\t\tloopCount++;\r\n\r\n\t\t\tcontainers.forEach(container => {\r\n\t\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\t\tif (tr.classList.contains('nodata')) return;\r\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\r\n\t\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\r\n\r\n\t\t\t\t\t\tif (isIntersecting) {\r\n\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\r\n\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\r\n\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\r\n\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\r\n\r\n\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\r\n\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\r\n\t\t\t\t\t\t\t\texpanded = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#range = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trefresh = () => {\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trender = () => {\r\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\t// 1. 기존 선택 클래스 초기화\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\r\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\r\n\t\t\t});\r\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\r\n\t\t\t\ttr.classList.remove('selected-start');\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tif (startRow < 0 || startCol < 0) return;\r\n\r\n\t\t// 2. 범위 렌더링\r\n\t\tcontainers.forEach((container) => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\r\n\t\t\t\t\tif (!isSelected) return;\r\n\r\n\t\t\t\t\tcell.classList.add('selected');\r\n\r\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\r\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\r\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\r\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 3. 포커스 셀 복구\r\n\t\tconst $focusTd = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${startRow}\"] td[data-col=\"${startCol}\"]`);\r\n\t\tif ($focusTd) {$focusTd.classList.add(\"selected-start\");\r\n\t\t\t$focusTd.closest('tr')?.classList.add(\"selected-start\");\r\n\t\t}\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!mainZone) {\r\n\t\t\ttrace.log(\"❌ [CellSelection] .ng-sheet-body not found!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmainZone.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tif (cell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\tthis.#sheet.style.userSelect = 'none';\r\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\r\n\r\n\t\t\tconst tr = cell.closest('tr');\r\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\r\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\r\n\r\n\t\t\tif (startRow < 0) {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis.setFocus(startRow, startCol);\r\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\r\n\r\n\t\t\tlet lastMatrixRow = startRow;\r\n\t\t\tlet lastCol = startCol;\r\n\r\n\t\t\tconst onMouseMove = (moveEvent) => {\r\n\t\t\t\tconst targetEl = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);\r\n\t\t\t\tlet targetCell = targetEl?.closest('td, th');\r\n\r\n\t\t\t\tif (!targetCell || !this.#sheet.contains(targetCell)) {\r\n\t\t\t\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr:not(.nodata) td, .ng-sheet-body-content tbody tr:not(.nodata) th');\r\n\t\t\t\t\tfor (const c of allCells) {\r\n\t\t\t\t\t\tconst rect = c.getBoundingClientRect();\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tmoveEvent.clientX >= rect.left &&\r\n\t\t\t\t\t\t\tmoveEvent.clientX <= rect.right &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY >= rect.top &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY <= rect.bottom\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\ttargetCell = c;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!targetCell) return;\r\n\t\t\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\r\n\t\t\t\tif (targetCell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\t\tconst targetTr = targetCell.closest('tr');\r\n\t\t\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\r\n\t\t\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\r\n\r\n\t\t\t\tif (endRow < 0) return;\r\n\t\t\t\tif (lastMatrixRow === endRow && lastCol === endCol) return;\r\n\r\n\t\t\t\tlastMatrixRow = endRow;\r\n\t\t\t\tlastCol = endCol;\r\n\r\n\t\t\t\tthis.setRange(startRow, startCol, endRow, endCol);\r\n\t\t\t};\r\n\r\n\t\t\tconst onMouseUp = () => {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\r\n\t\t\t\tdocument.removeEventListener('mousemove', onMouseMove);\r\n\t\t\t\tdocument.removeEventListener('mouseup', onMouseUp);\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener('mousemove', onMouseMove);\r\n\t\t\tdocument.addEventListener('mouseup', onMouseUp);\r\n\t\t});\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellNavigation {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#currentCell = null;\r\n\t#currentTr = null;\r\n\t#currentRow = -1;\r\n\t#currentCol = -1;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.#initEvents();\r\n\t\ttrace.log(\"🎯 [CellNavigation] Initialized (Diagnostic Logging Restored)\");\r\n\t}\r\n\r\n\tget currentCell() {\r\n\t\treturn this.#currentCell;\r\n\t}\r\n\r\n\tset currentCell(cell) {\r\n\t\tif (!cell) return;\r\n\r\n\t\tthis.#currentCell = cell;\r\n\t\tcell.focus({ preventScroll: true });\r\n\r\n\t\tthis.#currentTr = cell.closest(\"tr\");\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\ttrace.log(`📌 [setCurCell] Active set -> dataRow: ${cell.dataset.row}, subrow: ${cell.closest('tr')?.dataset.subrow}, matrixRow: ${matrixRow}, col: ${cell.dataset.col}`);\r\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\r\n\t}\r\n\r\n\t#getMatrixRowFromTr(tr) {\r\n\t\tif (!tr) return 0;\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10) || 0;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\t// 1. tr에 data-matrix-row가 박혀있다면 최우선 사용\r\n\t\tconst mRowAttr = parseInt(tr.dataset.matrixRow, 10);\r\n\t\tif (!isNaN(mRowAttr)) return mRowAttr;\r\n\r\n\t\t// 2. tbody 내에서 동일 data-row를 가진 그룹 중 몇 번째 서브 행인지 정확히 산출\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tif (tbody) {\r\n\t\t\tconst groupTrs = Array.from(tbody.querySelectorAll(`tr[data-row=\"${dataRow}\"]`));\r\n\t\t\tconst subIdx = groupTrs.indexOf(tr);\r\n\t\t\tif (subIdx >= 0) {\r\n\t\t\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\t\t\treturn (dataRow * templateLength) + subIdx;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst subRowIndex = parseInt(tr.dataset.subrow, 10) || 0;\r\n\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\treturn (dataRow * templateLength) + subRowIndex;\r\n\t}\r\n\r\n\tmoveCell(e) {\r\n\r\n\t\t//trace.log(e.target.tagName);\r\n\t\tif (![\"TH\",\"TD\"].includes(e.target.tagName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!this.#currentCell || !this.#currentTr) {\r\n\t\t\ttrace.log(\"⚠️ [moveCell] currentCell or currentTr is missing!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst cell = this.#currentCell;\r\n\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\tlet nextMatrixRow = matrixRow;\r\n\t\tlet nextCol = col;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tnextMatrixRow = matrixRow + (cell.rowSpan || 1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\t\tnextMatrixRow = Math.max(0, matrixRow - (cell.rowSpan || 1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\t\tif (nextCol < 0 && matrixRow > 0) {\r\n\t\t\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow - 1;\r\n\t\t\t\t\t\tconst prevTrs = this.#findTargetTrsByMatrix(nextMatrixRow);\r\n\t\t\t\t\t\tconst maxColCell = this.#getMaxColCell(prevTrs);\r\n\t\t\t\t\t\tnextCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) : 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\t\t\tconst maxColCell = this.#getMaxColCell(targetTrs);\r\n\t\t\t\t\tconst maxCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) + parseInt(maxColCell.colSpan || 1, 10) : 0;\r\n\r\n\t\t\t\t\tif (nextCol >= maxCol) {\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow + 1;\r\n\t\t\t\t\t\tnextCol = 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tconst maxDataRow = this.#host.data.length;\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst maxMatrixRowLimit = (maxDataRow * templateLength) - 1;\r\n\t\t\t\tif (matrixRow + (cell.rowSpan || 1) > maxMatrixRowLimit) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tif (matrixRow <= 0) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\ttrace.log(\"========\")\r\n\r\n\t\t// 🎯 전체 데이터 갯수 한계 체크 (오버플로우 방지)\r\n\t\tconst totalCount = this.#sheet.view.getArray()?.length || 0;\r\n\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\tconst maxMatrixRow = (totalCount * templateLength) - 1;\r\n\t\tnextMatrixRow = Math.max(0, Math.min(nextMatrixRow, maxMatrixRow));\r\n\r\n\t\ttrace.log(`⌨️ [Key: ${e.code}] Current matrixRow: ${matrixRow} -> Target nextMatrixRow: ${nextMatrixRow}, nextCol: ${nextCol}`);\r\n\r\n\t\tconst nextDataRow = Math.floor(nextMatrixRow / templateLength);\r\n\t\tconst nextSubRowIndex = nextMatrixRow % templateLength;\r\n\r\n\t\tconst attemptFindAndMove = (retries = 0) => {\r\n\t\t\tlet targetCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\r\n\t\t\tif (targetCell) {\r\n\t\t\t\ttrace.log(`✅ [Found Cell] Attempt ${retries} -> dataRow: ${targetCell.dataset.row}, col: ${targetCell.dataset.col}`);\r\n\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, targetCell.dataset.col, actualMatrixRow, targetCell.dataset.col);\r\n\r\n\t\t\t\tthis.#ensureCellVisible(targetCell);\r\n\t\t\t} else {\r\n\t\t\t\ttrace.log(`📜 [Scroll Trigger] Cell not found in DOM, invoking rowManager.scrollToDataRow(${nextDataRow})`);\r\n\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(nextDataRow, \"bottom\", () => {\r\n\t\t\t\t\ttrace.log(\"nextDataRow\", nextDataRow);\r\n\r\n\t\t\t\t\tconst retryLoop = () => {\r\n\t\t\t\t\t\tlet retryCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\t\t\t\t\t\tif (retryCell) {\r\n\t\t\t\t\t\t\ttrace.log(`✅ [Found After Scroll] RetryLoop success -> dataRow: ${retryCell.dataset.row}`);\r\n\t\t\t\t\t\t\tthis.currentCell = retryCell;\r\n\t\t\t\t\t\t\tconst tr = retryCell.closest(\"tr\");\r\n\t\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, retryCell.dataset.col, actualMatrixRow, retryCell.dataset.col);\r\n\t\t\t\t\t\t\tthis.#ensureCellVisible(retryCell);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t};\r\n\t\t\t\t\tretryLoop();\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tattemptFindAndMove();\r\n\t}\r\n\r\n\t#ensureCellVisible(cell) {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tconst bodyContainer = this.#sheet.querySelector('.ng-sheet-body .ng-container-body');\r\n\t\tconst headerBody = this.#sheet.querySelector('.ng-sheet-header .ng-container-body');\r\n\r\n\t\tif (!bodyViewport || !bodyContainer) return;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\t\tconst containerRect = bodyContainer.getBoundingClientRect();\r\n\t\tconst headerRect = headerBody ? headerBody.getBoundingClientRect() : null;\r\n\r\n\t\ttrace.log(`📐 [DIAGNOSTIC VISIBILITY] \r\n- cell.dataset.col: ${cell.dataset.col}\r\n- cellRect (left: ${cellRect.left}, right: ${cellRect.right})\r\n- containerRect (left: ${containerRect.left}, right: ${containerRect.right}, width: ${containerRect.width}, scrollLeft: ${bodyContainer.scrollLeft}, scrollWidth: ${bodyContainer.scrollWidth}, clientWidth: ${bodyContainer.clientWidth})\r\n- viewportRect (width: ${viewportRect.width})\r\n- headerBody (scrollLeft: ${headerBody?.scrollLeft}, width: ${headerRect?.width})\r\n `);\r\n\r\n\t\tconst isAbove = cellRect.top < viewportRect.top;\r\n\t\tconst isBelow = cellRect.bottom > viewportRect.bottom;\r\n\r\n\t\tif (isAbove || isBelow) {\r\n\t\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\t\tconst col = cell.dataset.col;\r\n\t\t\tconst $tr = cell.closest(\"tr\");\r\n\t\t\tconst subrow = $tr?.dataset.subrow || 0;\r\n\r\n\t\t\tif (!isNaN(dataRow) && this.#sheet.rowManager) {\r\n\t\t\t\ttrace.log(\"11111111111\");\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(dataRow, \"top\", () => {\r\n\t\t\t\t\tconst targetCell = this.#sheet.querySelector(`.ng-sheet-body tr[data-row=\"${dataRow}\"][data-subrow=\"${subrow}\"] td[data-col=\"${col}\"]`);\r\n\t\t\t\t\tif (targetCell) {\r\n\t\t\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\t\t\tconst tr = targetCell.closest(\"tr\");\r\n\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, col, actualMatrixRow, col);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (cellRect.left < containerRect.left) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Left] cell out of left bound`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft -= (containerRect.left - cellRect.left + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t} else if (cellRect.right > containerRect.right) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Right] cell out of right bound. cellRect.right: ${cellRect.right} > containerRect.right: ${containerRect.right}`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft += (cellRect.right - containerRect.right + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t}\r\n\t}\r\n\r\n\t#getMinCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet minCol = Infinity;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tminCol = Math.min(minCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn minCol === Infinity ? 0 : minCol;\r\n\t};\r\n\r\n\t#getMaxCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet maxCol = 0;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tmaxCol = Math.max(maxCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn maxCol;\r\n\t};\r\n\r\n\t#getMaxColCell = (targetTrs) => {\r\n\t\tconst allCells = [];\r\n\t\ttargetTrs.forEach(tr => allCells.push(...Array.from(tr.querySelectorAll('td'))));\r\n\t\tif (allCells.length === 0) return null;\r\n\t\tallCells.sort((a, b) => parseInt(a.dataset.col, 10) - parseInt(b.dataset.col, 10));\r\n\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\treturn allCells[allCells.length - 1];\r\n\t};\r\n\r\n\t#getNextCol = (matrixRow, col) => {\r\n\t\tconst td = this.#sheet.querySelector(`.ng-sheet-body tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`) ||\r\n\t\t\tthis.#sheet.querySelector(`.ng-sheet-body td[data-col=\"${col}\"]`);\r\n\r\n\t\tconst colSpan = td?.colSpan || 1;\r\n\t\tconst next = col + colSpan;\r\n\t\ttrace.log(`🔍 [#getNextCol] current col: ${col}, found td colSpan: ${colSpan}, calculated next col: ${next}`);\r\n\t\treturn next;\r\n\t}\r\n\r\n\t#getPreviousCol = (matrixRow, currentCol) => {\r\n\t\tif (currentCol <= 0) return 0;\r\n\t\tconst currentTrCells = this.#currentTr ? Array.from(this.#currentTr.querySelectorAll('td, th')) : [];\r\n\t\tconst cols = new Set();\r\n\r\n\t\tcurrentTrCells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tcols.add(c);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (cols.size === 0) {\r\n\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\ttargetTrs.forEach(tr => {\r\n\t\t\t\tArray.from(tr.querySelectorAll('td, th')).forEach(cell => {\r\n\t\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\t\t\tcols.add(c);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst smallerCols = Array.from(cols).filter(c => c < currentCol);\r\n\t\treturn smallerCols.length === 0 ? Math.max(0, currentCol - 1) : Math.max(...smallerCols);\r\n\t};\r\n\r\n\t#findTargetTrsByMatrix = (matrixRow) => {\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body .ng-container-left, .ng-sheet-body .ng-container-body, .ng-sheet-body .ng-container-right'\r\n\t\t);\r\n\t\tconst matchedTrs = [];\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tconst trs = Array.from(container.querySelectorAll('tbody tr'));\r\n\t\t\tfor (const tr of trs) {\r\n\t\t\t\tconst mRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\tif (mRow === matrixRow) {\r\n\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst cells = Array.from(tr.querySelectorAll('td'));\r\n\t\t\t\tlet foundInSpan = false;\r\n\t\t\t\tfor (const cell of cells) {\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tif (rowSpan > 1 && matrixRow >= mRow && matrixRow < mRow + rowSpan) {\r\n\t\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\t\tfoundInSpan = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (foundInSpan) break;\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn matchedTrs;\r\n\t};\r\n\r\n\t#getNearElement = (dataRow, subRowIndex, col, matrixRow) => {\r\n\t\tconst targetMatrixRow = matrixRow !== undefined ? matrixRow : (dataRow * (this.#sheet.templateLength || 1)) + subRowIndex;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\tconst targetDataRow = Math.floor(targetMatrixRow / templateLength);\r\n\t\tconst targetSubRow = targetMatrixRow % templateLength;\r\n\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body, .ng-container-left, .ng-container-body, .ng-container-right, .ng-part-body'\r\n\t\t);\r\n\r\n\t\tconst searchedTrs = new Set();\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => searchedTrs.add(tr));\r\n\t\t});\r\n\r\n\t\tfor (const tr of Array.from(searchedTrs)) {\r\n\t\t\tconst trDataRow = parseInt(tr.dataset.row, 10);\r\n\t\t\tif (isNaN(trDataRow)) continue;\r\n\r\n\t\t\tconst tbody = tr.closest('tbody');\r\n\t\t\tconst groupTrs = tbody ? Array.from(tbody.querySelectorAll(`tr[data-row=\"${trDataRow}\"]`)) : [tr];\r\n\t\t\tconst trSubIdx = groupTrs.indexOf(tr);\r\n\r\n\t\t\tfor (const cell of Array.from(tr.querySelectorAll('td'))) {\r\n\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\tconst span = parseInt(cell.colSpan || 1, 10);\r\n\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\r\n\t\t\t\tif (isNaN(c) || window.getComputedStyle(cell).display === 'none') continue;\r\n\r\n\t\t\t\tconst cellDataRowStart = trDataRow;\r\n\t\t\t\tconst cellSubRowStart = trSubIdx;\r\n\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst cellStartMatrix = (cellDataRowStart * templateLength) + cellSubRowStart;\r\n\t\t\t\tconst cellEndMatrix = cellStartMatrix + rowSpan - 1;\r\n\r\n\t\t\t\tif (targetMatrixRow >= cellStartMatrix && targetMatrixRow <= cellEndMatrix) {\r\n\t\t\t\t\tif (col >= c && col < c + span) {\r\n\t\t\t\t\t\treturn cell;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn null;\r\n\t};\r\n\r\n\t#initEvents() {\r\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tthis.currentCell = cell;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\r\n\t\t\tif ([\"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\r\n\t\t\t\tthis.moveCell(e);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}","// ui/col/ColResizer.js\nimport { trace } from \"@nopeer\";\nimport { COLLAPSED_WIDTH, TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nconst RESIZE_OFFSET = 2; // 🎯 리사이즈 감지 영역 오프셋을 상단으로 추출\n\nexport class ColResizer {\n #sheet;\n #host;\n #panel;\n #tooltip;\n\n #targetColIndex = null;\n #nextColIndex = null;\n #targetContainerType = null;\n #targetCell = null;\n #startX = 0;\n #startColWidth = 0;\n #nextColStartWidth = 0;\n #startCellWidth = 0;\n #startLeft = 0;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#host = sheet.getRootNode().host;\n this.#panel = this.#sheet.querySelector('.ng-col-resizer-panel');\n this.#tooltip = this.#panel?.querySelector('.resizer-overlay');\n this.bindEvents();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointermove', this.#onPointerMove);\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n this.#sheet.removeEventListener('dblclick', this.#onDblClick);\n }\n\n refreshLayout(containerType = 'body') {\n const containers = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType}`));\n if (containers.length === 0) return;\n\n const isFixedContainer = containerType === 'left' || containerType === 'right';\n const isAutoFit = !isFixedContainer && (\n this.#sheet.isAutoFitCol ||\n containers[0].querySelector('table')?.getAttribute('auto-fit-col') === 'true'\n );\n\n if (!isAutoFit) {\n\n const firstColgroup = containers[0].querySelector('table colgroup');\n if (!firstColgroup) return;\n\n let totalWidth = 0;\n const colWidths = {};\n\n Array.from(firstColgroup.querySelectorAll('col')).forEach(col => {\n const colIdx = col.getAttribute('data-col');\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) {\n colWidths[colIdx] = w;\n totalWidth += w;\n }\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n\n trace.log(\"====================\", containers, containerType);\n\n if (containerType === 'body') {\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n //tbl.style.minWidth = `${totalWidth}px`;\n });\n } else {\n container.style.flex = `0 0 ${totalWidth}px`;\n container.style.width = `${totalWidth}px`;\n container.style.minWidth = `${totalWidth}px`;\n container.style.maxWidth = `${totalWidth}px`;\n\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n tbl.style.minWidth = `${totalWidth}px`;\n tbl.style.maxWidth = `${totalWidth}px`;\n\n Object.entries(colWidths).forEach(([colIdx, w]) => {\n tbl.querySelectorAll(`th[data-col=\"${colIdx}\"], td[data-col=\"${colIdx}\"]`).forEach(cell => {\n cell.style.width = `${w}px`;\n cell.style.minWidth = `${w}px`;\n cell.style.maxWidth = `${w}px`;\n });\n });\n });\n }\n });\n } else {\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n tables.forEach(tbl => {\n //tbl.style.width = '100%';\n //tbl.style.minWidth = '100%';\n //tbl.style.maxWidth = '';\n });\n });\n }\n\n this.#sheet.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n setColumnWidth(globalColIndex, width, containerType = null) {\n\n trace.log(\"setColumnWidth\");\n\n\n let targetCols = [];\n\n //if (containerType) {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType} table colgroup col[data-col=\"${globalColIndex}\"]`));\n //} else {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n //}\n targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n\n if (targetCols.length === 0) return;\n\n const firstContainer = targetCols[0].closest('.ng-container-left, .ng-container-body, .ng-container-right');\n const resolvedContainerType = containerType || (\n firstContainer?.classList.contains('ng-container-left') ? 'left' :\n firstContainer?.classList.contains('ng-container-right') ? 'right' : 'body'\n );\n\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n\n trace.log(col, width);\n });\n\n const sourceCol = this.#sheet.sourceTable?.querySelector(`colgroup col[data-col=\"${globalColIndex}\"]`);\n if (sourceCol) {\n sourceCol.setAttribute('width', width);\n sourceCol.style.width = `${width}px`;\n }\n\n\n\n this.refreshLayout(resolvedContainerType);\n\n // 🎯 [핵심] autoFit을 여기서 또 호출하면 루프가 돌거나 레이아웃 계산이 꼬입니다.\n // 바디 영역 리사이즈 시에는 body만 refreshLayout 해주면 됩니다!\n if (resolvedContainerType === 'left' || resolvedContainerType === 'right') {\n this.refreshLayout('body');\n }\n\n this.#sheet.rowManager?.refresh();\n }\n\n #checkIsAutoFit(targetCell) {\n if (this.#sheet.isAutoFitCol) return true;\n const table = targetCell?.closest('table');\n if (table && table.getAttribute('auto-fit-col') === 'true') return true;\n return false;\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointermove', this.#onPointerMove);\n //this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n //this.#sheet.addEventListener('dblclick', this.#onDblClick);\n\n this.#sheet.addDebounseEventListener('dblclick', this.#onDblClick, 'pointerdown', this.#onPointerDown);\n }\n\n #getContainerType(cell) {\n const container = cell.closest('.ng-container-left, .ng-container-body, .ng-container-right');\n if (!container) return null;\n if (container.classList.contains('ng-container-left')) return 'left';\n if (container.classList.contains('ng-container-right')) return 'right';\n return 'body';\n }\n\n #onPointerMove = (e) => {\n\n\n const headerPart = e.target.closest('thead');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n\n headerPart.querySelectorAll('.resizable-edge').forEach(el => {\n if (el !== cell) el.classList.remove('resizable-edge');\n });\n\n if (!cell || cell.dataset.col === undefined) return;\n if (cell.getAttribute('collapsed') === 'true') return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n const isLeftEdge = offsetX <= RESIZE_OFFSET;\n const isRightEdge = (rect.width - offsetX) <= RESIZE_OFFSET;\n\n if (isLeftEdge) {\n const prevCell = cell.previousElementSibling;\n if (!prevCell || prevCell.getAttribute('collapsed') === 'true') {\n cell.classList.remove('resizable-edge');\n return;\n }\n }\n\n if (isLeftEdge || isRightEdge) {\n cell.classList.add('resizable-edge');\n } else {\n cell.classList.remove('resizable-edge');\n }\n };\n\n #onPointerDown = (e) => {\n\n //const path = e.composedPath();\n //const cell1 = path.find(el => el?.nodeType === Node.ELEMENT_NODE && (el.tagName === 'TH' || el.tagName === 'TD'));\n\n //trace.log(e);\n //trace.log( path, cell1);\n\n //const actualTarget = document.elementFromPoint(e.clientX, e.clientY);\n //if (!actualTarget) return;\n\n trace.log(e.actualTarget, e.target);\n\n const headerPart = e.actualTarget.closest('thead');\n if (!headerPart) return;\n\n const cell = e.actualTarget.closest('th, td');\n trace.log(cell, e.actualTarget);\n\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n\n\n e.preventDefault();\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n let targetCell = cell;\n\n if (offsetX <= RESIZE_OFFSET) {\n const prevCell = cell.previousElementSibling;\n if (prevCell && prevCell.dataset.col !== undefined && prevCell.getAttribute('collapsed') !== 'true') {\n targetCell = prevCell;\n } else if (!cell.previousElementSibling) {\n return;\n }\n }\n\n this.#targetCell = targetCell;\n this.#targetContainerType = this.#getContainerType(targetCell);\n\n const container = this.#sheet.querySelector(`.ng-container-${this.#targetContainerType}`);\n if (!container) return;\n\n const baseColIndex = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n this.#targetColIndex = baseColIndex + colSpan - 1;\n\n const isAutoFit = this.#checkIsAutoFit(targetCell);\n if (isAutoFit) {\n this.#nextColIndex = this.#targetColIndex + 1;\n const nextColEl = container.querySelector(`col[data-col=\"${this.#nextColIndex}\"]`);\n if (nextColEl) {\n this.#nextColStartWidth = parseInt(nextColEl.getAttribute('width'), 10) || 100;\n } else {\n this.#nextColIndex = null;\n }\n } else {\n this.#nextColIndex = null;\n }\n\n const targetRect = targetCell.getBoundingClientRect();\n const sheetRect = this.#sheet.getBoundingClientRect();\n\n this.#startCellWidth = targetRect.width;\n this.#startLeft = targetRect.left - sheetRect.left;\n\n const targetColEl = container.querySelector(`col[data-col=\"${this.#targetColIndex}\"]`);\n const attrW = targetColEl?.getAttribute('width');\n this.#startColWidth = (attrW && !isNaN(parseInt(attrW, 10))) ? parseInt(attrW, 10) : targetRect.width / colSpan;\n\n this.#startX = e.clientX;\n\n if (this.#panel) {\n this.#panel.classList.add('active');\n this.#updatePositions(e.clientX);\n }\n\n window.addEventListener('pointermove', this.#onDragMove);\n window.addEventListener('pointerup', this.#onDragEnd, { once: true });\n };\n\n #updatePositions(clientX) {\n let diff = clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxDiff = this.#nextColStartWidth - COLLAPSED_WIDTH;\n const minDiff = -(this.#startColWidth - COLLAPSED_WIDTH);\n diff = Math.max(minDiff, Math.min(diff, maxDiff));\n }\n\n const currentColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n\n const targetRect = this.#targetCell.getBoundingClientRect();\n let realCellWidth = clientX - targetRect.left;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxCellWidth = this.#startCellWidth + (this.#nextColStartWidth - COLLAPSED_WIDTH);\n realCellWidth = Math.min(realCellWidth, maxCellWidth);\n }\n\n const currentCellWidth = Math.max(COLLAPSED_WIDTH, realCellWidth);\n\n if (this.#panel) {\n this.#panel.style.setProperty('--tooltip-left', `${this.#startLeft}px`);\n this.#panel.style.setProperty('--tooltip-width', `${currentCellWidth}px`);\n }\n\n const sizeBadge = this.#tooltip?.querySelector('.size-badge');\n if (sizeBadge) {\n sizeBadge.textContent = `${Math.round(currentColWidth)}px`;\n }\n }\n\n #onDragMove = (e) => {\n trace.log(e);\n this.#updatePositions(e.clientX);\n };\n\n #onDragEnd = (e) => {\n window.removeEventListener('pointermove', this.#onDragMove);\n\n const diff = e.clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n let finalWidth = 0;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n let newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n let newNextWidth = this.#startColWidth + this.#nextColStartWidth - newColWidth;\n\n if (newNextWidth < COLLAPSED_WIDTH) {\n newNextWidth = COLLAPSED_WIDTH;\n newColWidth = this.#startColWidth + this.#nextColStartWidth - COLLAPSED_WIDTH;\n }\n\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n this.setColumnWidth(this.#nextColIndex, newNextWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n } else {\n const newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n if (this.#targetColIndex !== null && this.#targetContainerType) {\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n }\n }\n\n if (this.#targetCell) {\n const targetCell = this.#targetCell;\n if (targetCell.getAttribute('collapsed') !== 'true' && finalWidth > 20) {\n targetCell.dataset.expandWidth = String(finalWidth);\n }\n }\n\n if (this.#panel) {\n this.#tooltip?.classList.add('fade-out');\n setTimeout(() => {\n this.#panel.classList.remove('active');\n this.#tooltip?.classList.remove('fade-out');\n }, 150);\n }\n\n this.#targetColIndex = null;\n this.#nextColIndex = null;\n this.#targetContainerType = null;\n this.#targetCell = null;\n };\n\n #onDblClick = (e) => {\n\n const targetEl = e.target;\n let cell = targetEl.closest('th, td');\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n if (offsetX <= RESIZE_OFFSET) {\n cell = cell.previousElementSibling;\n }\n\n const baseColIndex = parseInt(cell.dataset.col, 10);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${baseColIndex}\"]`);\n if (!tbodyCell || !tbodyCell.dataset.bind || tbodyCell.classList.contains(\"CELL-RADIO\")) return;\n\n let extraPadding = 0;\n Array.from(tbodyCell.firstElementChild.children).forEach(($el) => {\n switch ($el.tagName) {\n case 'SPAN': extraPadding += 8; break;\n case 'DIV': extraPadding += 8; break;\n case 'BUTTON': extraPadding += 32; break;\n case 'SELECT': extraPadding += 32; break;\n case 'INPUT':\n switch (($el.type || 'text').toLowerCase()) {\n // 1. 체크박스 / 라디오 (비교적 좁은 영역)\n case 'checkbox':\n case 'radio':\n extraPadding += 12;\n break;\n\n // 2. 버튼 계열 input\n case 'button':\n case 'submit':\n case 'reset':\n case 'image':\n extraPadding += 16;\n break;\n\n // 3. 특수 위젯 (컬러, 파일, 슬라이더)\n case 'color':\n case 'file':\n case 'range':\n extraPadding += 24;\n break;\n\n // 4. 화면에 안 보이는 hidden 필드\n case 'hidden':\n extraPadding += 0;\n break;\n\n // 5. 텍스트 및 숫자, 날짜 등 일반 입력 필드 (기본값)\n case 'text':\n case 'search':\n case 'tel':\n case 'url':\n case 'email':\n case 'password':\n case 'number':\n case 'date':\n case 'time':\n case 'datetime-local':\n case 'month':\n case 'week':\n default:\n extraPadding += 16;\n break;\n }\n break;\n }\n });\n\n trace.log(extraPadding);\n\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n\n // 헤더 텍스트 길이 측정\n const headerText = cell.innerText || \"\";\n const headerSize = nine.measureTextSize(headerText, font);\n let maxTextWidth = (headerSize.width || 0) + 16;\n\n this.#host.execute(() => {\n\n this.#sheet.view.getArray().forEach((record, idx) => {\n const val = String(tbodyCell.dataset.expr ? this.#host.exprEngine.evaluate(tbodyCell.dataset.expr, record, idx) : record.v[fieldIdx] ?? \"\").trim();\n const size = nine.measureTextSize(val, font);\n if (size.width && size.width > maxTextWidth) {\n maxTextWidth = size.width;\n }\n });\n\n // 글자 수 당 대략적인 픽셀 계산 (기본 패딩 여백 포함, 최소 32px ~ 최대 400px 제한)\n const calculatedWidth = Math.max(32, Math.min(400, Math.ceil(maxTextWidth) + extraPadding));\n\n // 자동 계산된 너비 적용\n this.setColumnWidth(tbodyCell.dataset.col, calculatedWidth, this.#getContainerType(cell));\n })\n };\n}\n\n","// ui/col/ColMover.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColMover {\n #sheet;\n #grip;\n #indi;\n\n #isDragging = false;\n #sourceCell = null;\n #sourceColIndex = null;\n #targetColIndex = null;\n #shiftX = 0;\n #timer = null;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#grip = this.#sheet.querySelector('.ng-col-mover-grip');\n this.#indi = this.#sheet.querySelector('.ng-col-mover-indi');\n this.bindEvents();\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n }\n\n #checkIsMovable() {\n const host = this.#sheet.getRootNode()?.host;\n return this.#sheet.getAttribute('col-movable') === 'true' || host?.getAttribute('col-movable') === 'true';\n }\n\n #getDeepElementFromPoint(x, y) {\n const root = this.#sheet.getRootNode();\n let el = root.elementFromPoint ? root.elementFromPoint(x, y) : document.elementFromPoint(x, y);\n\n while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) {\n const nested = el.shadowRoot.elementFromPoint(x, y);\n if (!nested || nested === el) break;\n el = nested;\n }\n\n return el;\n }\n\n #getColGroupRange(cell) {\n if (!cell || cell.dataset.col === undefined) return null;\n\n const startCol = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const endCol = startCol + colSpan - 1;\n const rowIndex = cell.closest('tr')?.sectionRowIndex ?? 0;\n\n const table = cell.closest('table');\n if (!table) return { startCol, colSpan, endCol, rowIndex, isGroup: false, parentGroupRange: null, isValidGroup: true };\n\n const headerCells = table.querySelectorAll('thead th, thead td');\n let hasStrictChildren = false;\n let isValidGroup = true;\n let parentGroupRange = null;\n\n for (const subCell of headerCells) {\n if (subCell === cell || subCell.dataset.col === undefined) continue;\n\n const subStart = parseInt(subCell.dataset.col, 10);\n const subSpan = subCell.colSpan || 1;\n const subEnd = subStart + subSpan - 1;\n const subRowIndex = subCell.closest('tr')?.sectionRowIndex ?? 0;\n\n if (subRowIndex < rowIndex && subStart <= startCol && subEnd >= endCol && subSpan > colSpan) {\n if (!parentGroupRange) {\n parentGroupRange = { startCol: subStart, endCol: subEnd };\n } else {\n parentGroupRange.startCol = Math.max(parentGroupRange.startCol, subStart);\n parentGroupRange.endCol = Math.min(parentGroupRange.endCol, subEnd);\n }\n }\n\n const isOverlap = !(subEnd < startCol || subStart > endCol);\n if (isOverlap) {\n const isFullyContained = (subStart >= startCol && subEnd <= endCol);\n\n if (isFullyContained) {\n if (subSpan < colSpan) {\n hasStrictChildren = true;\n }\n } else if (subStart < startCol || subEnd > endCol) {\n if (!(subStart <= startCol && subEnd >= endCol)) {\n isValidGroup = false;\n }\n }\n }\n }\n\n const isRealGroup = hasStrictChildren && isValidGroup;\n\n return {\n startCol,\n colSpan: isRealGroup ? colSpan : 1,\n endCol: isRealGroup ? endCol : startCol,\n rowIndex,\n isGroup: isRealGroup,\n parentGroupRange,\n isValidGroup\n };\n }\n\n #createGroupHeaderPreview(cell) {\n const groupRange = this.#getColGroupRange(cell);\n if (!groupRange) return null;\n\n const { startCol, endCol, isGroup } = groupRange;\n\n // 핵심: 테이블이 여러 개인 구조이므로 cell이 속한 바로 그 테이블을 직접 가져옵니다.\n const origTable = cell.closest('table');\n if (!origTable) return null;\n\n let minLeft = Infinity, maxRight = -Infinity, minTop = Infinity, maxBottom = -Infinity;\n const targetCells = [];\n\n origTable.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n const isTarget = isGroup\n ? (cCol >= startCol && cEnd <= endCol)\n : (c === cell);\n\n if (isTarget) {\n const rect = c.getBoundingClientRect();\n minLeft = Math.min(minLeft, rect.left);\n maxRight = Math.max(maxRight, rect.right);\n minTop = Math.min(minTop, rect.top);\n maxBottom = Math.max(maxBottom, rect.bottom);\n\n const computedStyle = window.getComputedStyle(c);\n targetCells.push({ el: c, rect, style: computedStyle });\n }\n });\n\n if (targetCells.length === 0) return null;\n\n const groupWidth = maxRight - minLeft;\n const groupHeight = maxBottom - minTop;\n\n const headerContent = document.createElement('div');\n headerContent.className = 'grip-header-content';\n headerContent.style.position = 'relative';\n headerContent.style.width = `${groupWidth}px`;\n headerContent.style.height = `${groupHeight}px`;\n\n targetCells.forEach(({ el, rect, style }) => {\n const clonedCell = el.cloneNode(true);\n\n clonedCell.style.position = 'absolute';\n clonedCell.style.left = `${rect.left - minLeft}px`;\n clonedCell.style.top = `${rect.top - minTop}px`;\n\n clonedCell.style.width = `${rect.width}px`;\n clonedCell.style.minWidth = `${rect.width}px`;\n clonedCell.style.maxWidth = 'none';\n\n clonedCell.style.height = `${rect.height}px`;\n clonedCell.style.boxSizing = 'border-box';\n clonedCell.style.margin = '0';\n\n clonedCell.style.backgroundColor = style.backgroundColor !== 'transparent' && style.backgroundColor !== 'rgba(0, 0, 0, 0)'\n ? style.backgroundColor\n : '#f9fafb';\n clonedCell.style.color = style.color;\n clonedCell.style.font = style.font;\n clonedCell.style.fontWeight = style.fontWeight;\n clonedCell.style.fontSize = style.fontSize;\n clonedCell.style.textAlign = style.textAlign;\n clonedCell.style.padding = style.padding;\n clonedCell.style.border = style.border;\n clonedCell.style.borderRight = style.borderRight;\n clonedCell.style.borderBottom = style.borderBottom;\n clonedCell.style.display = 'flex';\n clonedCell.style.alignItems = 'center';\n clonedCell.style.justifyContent = style.textAlign === 'center' ? 'center' : (style.textAlign === 'right' ? 'flex-end' : 'flex-start');\n\n headerContent.appendChild(clonedCell);\n });\n\n return {\n element: headerContent,\n bounds: {\n left: minLeft,\n right: maxRight,\n top: minTop,\n bottom: maxBottom,\n width: groupWidth,\n height: groupHeight\n }\n };\n }\n\n #onPointerDown = (e) => {\n if (!this.#checkIsMovable()) return;\n\n const headerPart = e.target.closest('.ng-sheet-header');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n if (!cell || cell.classList.contains('resizable-edge') || ['INPUT', 'BUTTON'].includes(e.target.tagName)) return;\n if (cell.dataset.col === undefined) return;\n\n e.preventDefault();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cancelTimer = () => {\n if (this.#timer) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n window.removeEventListener('pointermove', onPointerMovePending);\n window.removeEventListener('pointerup', cancelTimer);\n window.removeEventListener('pointercancel', cancelTimer);\n };\n\n const onPointerMovePending = (moveEvent) => {\n const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);\n if (dist > 5) {\n cancelTimer();\n }\n };\n\n this.#timer = setTimeout(() => {\n cancelTimer();\n this.#startDrag(e, cell);\n }, 500);\n\n window.addEventListener('pointermove', onPointerMovePending);\n window.addEventListener('pointerup', cancelTimer, { once: true });\n window.addEventListener('pointercancel', cancelTimer, { once: true });\n };\n\n #startDrag(e, cell) {\n if (this.#isDragging) return;\n\n const preview = this.#createGroupHeaderPreview(cell);\n if (!preview) return;\n\n this.#isDragging = true;\n this.#sourceCell = cell;\n this.#sourceColIndex = parseInt(cell.dataset.col, 10);\n\n const sheetRect = this.#sheet.getBoundingClientRect();\n const { bounds, element } = preview;\n\n this.#shiftX = e.clientX - bounds.left;\n\n if (this.#grip) {\n this.#grip.replaceChildren(element);\n\n const relativeTop = bounds.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#grip.style.width = `${bounds.width}px`;\n this.#grip.style.height = `${fullHeight}px`;\n this.#grip.style.top = `${relativeTop}px`;\n this.#grip.style.display = 'block';\n\n this.#updateGripPosition(e.clientX);\n }\n\n document.body.style.cursor = 'move';\n\n window.addEventListener('pointermove', this.#onPointerMove);\n window.addEventListener('pointerup', this.#onPointerUp, { once: true });\n }\n\n #onPointerMove = (e) => {\n if (!this.#isDragging) return;\n\n this.#updateGripPosition(e.clientX);\n\n if (this.#grip) this.#grip.style.pointerEvents = 'none';\n if (this.#indi) this.#indi.style.pointerEvents = 'none';\n\n const targetElement = this.#getDeepElementFromPoint(e.clientX, e.clientY);\n const targetCell = targetElement?.closest('.ng-sheet-header th, .ng-sheet-header td');\n\n if (targetCell && targetCell.dataset.col !== undefined) {\n const targetColIndex = parseInt(targetCell.dataset.col, 10);\n const sheetRect = this.#sheet.getBoundingClientRect();\n const table = targetCell.closest('table');\n\n let colMinLeft = Infinity;\n let colMaxRight = -Infinity;\n\n if (table) {\n table.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n if (cCol <= targetColIndex && cEnd >= targetColIndex) {\n const cRect = c.getBoundingClientRect();\n colMinLeft = Math.min(colMinLeft, cRect.left);\n colMaxRight = Math.max(colMaxRight, cRect.right);\n }\n });\n }\n\n if (colMinLeft === Infinity) {\n const rect = targetCell.getBoundingClientRect();\n colMinLeft = rect.left;\n colMaxRight = rect.right;\n }\n\n const midX = colMinLeft + ((colMaxRight - colMinLeft) / 2);\n let calculatedTargetCol = 0;\n let indicatorLeft = 0;\n\n if (e.clientX < midX) {\n calculatedTargetCol = targetColIndex;\n indicatorLeft = colMinLeft - sheetRect.left;\n } else {\n const colSpan = targetCell.colSpan || 1;\n calculatedTargetCol = targetColIndex + colSpan;\n indicatorLeft = colMaxRight - sheetRect.left;\n }\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n const movingSpan = sourceGroup.colSpan;\n\n const sourceRowStart = sourceGroup.rowIndex;\n const sourceRowSpan = this.#sourceCell.rowSpan || 1;\n const sourceRowEnd = sourceRowStart + sourceRowSpan - 1;\n\n const targetRowStart = targetCell.closest('tr')?.sectionRowIndex ?? 0;\n const targetRowSpan = targetCell.rowSpan || 1;\n const targetRowEnd = targetRowStart + targetRowSpan - 1;\n\n const isRowSpanCompatible = !(sourceRowEnd < targetRowStart || sourceRowStart > targetRowEnd);\n\n let isOutOfBoundsOfParent = false;\n if (sourceGroup.parentGroupRange) {\n const { startCol: pStart, endCol: pEnd } = sourceGroup.parentGroupRange;\n if (calculatedTargetCol < pStart || (calculatedTargetCol + movingSpan - 1) > pEnd) {\n isOutOfBoundsOfParent = true;\n }\n }\n\n let isDroppingInsideOtherGroup = false;\n if (table) {\n const spannedCells = table.querySelectorAll('thead th[colspan], thead td[colspan]');\n\n for (const sCell of spannedCells) {\n if (sCell === this.#sourceCell) continue;\n\n const sRowStart = sCell.closest('tr')?.sectionRowIndex ?? 0;\n const sRowSpan = sCell.rowSpan || 1;\n const sRowEnd = sRowStart + sRowSpan - 1;\n\n const isVerticalOverlap = !(sourceRowEnd < sRowStart || sourceRowStart > sRowEnd);\n if (!isVerticalOverlap) continue;\n\n const sStart = parseInt(sCell.dataset.col, 10);\n const sSpan = sCell.colSpan || 1;\n const sEnd = sStart + sSpan - 1;\n\n if (calculatedTargetCol > sStart && calculatedTargetCol < sEnd + 1) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n\n const moveEndCol = calculatedTargetCol + movingSpan - 1;\n const isCrossIntersecting = (\n (calculatedTargetCol > sStart && calculatedTargetCol <= sEnd && moveEndCol > sEnd) ||\n (calculatedTargetCol < sStart && moveEndCol >= sStart && moveEndCol < sEnd)\n );\n\n if (isCrossIntersecting) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n }\n }\n\n const isSelfGroup = (\n calculatedTargetCol >= sourceGroup.startCol &&\n calculatedTargetCol <= sourceGroup.endCol + 1\n );\n\n const isInvalidMove = !isRowSpanCompatible || isSelfGroup || isOutOfBoundsOfParent || isDroppingInsideOtherGroup || !sourceGroup.isValidGroup;\n\n if (isInvalidMove) {\n this.#targetColIndex = null;\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n } else {\n this.#targetColIndex = calculatedTargetCol;\n if (this.#grip) this.#grip.classList.remove('invalid');\n\n if (this.#indi) {\n const headerPart = targetCell.closest('.ng-sheet-header');\n const headerRect = headerPart.getBoundingClientRect();\n const relativeTop = headerRect.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#indi.style.top = `${relativeTop}px`;\n this.#indi.style.height = `${fullHeight}px`;\n this.#indi.style.left = `${indicatorLeft - 1}px`;\n this.#indi.style.display = 'block';\n }\n }\n } else {\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n this.#targetColIndex = null;\n }\n };\n\n #updateGripPosition(clientX) {\n if (!this.#grip) return;\n const sheetRect = this.#sheet.getBoundingClientRect();\n const left = clientX - sheetRect.left - this.#shiftX;\n this.#grip.style.left = `${left}px`;\n }\n\n #onPointerUp = (e) => {\n if (!this.#isDragging) return;\n\n window.removeEventListener('pointermove', this.#onPointerMove);\n document.body.style.cursor = '';\n\n if (this.#grip) {\n this.#grip.style.display = 'none';\n this.#grip.replaceChildren();\n }\n if (this.#indi) this.#indi.style.display = 'none';\n\n if (\n this.#targetColIndex !== null &&\n this.#sourceColIndex !== null &&\n this.#targetColIndex !== this.#sourceColIndex &&\n this.#targetColIndex !== this.#sourceColIndex + 1\n ) {\n this.moveColumn(this.#sourceColIndex, this.#targetColIndex);\n }\n\n this.#isDragging = false;\n this.#sourceCell = null;\n this.#sourceColIndex = null;\n this.#targetColIndex = null;\n };\n\n moveColumn(fromColIndex, toColIndex) {\n\n trace.log(this.#sheet.sourceTable.cloneNode(true));\n\n const colgroup = this.#sheet.sourceTable.querySelector('colgroup');\n const targetCol = colgroup.querySelector(`col[data-col=\"${toColIndex}\"]`);\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n if (!sourceGroup || !sourceGroup.isValidGroup) return;\n\n const spanCount = sourceGroup.colSpan;\n const isInRange = (idx) => idx >= fromColIndex && idx < fromColIndex + spanCount;\n\n // 1. colgroup 내 <col> 이동 및 fixed 설정\n const targetViewportCol = this.#sheet.querySelector(`.ng-sheet-body-content col[data-col=\"${toColIndex}\"]`);\n const fixedType = targetViewportCol?.closest('.ng-container-left') ? 'left' : targetViewportCol?.closest('.ng-container-right') ? 'right' : null;\n\n colgroup.querySelectorAll('col').forEach(col => {\n if (isInRange(parseInt(col.getAttribute('data-col'), 10))) {\n fixedType ? col.setAttribute('fixed', fixedType) : col.removeAttribute('fixed');\n colgroup.insertBefore(col, targetCol);\n }\n });\n\n // 2. 테이블 행(tr) 내부의 셀(th, td) 순서 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n this.#sheet.sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n const cells = Array.from(tr.children);\n const targetRowCell = cells.find(c => parseInt(c.dataset.col, 10) >= toColIndex);\n\n cells.forEach(cell => {\n if (isInRange(parseInt(cell.dataset.col, 10))) {\n tr.insertBefore(cell, targetRowCell || null);\n }\n });\n });\n });\n\n this.#sheet.recompileAndRefresh();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n }\n}","// ui/col/ColFixManager.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColFixManager {\n #sheet;\n\n constructor(sheet) {\n this.#sheet = sheet;\n }\n\n /**\n * 🎯 현재 클릭된 셀의 고정 구역('left', 'right', 'none') 탐색\n */\n getFixState(targetCell, table) {\n if (!targetCell || !table) return 'none';\n\n // 🎯 [보정] 3분할 레이어 구조 내부의 컨테이너를 안전하게 탐색\n const container = targetCell.closest('.ng-container-left, .ng-container-right, .ng-container-body');\n if (container?.classList.contains('ng-container-left')) return 'left';\n if (container?.classList.contains('ng-container-right')) return 'right';\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n if (!isNaN(baseCol)) {\n const colEl = table.querySelector(`colgroup col[data-col=\"${baseCol}\"]`);\n const fixedAttr = colEl?.getAttribute('fixed');\n if (fixedAttr) return fixedAttr;\n }\n\n return 'none';\n }\n\n /**\n * 🎯 상하 멀티 헤더 경계선 일치 여부 검사 (Fix Column 가부 판별)\n */\n canFixColumn(targetCell, table) {\n if (!targetCell || targetCell.tagName !== 'TH' || !table) return false;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n if (isNaN(baseCol)) return false;\n\n const targetBoundaryCol = baseCol + colSpan - 1;\n const theadTrs = Array.from(table.querySelectorAll('thead tr'));\n\n if (theadTrs.length <= 1) return true;\n\n for (const tr of theadTrs) {\n const cells = Array.from(tr.querySelectorAll('th, td'));\n let cellBoundaryFound = false;\n\n for (const cell of cells) {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEndCol = cCol + cSpan - 1;\n\n // 목표 경계선이 특정 셀의 중간을 관통하는 경우 (Fix 불가능)\n if (cCol <= targetBoundaryCol && targetBoundaryCol < cEndCol) {\n return false;\n }\n\n if (cEndCol === targetBoundaryCol) {\n cellBoundaryFound = true;\n break;\n }\n }\n\n if (!cellBoundaryFound) return false;\n }\n\n return true;\n }\n\n /**\n * 🎯 [인스턴스 메서드] 배치 범위 고정 및 해제 처리\n * - 원본(`sourceTable`)의 구조(fixed 속성)를 직접 조작하므로 decompile은 절대 호출하지 않음!\n */\n executeFixToggle(action, targetCell, fixType = 'left') {\n if (!this.#sheet || !targetCell) return;\n\n const sourceTable = this.#sheet.sourceTable;\n if (!sourceTable) return;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n const targetColIndex = baseCol + colSpan - 1;\n\n if (isNaN(targetColIndex)) return;\n\n const colgroup = sourceTable.querySelector('colgroup');\n if (!colgroup) return;\n\n const cols = Array.from(colgroup.querySelectorAll('col'));\n\n if (action === 'fix-column') {\n // 🎯 Batch Fix: 0번부터 targetColIndex까지의 모든 <col>과 셀에 fixed 속성 일괄 부여\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx <= targetColIndex) {\n col.setAttribute('fixed', fixType);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (!isNaN(cIdx) && cIdx <= targetColIndex) {\n cell.setAttribute('fixed', fixType);\n }\n });\n });\n });\n\n } else if (action === 'unfix-column') {\n let minBaseCol = baseCol;\n let maxEndCol = baseCol + colSpan - 1;\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach((tr, rIdx) => {\n Array.from(tr.children).forEach(cell => {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n const rSpan = cell.rowSpan || 1;\n const trIndex = tr.sectionRowIndex ?? rIdx;\n\n // 현재 클릭된 셀의 수직 범위와 겹치는 머지 셀이 있는지 검사\n const isVerticalOverlap = !(trIndex + rSpan - 1 < cell.closest('tr').sectionRowIndex || trIndex > (cell.closest('tr').sectionRowIndex + rSpan - 1));\n\n // 만약 기존에 고정(fixed)되어 있으면서 현재 클릭한 타겟 라인과 걸쳐있는 머지 셀이라면 범위를 확장합니다.\n const isHorizontalOverlap = !(cEnd < baseCol || cCol > targetColIndex);\n\n if (isHorizontalOverlap) {\n minBaseCol = Math.min(minBaseCol, cCol);\n maxEndCol = Math.max(maxEndCol, cEnd);\n }\n });\n });\n });\n\n // 🎯 2단계: 계산된 실제 머지 블록의 시작점(minBaseCol) 이상인 모든 <col> 속성 해제\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx >= minBaseCol) {\n col.removeAttribute('fixed');\n }\n });\n\n // 🎯 3단계: left 구역의 고정 연속성(체인) 검증\n let isBroken = false;\n cols.forEach(col => {\n if (isBroken) {\n col.removeAttribute('fixed');\n } else if (!col.getAttribute('fixed')) {\n isBroken = true;\n }\n });\n\n // 🎯 4단계: <col>들의 최종 fixed 상태를 기준으로 모든 thead, tbody, tfoot 셀(th, td)의 fixed 속성 완벽 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (isNaN(cIdx)) return;\n\n const correspondingCol = cols.find(c => parseInt(c.getAttribute('data-col'), 10) === cIdx);\n const isColFixed = correspondingCol?.getAttribute('fixed');\n\n if (isColFixed) {\n cell.setAttribute('fixed', isColFixed);\n } else {\n cell.removeAttribute('fixed');\n }\n });\n });\n });\n }\n\n trace.log(this.#sheet.sourceTable);\n\n // 🎯 recompileAndRefresh 단 1회 호출로 원본 정렬 및 뷰포트 재생성 완결\n this.#sheet.recompileAndRefresh?.();\n }\n}","import { NINE_TABLE } from '@/core/constants.js';\r\nimport { trace } from \"@nopeer\";\r\n\r\n/**\r\n * 🎯 [필터 패널 커스텀 엘리먼트 Light DOM 버전]\r\n */\r\nexport class NineTableFilterPanel extends HTMLElement {\r\n\t#sheet;\r\n\t#host;\r\n\t#nineTable;\r\n\t#view;\r\n\t#button;\r\n\tcurrentCol = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#init();\r\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\r\n\t}\r\n\r\n\t#init = () => {\r\n\t\t//setTimeout(() => {\r\n\t\t\tthis.#renderer();\r\n\r\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\r\n\t\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\r\n\t\t\ttrace.log(\"1***********************\", this.#nineTable);\r\n\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\r\n\t\t\t\ttrace.log(\"2***********************\", this.#view);\r\n\t\t\t})\r\n\r\n\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t});\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\r\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\r\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\r\n\t\t//});\r\n\t}\r\n\r\n\t#renderer = () => {\r\n\t\tthis.innerHTML = `\r\n <style>\r\n nine-table-filter-panel nine-table-simple {\r\n width: 100%;\r\n flex: 1;\r\n border: none;\r\n }\r\n nine-table-filter-panel.active {\r\n display: flex;\r\n }\r\n nine-table-filter-panel .search-box {\r\n width: 100%;\r\n height: 28px;\r\n box-sizing: border-box;\r\n padding: 0px 8px;\r\n border: none;\r\n border-bottom: 1px solid #e5e7eb;\r\n border-radius: 0px;\r\n outline: none;\r\n font-size: 12px;\r\n background: #fafafa;\r\n color: #333;\r\n }\r\n nine-table-filter-panel .search-box:focus {\r\n background: #ffffff;\r\n }\r\n nine-table-filter-panel .footer-section {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 4px 6px;\r\n gap: 8px;\r\n border-top: 1px solid #e5e7eb;\r\n background: #f9fafb;\r\n flex-shrink: 0;\r\n }\r\n nine-table-filter-panel .footer-btns {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 6px;\r\n }\r\n nine-table-filter-panel .footer-btns label {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n nine-table-filter-panel .btn-group {\r\n display: flex;\r\n gap: 4px;\r\n }\r\n nine-table-filter-panel button {\r\n padding: 4px 14px;\r\n border-radius: 4px;\r\n border: 1px solid #d1d5db;\r\n background: #ffffff;\r\n cursor: pointer;\r\n font-size: 11px;\r\n }\r\n nine-table-filter-panel button:hover {\r\n background: #f3f4f6;\r\n }\r\n nine-table-filter-panel button#btnOk {\r\n background: #2563eb;\r\n color: white;\r\n border: none;\r\n }\r\n </style>\r\n\r\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\r\n \r\n <nine-table-simple class=\"filter-list\" theme=\"simple\">\r\n <table auto-fit-col=\"true\">\r\n <colgroup>\r\n <col width=\"32\" fixed=\"left\" />\r\n <col width=\"180\" />\r\n <col width=\"0\" fixed=\"right\"/>\r\n </colgroup>\r\n <tbody>\r\n <tr>\r\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\r\n <td data-bind=\"DATA2\" html=\"true\"></td>\r\n <td data-bind=\"DATA\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </nine-table-simple>\r\n\r\n <div class=\"footer-section\">\r\n <div class=\"footer-btns\">\r\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\r\n <div class=\"btn-group\">\r\n <button id=\"btnOk\">Apply</button>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n\t}\r\n\r\n\topen(filterBtn) {\r\n\t\tthis.#button = filterBtn;\r\n\r\n\t\tconst cell = filterBtn.closest(\"th, td\");\r\n\t\tthis.currentCol = cell?.dataset.col;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\r\n\r\n\t\tconst panelWidth = this.offsetWidth || 240;\r\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\r\n\t\tlet top = cellRect.bottom - sheetRect.top;\r\n\r\n\t\tif (left < 0) {\r\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\r\n\t\t}\r\n\r\n\t\tthis.style.left = `${left}px`;\r\n\t\tthis.style.top = `${top}px`;\r\n\r\n\t\tconst searchBox = this.querySelector(\".search-box\");\r\n\t\tsearchBox.value = \"\";\r\n\r\n\t\tthis.classList.add(\"active\");\r\n\t\tthis.classList.add(\"loading\");\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tthis.#loadVirtualFilterItems();\r\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\r\n\t\t\t} finally {\r\n\t\t\t\tthis.classList.remove(\"loading\");\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t#closeHandler = (e) => {\r\n\t\tconst path = e.composedPath ? e.composedPath() : [];\r\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.close();\r\n\t};\r\n\r\n\tclose() {\r\n\t\tthis.currentCol = null;\r\n\t\tthis.classList.remove(\"active\");\r\n\t\tthis.#button = null;\r\n\t}\r\n\r\n\t#loadVirtualFilterItems() {\r\n\t\tconst filteredRecords = this.#host.data.getArray();\r\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] 형태 배열\r\n\t\tconst fields = this.#host.fields.get() || [];\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst ds = targetCols.flatMap((colInfo) => {\r\n\t\t\tconst bindKey = colInfo.bind;\r\n\t\t\tconst exprKey = colInfo.expr;\r\n\r\n\t\t\tconst filterKey = bindKey || exprKey; // 실제 필터 파라미터 키로 사용\r\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\r\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\r\n\r\n\t\t\t// 1. Map을 이용한 O(N) 고속 유니크 추출 (DATA는 bind/원시값, DATA2는 expr 연산 결과)\r\n\t\t\tconst uniqueMap = new Map();\r\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\r\n\t\t\t\tconst record = filteredRecords[i];\r\n\t\t\t\tif (!record) continue;\r\n\r\n\t\t\t\t// DATA 기준이 될 원시 값 (bind가 있으면 필드 인덱스에서, 없으면 expr 결과)\r\n\t\t\t\tlet rawVal = undefined;\r\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\trawVal = record.v[fieldIdx];\r\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\r\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\r\n\t\t\t\t} else if (exprKey && exprEngine) {\r\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// DATA2에 출력될 화면 표시 값 (expr 수식 연산 결과, 없으면 rawVal)\r\n\t\t\t\tlet displayVal = rawVal;\r\n\t\t\t\tif (exprKey && exprEngine) {\r\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\r\n\t\t\t\t\tuniqueMap.set(displayVal, {\r\n\t\t\t\t\t\tv: rawVal, // 💡 필터링 비교 기준 (DATA)\r\n\t\t\t\t\t\tv2: displayVal // 💡 화면 출력 기준 (DATA2)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst uniqueList = [...uniqueMap.values()];\r\n\r\n\t\t\t// 2. 출력값(v2) 기준 정렬\r\n\t\t\tuniqueList.sort((a, b) => String(a.v2 || \"\").localeCompare(String(b.v2 || \"\")));\r\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\r\n\r\n\t\t\treturn uniqueList.map(o => ({\r\n\t\t\t\tLVL: 2,\r\n\t\t\t\tDATA: o.v, // 필터링 비교용 값\r\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2, // 화면 출력용 값\r\n\t\t\t\tCOLNM: filterKey,\r\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v || \"\") >= 0 ? \"Y\" : \"N\"\r\n\t\t\t}));\r\n\t\t});\r\n\r\n\t\tthis.#nineTable.data.set(ds);\r\n\r\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\r\n\t\tif (selectAllChk) {\r\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\r\n\t\t}\r\n\t}\r\n\r\n\t#onOk = () => {\r\n\t\tthis.#host.loading = true;\r\n\r\n\t\tconst filterRecords = this.#view.view.getArray();\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\r\n\t\tconst checkedRecords = filterRecords.filter(record => {\r\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\r\n\t\t\treturn (chk === \"Y\" || chk === true);\r\n\t\t});\r\n\r\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\r\n\r\n\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\r\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\r\n\r\n\t\t\tif (selectedVals.length > 0) {\r\n\t\t\t\tfilterParams[filterKey] = selectedVals;\r\n\t\t\t} else {\r\n\t\t\t\tdelete filterParams[filterKey];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tconst totalCount = this.#nineTable.data.count();\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tif (totalCount === checkedRecords.length) {\r\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\t\t\tbtn.updateFilteredState();\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.#sheet.invalidate();\r\n\t\t\t\tthis.close();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#host.loading = false;\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t#onInput = (e) => {\r\n\r\n\t\tconst query = e.target.value.toLowerCase().trim();\r\n\r\n\t\tif (!query) {\r\n\t\t\tthis.#view.filtering.clear();\r\n\t\t} else {\r\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\r\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\r\n\r\n\t\t\tconst matchedValues = [];\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\r\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\r\n\r\n\t\t\t\t// 💡 expr 연산 결과가 담긴 DATA2 텍스트와 검색어 비교\r\n\t\t\t\tif (textVal.includes(query)) {\r\n\t\t\t\t\tmatchedValues.push(val);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\ttrace.log(matchedValues);\r\n\r\n\t\t\tthis.#view.filtering.set({\r\n\t\t\t\tDATA2: [...new Set(matchedValues)]\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t#onSelectAll = (e) => {\r\n\t\tconst isChecked = e.target.checked;\r\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\r\n\r\n\t\tif (chkIdx >= 0) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#nineTable.refresh();\r\n\t};\r\n\r\n\t#onCancel = () => {\r\n\t\tthis.close();\r\n\t};\r\n}\r\n\r\nexport class NineTableFilterButton extends HTMLElement {\r\n\t#sheet;\r\n\t#columns = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\r\n\t\tthis.removeEventListener(\"click\", this.#onClick);\r\n\t\tthis.addEventListener(\"click\", this.#onClick);\r\n\t}\r\n\r\n\tget columns() {\r\n\t\tif (this.#columns) return this.#columns;\r\n\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst colIndex = cell?.dataset.col;\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\r\n\t\tconst cols = [];\r\n\t\tconst seen = new Set();\r\n\r\n\t\tif (sourceTable && colIndex !== undefined) {\r\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\t\tconst bindKey = $td.dataset.bind;\r\n\t\t\t\tconst exprKey = $td.dataset.expr;\r\n\r\n\t\t\t\tif (bindKey || exprKey) {\r\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\r\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\r\n\t\t\t\t\t\tseen.add(uniqueKey);\r\n\t\t\t\t\t\tcols.push({\r\n\t\t\t\t\t\t\tbind: bindKey,\r\n\t\t\t\t\t\t\texpr: exprKey,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#columns = cols;\r\n\t\treturn this.#columns;\r\n\t}\r\n\r\n\tupdateFilteredState = () => {\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst isFiltered = this.columns.some(colInfo => {\r\n\t\t\tconst key = colInfo.expr || colInfo.bind;\r\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\r\n\t\t});\r\n\t\tthis.classList.toggle('filtered', isFiltered);\r\n\t};\r\n\r\n\t#onClick = (e) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst col = cell?.dataset.col;\r\n\r\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\r\n\t\t\tpanel.close();\r\n\t\t} else if (panel) {\r\n\t\t\tpanel.open(this);\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class Filtering {\r\n\t#sheet;\r\n\t#host;\r\n\t#isFiltering = false;\r\n\t#filterPanel = null;\r\n\t#filters = {};\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t\tthis.#init();\r\n\t}\r\n\r\n\tget filters() {\r\n\t\treturn this.#filters;\r\n\t};\r\n\r\n\t#init = () => {\r\n\t\tthis.#initFilterPanel();\r\n\t}\r\n\r\n\t#initFilterPanel = () => {\r\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tif (!panel) {\r\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\r\n\t\t\tthis.#sheet.appendChild(panel);\r\n\t\t}\r\n\t\tthis.#filterPanel = panel;\r\n\t}\r\n\r\n\tisFiltering() {\r\n\t\treturn this.#isFiltering;\r\n\t}\r\n\r\n\tclear = (colnm) => {\r\n\t\tif (colnm) {\r\n\t\t\tdelete this.#filters[colnm];\r\n\t\t} else {\r\n\t\t\tthis.#filters = {};\r\n\t\t}\r\n\r\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\r\n\t\tthis.#applyFiltering();\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\tbtn.updateFilteredState();\r\n\t\t});\r\n\r\n\t\ttrace.log(`🔄 [NineTableFiltering] Filter cleared for ${colnm || 'all'}`);\r\n\t}\r\n\r\n\tset = (oFilter) => {\r\n\r\n\t\ttrace.log(oFilter);\r\n\r\n\t\tlet jsonFilter = Array.isArray(oFilter)\r\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\r\n\t\t\t: oFilter;\r\n\r\n\t\tthis.#filters = jsonFilter;\r\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\r\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\r\n\r\n\t\tthis.#applyFiltering();\r\n\t}\r\n\r\n\t#applyFiltering() {\r\n\t\tconst hostData = this.#host.data;\r\n\t\tconst rawRecords = hostData.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields();\r\n\t\tconst sheetIndex = this.#sheet.index;\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\r\n\r\n\t\tif (!hasFilters) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.#sheet.invalidate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 💡 필터 규칙 빌드 (targetKey가 bind인지 expr 수식인지 판별)\r\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\r\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\r\n\t\t\treturn {\r\n\t\t\t\ttargetKey,\r\n\t\t\t\tisExpr,\r\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\r\n\t\t\t\tallowedSet: new Set(allowedValues)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\trawRecords.forEach((record, recordIdx) => {\r\n\t\t\tif (!record) return;\r\n\r\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\r\n\t\t\t}\r\n\r\n\t\t\tlet isPass = true;\r\n\r\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\r\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\r\n\t\t\t\tlet val = undefined;\r\n\r\n\t\t\t\tif (isExpr && exprEngine) {\r\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\r\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\tval = record.v[fieldIdx];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!allowedSet.has(val)) {\r\n\t\t\t\t\tisPass = false;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-panel')) {\r\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-button')) {\r\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\r\n}","// ui/data/Sorting.js (또는 정렬 관련 소스)\r\nimport { trace } from \"@nopeer\";\r\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\r\n\r\nexport class Sorting {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#columns = [];\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.#initEvents();\r\n\t\t}, 300);\r\n\t}\r\n\r\n\t#initEvents() {\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\r\n\r\n\t\t\t$el.addEventListener('dblclick', (e) => {\r\n\r\n\t\t\t\tconst cell = e.target.closest('th, td');\r\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\r\n\r\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\r\n\r\n\t\t\t\t// 🎯 [수정] 줄바꿈으로 깨져있던 마이너스 연산자를 한 줄로 정상 복구\r\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\r\n\r\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\r\n\r\n\t\t\t\thost.loading = true;\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.#handleSort(e, cell);\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\t// 🎯 3. 작업이 끝나면 무조건 로딩바 끄기\r\n\t\t\t\t\t\thost.loading = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}); // 또는 requestAnimationF\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\ttrace.log(\"🎯 [NineTableSorting] Initialized\");\r\n\t}\r\n\r\n\t#handleSort(e, cell) {\r\n\t\tconst colIndex = cell.dataset.col;\r\n\t\tconst tr = cell.closest('tr');\r\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\r\n\r\n\t\tif (colIndex === undefined) return;\r\n\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (!sourceTable) return;\r\n\r\n\t\tlet colName = null;\r\n\t\tlet exprVal = null; // 💡 expr 속성 수집용 변수\r\n\r\n\t\t// 1. 🎯 데이터 바인딩 키(colName) 및 expr 탐지\r\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\tif ($td.dataset.bind) {\r\n\t\t\t\tcolName = $td.dataset.bind;\r\n\t\t\t}\r\n\t\t\t// 💡 셀에 선언된 expr 식 추출\r\n\t\t\tif ($td.dataset.expr) {\r\n\t\t\t\texprVal = $td.dataset.expr;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!colName && !exprVal) return;\r\n\r\n\t\tconst isAsc = cell.classList.contains('asc');\r\n\t\tconst isDesc = cell.classList.contains('desc');\r\n\r\n\t\tif (!e.ctrlKey && !e.shiftKey) {\r\n\t\t\tthis.#columns = [];\r\n\t\t}\r\n\r\n\t\tconst existingColIndex = this.#columns.findIndex(\r\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\r\n\t\t);\r\n\r\n\t\t// 정렬 규칙 추가 시 expr 속성(`expr`) 함께 저장\r\n\t\tconst ruleData = {\r\n\t\t\tcolIndex,\r\n\t\t\tsubRowIndex,\r\n\t\t\tcolname: colName || exprVal,\r\n\t\t\tcolName: colName || exprVal,\r\n\t\t\texpr: exprVal, // 💡 expr 규칙 보관\r\n\t\t\tasc: true,\r\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\r\n\t\t};\r\n\r\n\t\tif (!isAsc && !isDesc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\r\n\t\t\t}\r\n\t\t} else if (isAsc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#columns = this.#columns.filter(\r\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tthis.#applySorting();\r\n\t}\r\n\r\n\t#applySorting() {\r\n\t\tif (!this.#sheet.view) {\r\n\t\t\tconsole.warn(\"⚠️ [NineTableSorting] Sheet view (SheetView) is not initialized.\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.view.setSorting(this.#columns);\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.invalidate();\r\n\t\t//this.#sheet.rowManager?.refresh(true);\r\n\r\n\t\ttrace.log(\"🔄 [NineTableSorting] Sorting applied via RowManager.refresh(true)\");\r\n\t}\r\n\r\n\t#syncHeaderUI() {\r\n\t\t// 기존 UI 클래스 초기화\r\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\r\n\t\t\tel.classList.remove('asc', 'desc');\r\n\t\t});\r\n\r\n\t\tif (this.#columns.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 🎯 [핵심] tr[data-subrow] + [data-col] 조합으로 정밀 타겟팅\r\n\t\tthis.#columns.forEach(colRule => {\r\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\r\n\r\n\t\t\tif (colIndex !== undefined) {\r\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\r\n\t\t\t\tif (subRowIndex !== undefined) {\r\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\r\n\t\t\t\ttargetHeaderCells.forEach(cell => {\r\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t//TableCompiler.decompile(this.#sheet);\r\n\t}\r\n\r\n\trestore() {\r\n\t\tthis.#columns = [];\r\n\t\tif (this.#sheet.view) {\r\n\t\t\tthis.#sheet.view.resetSorting();\r\n\t\t}\r\n\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.rowManager?.refresh(true);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\nimport {Grouping} from \"@/data/Grouping.js\";\r\n\r\nexport class SheetView {\r\n\t#sheet;\r\n\t#host;\r\n\t#sortingColumns = []; // 정렬 규칙 [{ colname, asc, expr-func }]\r\n\t#filterRules = []; // 필터 규칙\r\n\t#viewIndexes = []; // 필터링 및 소팅이 반영된 유효 데이터 인덱스 버퍼\r\n\r\n\t#cachedVisibleRecords = null; // 💡 [추가] 캐싱된 유효 레코드 배열\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.refresh();\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [시트 뷰 전용 배열 조회] - 캐시 적용으로 성능 대폭 개선\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\t// 💡 캐시가 없거나 비어있을 때만 가져옴 (보통 refresh에서 갱신됨)\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords;\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.#host.data.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst visibleRecords = this.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (!targetRecord) return null;\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#convSingle(targetRecord, fields);\r\n\t};\r\n\r\n\t#convSingle = (o, fields) => {\r\n\t\tif (!o) return null;\r\n\t\tconst t = {};\r\n\t\tfields.forEach((colnm, i) => {\r\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t});\r\n\t\tif (o.m) t.m = o.m;\r\n\t\tif (o._) t._ = o._;\r\n\t\treturn t;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 또는 정렬/필터 변경 시에만 실행되는 뷰 버퍼 재계산\r\n\t */\r\n\t\t// SheetView.refresh() 내부 예시\r\n\trefresh = () => {\r\n\r\n\t\tthis.#cachedVisibleRecords = null;\r\n\r\n\t\t// 1. 필터 적용\r\n\t\tconst rawRecords = this.#host.data.getArray();\r\n\t\tlet indices = [];\r\n\t\trawRecords.forEach((record, i) => {\r\n\t\t\tif (!record) return;\r\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\r\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\r\n\t\t\tindices.push(i);\r\n\t\t});\r\n\r\n\t\ttrace.log(indices);\r\n\r\n\t\t// 2. 정렬 적용\r\n\t\tif (this.#sortingColumns.length > 0) {\r\n\t\t\tindices = this.#applySorting(indices, rawRecords);\r\n\t\t}\r\n\r\n\t\tthis.#viewIndexes = indices;\r\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\r\n\r\n\t\t//trace.log(this.#sheet.sourceTable);\r\n\t\t//const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\r\n\t\t//trace.log(\"#######\", isGrouped, this.#sheet.grouping?.columns);\r\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\r\n\t\tif (groupColumns.length > 0) {\r\n\t\t\t//this.#sheet.grouping.apply();\r\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\r\n\t\t\t//const groupResult = Grouping.apply(validRecords);\r\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // 최종 렌더링 아이템\r\n\r\n\t\t\t//trace.log(\"2.============================\", groupColumns, this.#cachedVisibleRecords);\r\n\r\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // 자식 매핑 공유\r\n\t\t} else {\r\n\t\t\tthis.#cachedVisibleRecords = validRecords;\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n\tsetSorting = (columns) => {\r\n\t\tthis.#sortingColumns = columns || [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\tgetSorting = () => {\r\n\t\treturn this.#sortingColumns;\r\n\t};\r\n\r\n\tresetSorting = () => {\r\n\t\tthis.#sortingColumns = [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\r\n\t#applySorting = (indices, validRecords) => {\r\n\t\ttrace.log(new Date());\r\n\r\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\r\n\r\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\r\n\t\t\t...rule,\r\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\r\n\t\t}));\r\n\r\n\t\treturn indices.sort((idxA, idxB) => {\r\n\t\t\tconst a = validRecords[idxA];\r\n\t\t\tconst b = validRecords[idxB];\r\n\r\n\t\t\tfor (const rule of rulesWithIdx) {\r\n\t\t\t\tconst isAsc = rule.asc;\r\n\t\t\t\tconst expr = rule.expr; // 💡 등록된 expr 수식\r\n\t\t\t\tlet valA, valB;\r\n\r\n\t\t\t\t// 💡 1. expr 수식이 존재하면 ExprEngine으로 연산된 결과값을 가져옴\r\n\t\t\t\tif (expr) {\r\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\r\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 2. 일반 바인딩 필드인 경우 원시 배열에서 추출\r\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\r\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\r\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\r\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\r\n\r\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\r\n\t\t\t\tif (isEmptyA) return 1;\r\n\t\t\t\tif (isEmptyB) return -1;\r\n\r\n\t\t\t\tif (valA !== valB) {\r\n\t\t\t\t\tlet diff = 0;\r\n\r\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\r\n\t\t\t\t\t\tdiff = valA - valB;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst strA = String(valA);\r\n\t\t\t\t\t\tconst strB = String(valB);\r\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (diff !== 0) {\r\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn idxA - idxB;\r\n\t\t});\r\n\r\n\t\ttrace.log(new Date());\r\n\t};\r\n}","import { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class PreCompiler {\n\n static initializeTable(host, tbl) {\n if (!host || !tbl) return null;\n\n // 1. 기본 구조 보장 (colgroup, thead)\n PreCompiler.#ensureColgroup(tbl);\n PreCompiler.#ensureThead(tbl);\n PreCompiler.#ensureSectionTbodys(tbl);\n\n PreCompiler.#ensureRowIndicator(tbl);\n\n PreCompiler.#normalizeColAttributes(tbl);\n\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tfoot tr'));\n\n PreCompiler.#createColIndicator(tbl);\n\n // 2. 속성 정규화 (collapsed=\"true\" -> collapsible=\"true\" 보정)\n PreCompiler.#normalizeCollapsibleAttributes(tbl);\n\n // 3. 셀 커스텀 엘리먼트 생성\n PreCompiler.#generateCell(host, tbl);\n\n // 5. 초기 접힘/펼치기(expand) 버튼 및 너비 세팅\n PreCompiler.#initColExpanders(tbl);\n\n // 6. 필터 버튼 생성\n PreCompiler.#initFilterButtons(host, tbl);\n\n PreCompiler.#applyInitialCellWidths(tbl);\n //tbl.classList.add('nine-table-element');\n\n //trace.log(\"**************\", tbl.cloneNode(true));\n return tbl;\n }\n\n static #createColIndicator(tbl) {\n const thead = tbl.querySelector('thead');\n if (!thead || thead.querySelector('.col-indicator-rowgroup')) return;\n\n const tdTmpl = `<th data-col=\"@col\" class=\"col-indicator\" scope=\"col\"></th>`;\n\n // 맨 위에 인덱스용 row(tr) 삽입\n const tr = thead.insertRow(0);\n tr.setAttribute('role', 'row');\n tr.classList.add('col-indicator-rowgroup');\n tr.classList.add('collapse');\n\n const firstRow = tbl.querySelector('tbody tr');\n if (!firstRow) return;\n\n let cnt = 0;\n firstRow.querySelectorAll('th, td').forEach(td => {\n if (!td.classList.contains('dummy')) {\n const colSpan = td.colSpan || 1;\n for (let i = 0; i < colSpan; i++) {\n const html = tdTmpl.replace('@col', cnt).replace('@text', PreCompiler.#numToExcelCol(cnt++));\n tr.insertAdjacentHTML('beforeend', html);\n }\n }\n });\n\n // 🎯 colgroup의 모든 스타일 및 속성 동기화\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n tr.querySelectorAll('.col-indicator').forEach((el, i) => {\n const background = cols[i].getAttribute('background');\n if (background) {\n el.style.background = background;\n }\n });\n }\n\n // 엑셀 스타일 알파벳 변환 유틸 (A, B, C ... Z, AA, AB ...)\n static #numToExcelCol(num) {\n let text = '';\n for (let n = num; n >= 0; n = Math.floor(n / 26) - 1) {\n text = String.fromCharCode(65 + (n % 26)) + text;\n }\n return text;\n }\n\n static #ensureSectionTbodys(tbl) {\n let tbody = tbl.querySelector('tbody:not(.head):not(.foot)');\n\n if (!tbody) return;\n\n tbody.classList.add('body');\n\n // 🎯 이미 존재하지 않을 때만 생성\n if (!tbl.querySelector('tbody.head')) {\n const headTbody = document.createElement('tbody');\n headTbody.classList.add('head');\n tbody.before(headTbody);\n }\n\n if (!tbl.querySelector('tbody.foot')) {\n const footTbody = document.createElement('tbody');\n footTbody.classList.add('foot');\n tbody.after(footTbody);\n }\n }\n\n static #ensureColgroup(tbl) {\n let colgroup = tbl.querySelector('colgroup');\n if (!colgroup) {\n colgroup = document.createElement('colgroup');\n tbl.prepend(colgroup);\n }\n\n // 🎯 <col> 엘리먼트 자체가 없다면 행 기준으로 생성\n if (colgroup.querySelectorAll('col').length === 0) {\n const firstRow = tbl.querySelector('tbody tr');\n let colCount = 1;\n if (firstRow) {\n colCount = Array.from(firstRow.querySelectorAll('th, td')).reduce((sum, cell) => {\n return sum + (parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1);\n }, 0);\n }\n colCount = Math.max(colCount, 1);\n\n for (let i = 0; i < colCount; i++) {\n const col = document.createElement('col');\n colgroup.appendChild(col);\n }\n }\n\n // 🎯 col 속성 및 너비 정리는 별도 함수로 분리\n //PreCompiler.#normalizeColAttributes(tbl);\n }\n\n // 🎯 <col>들의 data-col, width, style.width 속성 정리를 전담하는 메서드\n static #normalizeColAttributes(tbl) {\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n if (cols.length === 0) return;\n\n const containerWidth = tbl.clientWidth || 0;\n const defaultWidth = Math.max(Math.floor(containerWidth / cols.length), 100);\n\n cols.forEach((col, i) => {\n // 1. data-col 인덱스 보장\n if (!col.hasAttribute('data-col')) {\n col.setAttribute('data-col', i);\n }\n\n // 2. width 속성 및 style.width 정규화\n const width = col.getAttribute('width') || parseInt(col.style.width, 10) || defaultWidth;\n col.setAttribute('width', width);\n\n const widthVal = String(width).includes('px') ? width : `${width}px`;\n col.style.width = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n if (tbl.querySelector('thead')) return;\n\n const thead = document.createElement('thead');\n const colgroup = tbl.querySelector('colgroup');\n\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n }\n\n static #normalizeCollapsibleAttributes(tbl) {\n const headers = tbl.querySelectorAll('thead th, thead td');\n headers.forEach(cell => {\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n if (isCollapsed && cell.getAttribute('collapsible') !== 'true') {\n cell.setAttribute('collapsible', 'true');\n }\n });\n }\n\n static #generateCell(host, $tbl) {\n\n const targetAttributes = ['data-bind', 'data-expr', 'type'];\n let autoIdCounter = 0;\n\n $tbl.querySelectorAll('tbody th, tbody td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type') || \"renderer\";\n const tagName = `cell-${cellType}`;\n\n const $datalist = $cell.querySelector(\"datalist\");\n\n if ($datalist) {\n let l = [];\n $datalist.querySelectorAll('option').forEach($option => {\n l.push({\n k: $option.getAttribute(\"k\"),\n v: $option.getAttribute(\"v\"),\n });\n });\n\n // 🎯 1. 절대 겹치지 않는 유니크한 가상 함수 이름 생성\n const uniqueFuncName = `__ds_${Date.now()}_${++autoIdCounter}`;\n\n // 🎯 2. 호스트(NineTable)에 해당 데이터를 반환하는 클로저 함수 등록\n if (host) {\n host[uniqueFuncName] = () => l;\n }\n\n // 🎯 3. 셀에 data-source 자동 장착 (정규식/세터 스캔기가 알아서 캐치함)\n $cell.setAttribute(\"data-source\", `host.${uniqueFuncName}()`);\n\n // 🎯 4. 사용이 끝난 정적 datalist 엘리먼트는 DOM에서 제거\n $datalist.remove();\n }\n\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr));\n }\n\n // 💡 2. 기타 속성들 중 표현식이 포함된 경우 프리컴파일\n Array.from($cell.attributes).forEach(attr => {\n if (['data-bind', 'data-expr', 'cell-type'].includes(attr.name)) return;\n if (attr.value.includes(\"data.\") || attr.value.includes(\"host.\")) {\n $cell.setAttribute(attr.name, host.exprEngine.precompile(attr.value));\n }\n });\n\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')}></${tagName}>`;\n $cell.setAttribute('tabindex', '0');\n });\n\n $tbl.querySelectorAll('thead th, thead td, tfoot th, tfoot td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type');\n if (cellType) {\n const originalContent = $cell.innerHTML;\n const tagName = `cell-${cellType}`;\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')} content=\"${originalContent}\"></${tagName}>`;\n }\n });\n }\n\n static #initFilterButtons(host, tbl) {\n const hostFilter = host.getAttribute('filtering') === 'true';\n const tableFilter = tbl.getAttribute('filtering') === 'true';\n\n // 🎯 인덱스 행을 제외한 실제 헤더 셀들만 타겟팅\n tbl.querySelectorAll('thead tr:not(.col-indicator-rowgroup) th, thead tr:not(.col-indicator-rowgroup) td').forEach(cell => {\n const finalFiltering = cell.getAttribute('filtering') === 'true' || tableFilter || hostFilter;\n\n cell.setAttribute('filtering', finalFiltering ? 'true' : 'false');\n\n if (finalFiltering) {\n cell.appendChild(document.createElement('nine-table-filter-button'));\n }\n });\n }\n\n static #initColExpanders(tbl) {\n /** 작동하나? */\n tbl.querySelectorAll('thead th, thead td').forEach(cell => {\n const isCollapsible = cell.getAttribute('collapsible') === 'true' || cell.getAttribute('expandable') === 'true';\n if (!isCollapsible) return;\n\n trace.log(\"11.*******************************\", cell.dataset.col);\n\n const colIndex = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const col = tbl.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n\n trace.log(\"11.*******************************\", col);\n\n const currentWidth = col ? (parseInt(col.getAttribute('width'), 10) || 100) : 100;\n\n if (!cell.dataset.expandWidth || parseInt(cell.dataset.expandWidth, 10) <= COLLAPSED_WIDTH) {\n cell.dataset.expandWidth = String(currentWidth > COLLAPSED_WIDTH ? currentWidth : 100);\n }\n\n let expandBtn = cell.querySelector('nine-table-col-expand');\n if (!expandBtn) {\n expandBtn = document.createElement('nine-table-col-expand');\n cell.insertBefore(expandBtn, cell.firstChild);\n }\n\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n expandBtn.classList.add('collapsed');\n expandBtn.classList.remove('expand');\n expandBtn.setAttribute('collapsed', 'true');\n cell.style.color = 'transparent';\n\n const targetWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n if (!isNaN(colIndex)) {\n for (let i = 0; i < colSpan; i++) {\n const targetCol = tbl.querySelector(`colgroup col[data-col=\"${colIndex + i}\"]`);\n if (targetCol) {\n targetCol.setAttribute('width', targetWidth);\n targetCol.style.width = `${targetWidth}px`;\n }\n }\n }\n } else {\n expandBtn.classList.remove('collapsed');\n expandBtn.classList.add('expand');\n expandBtn.setAttribute('collapsed', 'false');\n cell.style.color = '';\n }\n });\n }\n\n static #ensureRowIndicator(tbl, host) {\n // 1. colgroup에 인디케이터용 <col> 추가\n const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 0;\n\n const colgroup = tbl.querySelector('colgroup');\n\n //if (colgroup && !colgroup.querySelector('col.row-indicator-col')) {\n const col = document.createElement('col');\n //col.className = 'row-indicator-col';\n col.setAttribute('fixed', 'left');\n col.setAttribute('width', w);\n col.style.width = `${w}px`;\n colgroup.prepend(col);\n //}\n\n // 2. thead, tbody, tfoot 각 섹션별로 첫 번째 tr에 인디케이터 생성 및 rowSpan 부여\n //const sections = tbl.querySelectorAll('thead, tbody, tfoot');\n\n tbl.querySelectorAll('thead, tbody, tfoot').forEach(section => {\n const rows = Array.from(section.querySelectorAll('tr'));\n if (rows.length === 0) return;\n\n const firstTr = rows[0];\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n //indicatorCell.setAttribute('filtering', 'false');\n\n // 💡 섹션 내 행이 여러 개면(멀티 라인 템플릿 등) 전체를 아우르도록 rowSpan 설정\n if (rows.length > 1) {\n indicatorCell.rowSpan = rows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\n }\n\n static #applyInitialCellWidths(tbl) {\n // 🎯 컬럼 기준이 아닌 셀(th, td) 기준으로 순회하여 colspan 반영\n tbl.querySelectorAll('th[data-col], td[data-col]').forEach(cell => {\n\n trace.log(cell);\n\n const startColIdx = parseInt(cell.getAttribute('data-col'), 10);\n if (isNaN(startColIdx)) return;\n\n // 셀의 실제 colspan 값 추출 (기본값 1)\n const colSpan = parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1;\n let totalWidth = 0;\n\n // colspan 만큼 다음 컬럼들의 너비를 누적 합산\n for (let i = 0; i < colSpan; i++) {\n const targetIdx = startColIdx + i;\n const col = tbl.querySelector(`colgroup col[data-col=\"${targetIdx}\"]`);\n if (col) {\n totalWidth += parseInt(col.getAttribute('width'), 10) || 100;\n }\n }\n\n if (totalWidth > 0) {\n const widthVal = `${totalWidth}px`;\n cell.style.width = widthVal;\n cell.style.minWidth = widthVal;\n cell.style.maxWidth = widthVal;\n }\n });\n }\n}","// NineTableSheet.js (필터 버튼 레이아웃 및 패딩 스타일 완벽 통합본)\n\nimport { trace } from \"@nopeer\";\nimport './nine-table-hscrollbar.js';\nimport './nine-table-vscrollbar.js';\nimport { RowManager } from './core/RowManager.js';\nimport { TableCompiler } from \"./core/TableCompiler.js\";\nimport { CellSelection } from \"@/ui/cell-manager/CellSelection.js\";\nimport { CellNavigation } from \"@/ui/cell-manager/CellNavigation.js\";\n\nimport { ColResizer } from \"@/ui/col/ColResizer.js\";\nimport { ColMover } from \"@/ui/col/ColMover.js\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nimport { Filtering } from \"@/data/Filtering.js\";\nimport {Grouping, GroupingManager} from \"@/data/Grouping.js\";\nimport { Sorting } from \"@/data/Sorting.js\";\nimport { SheetView } from \"@/data/SheetView.js\";\n\nimport { PreCompiler } from \"@/ui/layout/core/PreCompiler.js\";\n\nexport class NineTableSheet extends HTMLElement {\n #index;\n #host;\n #rowManager;\n #cellSelection;\n #cellNavigation;\n #colResizer;\n #colMover;\n #colFix;\n #sorting;\n #filtering;\n #grouping;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n static SCROLLBAR_SIZE = 16;\n\n constructor() {\n super();\n trace.log(\"11111\")\n this.#rowManager = new RowManager(this);\n trace.log(\"222\")\n this.#host = this.getRootNode().host;\n trace.log(\"333\")\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get index() { return this.#index; }\n get colResizer() { return this.#colResizer; }\n get filtering() { return this.#filtering; }\n get grouping() { return this.#grouping; }\n get colMover() { return this.#colMover; }\n get colFix() { return this.#colFix; }\n get rowManager() { return this.#rowManager; }\n get selection() { return this.#cellSelection; }\n get navigation() { return this.#cellNavigation; }\n get templateLength() { return this.#source.tbody.tr.length || 0; }\n\n get elements() { return this.#elements; }\n\n get isAutoFitCol() {\n const attrTrue = this.getAttribute('auto-fit-col') === 'true' || this.#host?.getAttribute('auto-fit-col') === 'true';\n const sourceTableTrue = this.#source.table?.getAttribute('auto-fit-col') === 'true';\n return attrTrue || sourceTableTrue;\n }\n\n get sourceTable() {\n return this.#source.table;\n }\n\n get source() {\n return this.#source;\n }\n\n get #isSimple() {\n return this.#host.hasAttribute('simple') || this.#host.getAttribute('theme') === 'simple';\n }\n\n recompileAndRefresh() {\n if (!this.#source.table) return;\n\n TableCompiler.recompile(this.#source.table);\n\n ['left', 'right', 'body'].forEach(type => {\n ['header', 'body', 'footer'].forEach(section => {\n const container = this.querySelector(`.ng-sheet-${section} .ng-container-${type}`);\n if (!container) return;\n container.querySelectorAll('table').forEach(tbl => tbl.remove());\n });\n });\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n requestAnimationFrame(() => {\n this.#updateContainerWidths();\n this.#rowManager?.refresh();\n });\n }\n\n refreshLayout() {\n if (!this.classList.contains('active') || !this.#source.table) return;\n\n requestAnimationFrame(() => {\n\n this.#updateContainerWidths();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n this.#adjustOverlay();\n\n this.#colResizer?.refreshLayout();\n\n this.#rowManager?.refresh();\n });\n }\n\n #adjustOverlay = () => {\n // 3분할된 영역 중 중앙(body) 또는 좌측 영역의 thead를 타겟팅하여 높이 측정\n const $thead = this.querySelector('.ng-container-body thead');\n const $overlay = this.querySelector('.ng-nodata-overlay');\n $overlay.style.top = `${$thead.offsetHeight}px`;\n }\n\n get view() {\n if (!this.#view && this.#host?.data) {\n this.#view = new SheetView(this);\n }\n return this.#view;\n }\n\n invalidate = () => {\n\n this.view.refresh();\n\n this.#rowManager.refresh(true);\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n }\n };\n\n autoFit = (enable = true) => {\n requestAnimationFrame(() => {\n this.#autoFit?.(enable);\n });\n };\n\n #autoFit = (enable = true) => {\n trace.log(\"autoFit\", this);\n\n const container = this.querySelector('.ng-sheet-body .ng-container-body');\n if (!container) return;\n\n const tables = container.querySelectorAll('table');\n const firstColgroup = this.querySelector('.ng-sheet-header .ng-container-body table colgroup');\n if (!firstColgroup) return;\n\n if (enable) {\n this.setAttribute('auto-fit-col', 'true');\n const containerWidth = container.clientWidth;\n if (containerWidth <= 0) return;\n\n let totalOriginalWidth = 0;\n const colList = [];\n\n // 1단계: 접힌 컬럼(16px 고정)과 일반 컬럼을 분리해서 수집\n firstColgroup.querySelectorAll('col').forEach(col => {\n const globalColIndex = col.getAttribute('data-col');\n const headerCell = this.querySelector(`.ng-sheet-header th[data-col=\"${globalColIndex}\"]`);\n const isCollapsed = headerCell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n colList.unshift({ globalColIndex, width: 16, isCollapsed: true });\n trace.log(`[AutoFit Col] Index ${globalColIndex}: COLLAPSED (forced 16px)`);\n } else {\n const w = parseInt(col.getAttribute('width'), 10) || 100;\n colList.push({ globalColIndex, width: w, isCollapsed: false });\n totalOriginalWidth += w;\n trace.log(`[AutoFit Col] Index ${globalColIndex}: NORMAL (original width: ${w}px)`);\n }\n });\n\n trace.log(`[AutoFit] Total Original Width of Normal Cols: ${totalOriginalWidth}px`);\n\n // 접힌 컬럼들이 차지하는 총 너비 계산\n const collapsedTotalWidth = colList\n .filter(c => c.isCollapsed)\n .reduce((sum, c) => sum + c.width, 0);\n\n // 남은 컨테이너 너비를 펼쳐진 컬럼들에게만 배분 (오류 수정)\n const availableWidth = Math.max(0, containerWidth - collapsedTotalWidth);\n trace.log(`[AutoFit] Collapsed Total Width: ${collapsedTotalWidth}px | Available Width for Normal Cols: ${availableWidth}px`);\n\n if (totalOriginalWidth > 0 && colList.length > 0) {\n let allocatedTotal = 0;\n\n const calculatedCols = colList.map(item => {\n if (item.isCollapsed) {\n return { globalColIndex: item.globalColIndex, remainder: 0, width: 16 };\n }\n\n // 연산자 오류 수정 (* 와 - 추가)\n const exactWidth = (item.width * availableWidth) / totalOriginalWidth;\n const baseWidth = Math.max(30, Math.floor(exactWidth));\n allocatedTotal += baseWidth;\n return {\n globalColIndex: item.globalColIndex,\n remainder: exactWidth - Math.floor(exactWidth),\n width: baseWidth\n };\n });\n\n // 잔여 픽셀 보정 (오류 수정)\n let remainderPixels = availableWidth - allocatedTotal;\n trace.log(`[AutoFit] Initial Allocated Total: ${allocatedTotal}px | Remainder Pixels to distribute: ${remainderPixels}`);\n\n const uncollapsedCols = calculatedCols.filter(c => !colList.find(item => item.globalColIndex === c.globalColIndex)?.isCollapsed);\n\n if (remainderPixels > 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => b.remainder - a.remainder);\n for (let i = 0; i < remainderPixels; i++) {\n uncollapsedCols[i % uncollapsedCols.length].width += 1;\n }\n } else if (remainderPixels < 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => a.remainder - b.remainder);\n for (let i = 0; i < Math.abs(remainderPixels); i++) {\n const target = uncollapsedCols[i % uncollapsedCols.length];\n if (target.width > 30) target.width -= 1;\n }\n }\n\n const finalSumWidth = calculatedCols.reduce((sum, c) => sum + c.width, 0);\n trace.log(`[AutoFit Verification] Target Container Width: ${containerWidth}px | Sum of All Calculated Cols: ${finalSumWidth}px`);\n\n if (containerWidth !== finalSumWidth) {\n trace.log(`⚠️ [AutoFit Mismatch Warning!] 오차 발생: ${containerWidth - finalSumWidth}px 차이가 납니다.`);\n } else {\n trace.log(`✅ [AutoFit Success] 완벽하게 일치합니다!`);\n }\n\n // 최종 적용\n calculatedCols.forEach(({ globalColIndex, width }) => {\n trace.log(`[AutoFit Apply] Col Index ${globalColIndex} -> ${width}px`);\n this.#colResizer?.setColumnWidth(globalColIndex, width, 'body');\n });\n }\n } else {\n this.removeAttribute('auto-fit-col');\n }\n\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n generate = ($table, index) => {\n\n this.#index = index;\n\n PreCompiler.initializeTable(this.#host, $table);\n\n trace.log(\"=======\", $table);\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n this.#renderSplitContainers();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#updateContainerWidths();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#syncHeaderAndFooterHeights();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //\n this.#initRowHoverEvent();\n\n ['left', 'body', 'right'].forEach(type => {\n const prefix = `.ng-container-${type}`;\n this.#elements[type] = {\n thead: this.querySelector(`${prefix} thead`),\n tbody: {\n head: this.querySelector(`${prefix} tbody.head`),\n body: this.querySelector(`${prefix} tbody.body`),\n foot: this.querySelector(`${prefix} tbody.foot`),\n },\n tfoot: this.querySelector(`${prefix} tfoot`),\n };\n });\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //trace.log(\"********1\", this.#source.table)\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar').refresh();\n }\n\n //this.#grouping = new GroupingManager(this);\n this.#grouping.initialize();\n\n this.loaded = true;\n };\n\n\n #updateContainerWidths = () => {\n const isAutoFit = this.isAutoFitCol;\n\n ['left', 'right', 'body'].forEach(type => {\n const containers = this.querySelectorAll(`.ng-container-${type}`);\n if (containers.length === 0) return;\n\n const firstTable = containers[0].querySelector('table');\n if (!firstTable) return;\n\n let width = 0;\n firstTable.querySelectorAll('col').forEach(col => {\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) width += w;\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n if (type === 'body') {\n container.style.flex = `1`;\n tables.forEach(tbl => {\n //tbl.style.width = isAutoFit ? `100%` : `${width}px`;\n //tbl.style.minWidth = isAutoFit ? `100%` : `${width}px`;\n });\n } else {\n container.style.flex = `0 0 ${width}px`;\n container.style.width = `${width}px`;\n container.style.minWidth = `${width}px`;\n container.style.maxWidth = `${width}px`;\n tables.forEach(tbl => {\n //tbl.style.width = `${width}px`;\n //tbl.style.minWidth = `${width}px`;\n });\n }\n });\n });\n };\n\n #renderSplitContainers = () => {\n const colTypes = [\n { selector: '.ng-container-left', type: 'left' },\n { selector: '.ng-container-body', type: null },\n { selector: '.ng-container-right', type: 'right' }\n ];\n\n colTypes.forEach(({ selector, type }) => {\n this.querySelector(`.ng-sheet-body ${selector}`).appendChild(this.#createSplitTable(type));\n });\n };\n\n #createSplitTable = (targetFixedType) => {\n\n const $tbl = this.#source.table.cloneNode(true);\n\n if (targetFixedType === 'left') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"left\") $el.remove();\n });\n } else if (targetFixedType === 'right') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"right\") $el.remove();\n });\n } else {\n $tbl.querySelectorAll(\"[fixed=left], [fixed=right]\").forEach($el => {\n $el.remove();\n });\n }\n\n return $tbl;\n };\n\n getRowHeight = () => {\n return this.#rowManager.getRowHeight();\n };\n\n scrollToX = (scrollLeft) => {\n const bodyContainer = this.querySelector('.ng-sheet-body .ng-container-body');\n if (bodyContainer) bodyContainer.scrollLeft = scrollLeft;\n };\n\n scrollToY = (scrollTop) => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (bodyViewport) bodyViewport.scrollTop = scrollTop;\n };\n\n #init = () => {\n trace.log(\"11111*****************\");\n\n this.#render();\n\n this.#cellSelection = new CellSelection(this);\n this.#cellNavigation = new CellNavigation(this);\n this.#colResizer = new ColResizer(this);\n this.#colMover = new ColMover(this);\n this.#colFix = new ColFixManager(this);\n\n this.#view = new SheetView(this);\n this.#filtering = new Filtering(this);\n this.#grouping = new GroupingManager(this);\n\n //trace.log(\"----------------------\")\n //trace.log(\"Is GroupingManager instance?\", this.#grouping instanceof GroupingManager); // true가 나와야 정상\n //trace.log(\"Grouping keys:\", Object.keys(this.#grouping)); // 또는 내부 속성 확인\n\n if (!this.#isSimple) {\n this.#sorting = new Sorting(this);\n }\n\n this.#elements.mainBody.addEventListener('scroll', () => {\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n trace.log(\"11111*****************\");\n const sbSize = NineTableSheet.SCROLLBAR_SIZE;\n trace.log(\"2222*****************\");\n this.innerHTML = `\n <div class=\"ng-sheet-body\">\n <div class=\"ng-sheet-body-content\">\n <div class=\"ng-container-left\"></div>\n <div class=\"ng-container-body\"></div>\n <div class=\"ng-container-right\"></div>\n </div>\n <div class=\"ng-virtual-height-holder\"></div>\n </div>\n\n <div class=\"ng-nodata-overlay\">Data Not Found</div>\n\n <!-- [Grid Row 1, Col 2] 세로 스크롤바 -->\n <nine-table-vscrollbar></nine-table-vscrollbar>\n\n <!-- [Grid Row 2, Col 1] 가로 스크롤바 -->\n <nine-table-hscrollbar></nine-table-hscrollbar>\n\n <!-- [Grid Row 2, Col 2] 우하단 엣지 -->\n <div class=\"ng-scroll-edge\"></div>\n \n <!-- 리사이저 및 드래그 패널들 -->\n <div class=\"ng-col-resizer-panel\">\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n </div>\n \n <div class=\"ng-col-mover-grip\"></div>\n <div class=\"ng-col-mover-indi\"></div>\n `;\n\n //let fixedHeight = this.#sheet.querySelector('.ng-container-body thead').offsetHeight + this.#sheet.querySelector('.ng-container-body tfoot').offsetHeight;\n trace.log(\"3333*****************\");\n this.#elements = {\n mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n hscrollbar: this.querySelector('nine-table-hscrollbar'),\n vscrollbar: this.querySelector('nine-table-vscrollbar'),\n content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n }\n trace.log(\"444*****************\");\n };\n\n #syncHeaderAndFooterHeights = () => {\n trace.log(\"**********************\", \"#syncHeaderAndFooterHeights\");\n\n const leftTable = this.querySelector('.ng-container-left table');\n const bodyTable = this.querySelector('.ng-container-body table');\n const rightTable = this.querySelector('.ng-container-right table');\n\n // 1. 헤더(thead) 행 높이 싱크 (인덱스 행 제외)\n const leftHeaderRows = Array.from(leftTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const bodyHeaderRows = Array.from(bodyTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const rightHeaderRows = Array.from(rightTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n\n this.#applyMaxHeights(leftHeaderRows, bodyHeaderRows, rightHeaderRows);\n\n // 2. 푸터(tfoot) 행 높이 싱크\n const leftFooterRows = Array.from(leftTable.querySelectorAll('tfoot tr'));\n const bodyFooterRows = Array.from(bodyTable.querySelectorAll('tfoot tr'));\n const rightFooterRows = Array.from(rightTable.querySelectorAll('tfoot tr'));\n\n this.#applyMaxHeights(leftFooterRows, bodyFooterRows, rightFooterRows);\n };\n\n// 공통 최대 높이 적용 헬퍼 메서드\n #applyMaxHeights = (leftRows, bodyRows, rightRows) => {\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n };\n\n #initRowHoverEvent = () => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n let activeRowIndex = null;\n\n // 마우스 진입 (모든 컨테이너 탐색)\n bodyViewport.addEventListener('mouseover', (e) => {\n const tr = e.target.closest('tr');\n if (!tr || !tr.dataset.row && tr.dataset.row !== '0') return;\n\n const rowIndex = tr.dataset.row;\n if (activeRowIndex === rowIndex) return;\n activeRowIndex = rowIndex;\n\n // 좌측, 본문, 우측 컨테이너에서 동일한 data-row를 가진 tr들을 모두 찾아 .hover 부여\n bodyViewport.querySelectorAll(`tr[data-row=\"${rowIndex}\"]`).forEach($tr => {\n $tr.classList.add('hover');\n });\n });\n\n // 마우스 이탈\n bodyViewport.addEventListener('mouseout', (e) => {\n const tr = e.target.closest('tr');\n if (!tr) return;\n\n // 현재 영역을 완전히 벗어났을 때만 전체 hover 제거\n const relatedTarget = e.relatedTarget;\n if (tr.contains(relatedTarget)) return;\n\n bodyViewport.querySelectorAll('tr.hover').forEach($tr => {\n $tr.classList.remove('hover');\n });\n activeRowIndex = null;\n });\n }\n\n disconnectedCallback() {\n this.#colResizer?.destroy();\n this.#colMover?.destroy();\n this.innerHTML = '';\n }\n}\n\nif (!customElements.get('nine-table-sheet')) {\n customElements.define('nine-table-sheet', NineTableSheet);\n}","import { trace } from \"@nopeer\";\nimport '@/ui/layout/nine-table-sheets.js';\nimport '@/ui/layout/nine-table-sheets-footer.js';\nimport '@/ui/layout/nine-table-toolbar.js';\nimport { NineTableSheet } from \"@/ui/layout/nine-table-sheet.js\";\n\nexport class LayoutManager {\n #host;\n\n constructor(owner) {\n this.#host = owner;\n this.#init();\n }\n\n #init = () => {\n this.#render();\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }).observe(this.#host);\n }\n\n set loading(val) {\n if (!!val) {\n this.#host.classList.add(\"loading\");\n } else {\n this.#host.classList.remove(\"loading\");\n }\n }\n\n #applyAutoHeight = () => {\n const activeSheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet.active'));\n if (activeSheets.length === 0) return;\n\n const maxDisplayRows = parseInt(this.#host.getAttribute('max-display-row'), 10) || 10;\n const maxRowHeight = Math.max(...activeSheets.map(sheet => sheet.getRowHeight()));\n\n const toolbarEl = this.#host.shadowRoot.querySelector('nine-table-toolbar');\n const footerEl = this.#host.shadowRoot.querySelector('nine-table-sheets-footer');\n\n const toolbarHeight = toolbarEl ? toolbarEl.getBoundingClientRect().height : 0;\n const footerHeight = footerEl ? footerEl.getBoundingClientRect().height : 0;\n const extraPadding = NineTableSheet.SCROLLBAR_SIZE;\n\n const calculatedHeight = (maxDisplayRows * maxRowHeight) + toolbarHeight + footerHeight + extraPadding;\n\n this.#host.style.height = `${calculatedHeight}px`;\n };\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n const sheetCount = rawTables.length;\n\n const sheetsHtml = rawTables.map((tbl, idx) => {\n const className = idx === 0 ? 'active' : '';\n const sheetId = tbl.id || `sheet${idx + 1}`;\n\n const sheetTag = `<nine-table-sheet class=\"${className}\" data-index=\"${idx}\" data-sheet-id=\"${sheetId}\" id=\"${sheetId}\"></nine-table-sheet>`;\n const splitterTag = idx < sheetCount - 1 ? `<nine-splitter class=\"h\" data-split-index=\"${idx}\"></nine-splitter>` : '';\n return sheetTag + splitterTag;\n }).join('');\n\n // 1. 공통 파일명 배열 정의\n const cssFiles = ['layout.css', 'nine-table-sheet.css', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table'];\n // 2. npm 패키지 CSS 배열 생성\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}\";`\n );\n\n // 3. 커스텀 CSS 배열 생성\n const customCssImports = [];\n if (nine.cssPath) {\n cssFiles.forEach(file => {\n customCssImports.push(`@import \"${nine.cssPath}/${file}\";`);\n });\n }\n\n this.#host.shadowRoot.innerHTML = `\n <style>\n ${[...npmCssImports, ...customCssImports].join('\\n')}\n </style>\n \n <nine-table-toolbar></nine-table-toolbar>\n\n <nine-table-body>\n <nine-table-summary></nine-table-summary>\n <div class=\"ng-loading-bar\"></div>\n <nine-table-sheets>\n <nine-table-sheets-body>\n ${sheetsHtml}\n </nine-table-sheets-body>\n <nine-table-sheets-footer></nine-table-sheets-footer>\n </nine-table-sheets>\n <nine-table-analysis></nine-table-analysis>\n </nine-table-body>\n <nine-table-footer></nine-table-footer>\n `;\n\n /**\n * <div class=\"nine-tab-bar\">${tabsHtml}</div>\n * <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n */\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($el, idx) => {\n\n if (rawTables[idx]) {\n setTimeout(() => {\n $el.generate(rawTables[idx], idx);\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n });\n }\n });\n };\n}","import { trace } from \"@nopeer\";\n\nexport class ExprEngine {\n #host;\n #fields;\n #exprCache = new Map(); // 💡 통합된 단일 캐시로 모든 컴파일된 함수 관리\n\n constructor(host) {\n this.#host = host;\n this.#fields = host.fields.get();\n }\n\n /**\n * 🎯 표현식 내의 data.fieldName을 원시 배열 인덱스 접근(rowItem.v[idx])으로 변환\n */\n rewriteExpr(expr) {\n\n if (!expr || !this.#fields.length) return expr;\n\n return expr.replace(/data\\.([a-zA-Z_$][\\w$]*)/g, (match, fieldName) => {\n const idx = this.#fields.indexOf(fieldName);\n return idx >= 0 ? `rowItem.v[${idx}]` : match;\n });\n }\n\n /**\n * 🎯 셀 또는 컬럼 정의에 선언된 expr 프리컴파일\n */\n precompile(expr) {\n if (!expr) return expr;\n return this.rewriteExpr(expr);\n }\n\n /**\n * 🎯 표현식 평가 및 실행 (통합 캐싱)\n */\n evaluate(expr, rowItem, row = 0) {\n if (expr === undefined || expr === null) return \"\";\n\n //trace.log(expr, rowItem, this.#exprCache);\n\n try {\n const trimmedExpr = String(expr).trim();\n const compiledExpr = this.rewriteExpr(trimmedExpr);\n\n // 💡 함수 호출, 데이터 참조, 연산식이 포함된 경우 통합 평가 및 캐싱\n if (compiledExpr.includes(\"data.\") || compiledExpr.includes(\"rowItem.v\") || compiledExpr.includes(\"host.\") || compiledExpr.includes(\"(\")) {\n let evalFn = this.#exprCache.get(compiledExpr);\n\n if (!evalFn) {\n evalFn = new Function('rowItem', 'row', 'host', `\n const data = rowItem;\n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n this.#exprCache.set(compiledExpr, evalFn);\n }\n\n return evalFn(rowItem, row, this.#host);\n }\n\n // 단순 리터럴 문자열인 경우\n return compiledExpr;\n } catch (e) {\n //console.error(\"ExprEngine evaluation error:\", expr, e);\n return expr;\n }\n }\n}","import { trace } from \"@nopeer\";\nimport { ngDataManager } from '@/data/ngDataManager.js';\nimport { fields } from \"@/data/Fields.js\";\nimport { LayoutManager } from '@/ui/layout/core/LayoutManager.js';\nimport { ExprEngine } from \"@/core/ExprEngine.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #templateCnt = 0; // 🎯 로딩 상태 플래그\n\n constructor() {\n super();\n\n this.#shadowRoot = this.attachShadow({ mode: 'open' });\n this.#dataManager = new ngDataManager(this);\n }\n\n connectedCallback() {\n setTimeout(() => {\n this.#templateCnt = this.querySelectorAll(\"table\")?.length;\n\n this.fields = new fields(this);\n this.exprEngine = new ExprEngine(this);\n\n this.#bindDynamicSetters();\n\n this.#layoutManager = new LayoutManager(this);\n\n this.#dispatchLoad();\n //this.dispatchEvent(new CustomEvent('load', { bubbles: true, detail: { target: this } }));\n });\n }\n\n disconnectedCallback() {\n trace.log('NineTable disconnected.');\n }\n\n #dispatchLoad = () => {\n // 🎯 2. 변수명 오타 수정 (#sheetCnt -> #templateCnt)\n //trace.log(\"*********************** template count:\", this.#templateCnt);\n\n let checkCount = 0;\n const maxChecks = 50; // 최대 5초 대기 (100ms * 50)\n\n const checkTimer = setInterval(() => {\n checkCount++;\n\n const sheets = this.shadow.querySelectorAll('nine-table-sheet');\n //trace.log(\"Current mounted sheets:\", sheets.length);\n\n if (checkCount >= maxChecks) {\n clearInterval(checkTimer);\n }\n\n if (sheets.length >= this.#templateCnt) {\n let loadSheetCnt = 0;\n sheets.forEach($sheet => {\n if ($sheet.loaded) loadSheetCnt++;\n });\n\n //trace.log('Checking sheet loaded status:', loadSheetCnt, '/', this.#templateCnt);\n\n if (loadSheetCnt >= this.#templateCnt) {\n clearInterval(checkTimer);\n this.loaded = true;\n this.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.LOAD, { bubbles: true, detail: { target: this } }));\n }\n }\n }, 100);\n }\n\n\n // 🎯 공통 데이터 & API 접근자\n get shadow() { return this.#shadowRoot; }\n get dataManager() { return this.#dataManager; }\n get data() { return this.#dataManager.data; }\n get row() { return this.#dataManager.row; }\n\n setData(records) {\n this.#dataManager.data.set(records);\n this.refresh();\n }\n\n refresh() {\n this.activeSheet?.invalidate();\n }\n\n // 🎯 섀도우 돔 내부에서 로딩바 요소를 안전하게 캐싱\n\n\n set loading(val) {\n this.#layoutManager.loading = val;\n }\n\n /**\n * 랜더링 이후에 생기는 data-source 처리기능\n */\n rerenderer() {\n\n this.activeSheet?.querySelectorAll(\"tbody.body th,tbody.body td\").forEach(($cell) => {\n const customComp = Array.from($cell.children).find($el => {\n return $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.rerenderer === 'function'\n });\n\n customComp?.rerenderer();\n })\n }\n\n // 시트 제어 API\n sheet = (idOrIndex) => {\n if (idOrIndex === null || idOrIndex < 0) return this.activeSheet;\n const sheets = Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n\n if (typeof idOrIndex === 'number') return sheets[idOrIndex] || null;\n if (typeof idOrIndex === 'string') {\n return this.shadow.querySelector(`nine-table-sheet#${idOrIndex}, nine-table-sheet[data-sheet-id=\"${idOrIndex}\"]`) || null;\n }\n return sheets[0] || null;\n }\n\n get sheets() {\n return Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n }\n\n get activeSheet() {\n return this.shadow.querySelector('nine-table-sheet.active') || null;\n }\n\n #bindDynamicSetters() {\n const extractedMethodNames = new Set();\n\n this.querySelectorAll('[data-source]').forEach(el => {\n const dataSource = el.getAttribute('data-source');\n if (!dataSource) return;\n\n // 💡 [수정] 뒤에 여멀림 괄호 '('가 오는 형태만 매칭하여 'DEPART' 같은 파라미터는 배제!\n const matches = dataSource.matchAll(/(?:host\\.)?([a-zA-Z0-9_$]+)\\s*\\(/g);\n for (const match of matches) {\n const name = match[1];\n if (name && name !== 'host') {\n extractedMethodNames.add(name);\n }\n }\n });\n\n // 추출된 메서드 이름별로 NineTable 인스턴스에 동적 세터 생성\n extractedMethodNames.forEach(methodName => {\n let internalValue = null;\n\n Object.defineProperty(this, methodName, {\n set: (newValue) => {\n internalValue = newValue;\n\n // 값이 대입되는 순간 그리드 자동 갱신\n //this.refresh();\n this.rerenderer();\n },\n get: () => internalValue,\n configurable: true,\n enumerable: true\n });\n });\n }\n\n execute = (fn) => {\n this.loading = true;\n setTimeout(() => {\n try {\n fn.call(this);\n } finally {\n this.loading = false;\n }\n })\n }\n}\n\nif (!customElements.get('nine-table')) {\n customElements.define('nine-table', NineTable);\n}\n\nif (!customElements.get('nine-table-simple')) {\n customElements.define('nine-table-simple', class extends NineTable {\n connectedCallback() {\n // simple 태그로 생성되면 자동으로 mode=\"simple\" 속성 부여\n this.setAttribute('theme', 'simple');\n\n super.connectedCallback();\n }\n });\n}","export class BasicCellElement extends HTMLElement {\r\n\r\n\tstatic _styleCache = new Map();\r\n\tstatic _customStyleCache = new Map(); // 👈 커스텀 스타일용 캐시 추가\r\n\r\n\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tapplyBaseStyle() {\r\n\t\tconst className = this.constructor.name;\r\n\r\n\t\treturn;\r\n\t\t// 1. 기본 스타일 시트 처리 (캐싱 O)\r\n\t\tif (!ngElement._styleCache.has(className)) {\r\n\t\t\tconst baseSheet = new CSSStyleSheet();\r\n\t\t\tngElement._styleCache.set(className, baseSheet);\r\n\r\n\t\t\tconst baseUrl = `https://cdn.jsdelivr.net/npm/@ninebone/grid@${__APP_VERSION__}/dist/css/${className}.css`;\r\n\t\t\tfetch(baseUrl)\r\n\t\t\t\t.then(res => res.text())\r\n\t\t\t\t.then(cssText => baseSheet.replaceSync(cssText))\r\n\t\t\t\t.catch(err => console.error(`Base CSS Load Error:`, err));\r\n\t\t}\r\n\r\n\t\tconst sheets = [ngElement._styleCache.get(className)];\r\n\r\n\t\t// 2. 커스텀 스타일 시트 처리 (자바스크립트 단 캐싱 O)\r\n\t\tif (nine.cssPath) {\r\n\t\t\tif (!ngElement._customStyleCache.has(className)) {\r\n\t\t\t\tconst customSheet = new CSSStyleSheet();\r\n\t\t\t\tngElement._customStyleCache.set(className, customSheet);\r\n\r\n\t\t\t\t// 💡 오타 수정 및 캐시 파라미터 제거\r\n\t\t\t\tconst customUrl = `${nine.cssPath}/ninegrid/${className}.css`;\r\n\r\n\t\t\t\tfetch(customUrl)\r\n\t\t\t\t\t.then(res => res.text())\r\n\t\t\t\t\t.then(cssText => customSheet.replaceSync(cssText))\r\n\t\t\t\t\t.catch(err => console.error(`Custom CSS Load Error:`, err));\r\n\t\t\t}\r\n\r\n\t\t\t// 캐시된 커스텀 시트가 있으면 기본 시트 배열 뒤에 추가\r\n\t\t\tsheets.push(ngElement._customStyleCache.get(className));\r\n\t\t}\r\n\r\n\t\t// 한 번에 섀도우 돔에 적용\r\n\t\tthis.shadowRoot.adoptedStyleSheets = sheets;\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\t// ngElement 레벨에서는 비워두셔도 됩니다.\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { BasicCellElement } from './BasicCellElement.js';\r\n\r\nconst exprCache = new Map();\r\nconst hostFuncCache = new Map();\r\n\r\nexport class CellElement extends BasicCellElement {\r\n\t#host;\r\n\t#sheet;\r\n\t#tr;\r\n\t#cell;\r\n\r\n\t#attr;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tget host() { return this.#host; }\r\n\tget sheet() { return this.#sheet; }\r\n\tget cell() { return this.#cell; }\r\n\tget tr() { return this.#tr; }\r\n\tget attr() { return this.#attr; }\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\tthis.#cell = this.closest(\"th,td\");\r\n\t\tthis.#tr = this.#cell.closest(\"tr\");\r\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\r\n\r\n\t\tthis.#cell.classList.add(this.tagName);\r\n\r\n\t\tthis.#attr = {};\r\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\r\n\t\t\tconst name = this.#cell.attributes[i].name;\r\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\r\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\r\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#cell) return;\r\n\r\n\r\n\t\tconst root = this.shadowRoot || this;\r\n\r\n\t\t// 🎯 버튼 이벤트 연결\r\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\r\n\t\t\tbutton.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\r\n\r\n\t\t\t\tconst rowData = this.data; // Proxy Lazy 접근\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t/**\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t})); */\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 링크 이벤트 연결\r\n\t\tconst renderer = root.querySelector(\".renderer\");\r\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\r\n\t\t\trenderer.classList.add(\"link\");\r\n\r\n\t\t\trenderer.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\r\n\r\n\t\t\t\tconst rowData = this.data;\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t}));\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [Proxy 최적화] 속성 읽기 시에도 fields.indexOf() 사용\r\n\t */\r\n\tget data() {\r\n\t\tconst rawRecord = this.#tr?.data;\r\n\t\tif (!rawRecord) return null;\r\n\t\tif (!rawRecord.v) return rawRecord;\r\n\r\n\t\tconst host = this.#host;\r\n\r\n\t\treturn new Proxy(rawRecord, {\r\n\t\t\tget(target, prop) {\r\n\t\t\t\tif (prop === '__ng') return target.__ng;\r\n\t\t\t\tif (prop === 'v') return target.v;\r\n\r\n\t\t\t\t// 💡 host.fields.indexOf(prop) 사용\r\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\r\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [핵심] 변환 없이 원시 v 배열에서 direct 인덱스 검색 (GC zero)\r\n\t */\r\n\tget value() {\r\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\r\n\r\n\t\tconst bindKey = this.#cell.dataset?.bind;\r\n\t\tif (!bindKey) return \"\";\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\t// 1. 원시 데이터 배열({ v: [...] }) 구조인 경우\r\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\r\n\t\t\t// 💡 fields.indexOf(bindKey)로 바로 찾기!\r\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\r\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\r\n\t\t}\r\n\r\n\t\t// 2. 일반 JSON 객체인 경우 (하위 호환)\r\n\t\treturn rawRecord[bindKey] ?? \"\";\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif (!this.#cell || !this.#host?.data) return;\r\n\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tif (isNaN(row) || !bindKey) return;\r\n\r\n\t\tconst updateRowState = this.getAttribute('update-row-state') !== \"false\";\r\n\t\tthis.#host.data.setValue(row, bindKey, v, updateRowState);\r\n\t}\r\n\r\n\tget row() {\r\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\r\n\t}\r\n\tget index() {\r\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\r\n\t}\r\n\r\n\tgetDisplayText = (defaultValue = \"\") => {\r\n\r\n\t\ttrace.log(\"=================================\");\r\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\ttrace.log(\"==============================\", rawRecord);\r\n\r\n\t\tif (!rawRecord) return defaultValue;\r\n\r\n\t\tconst expr = this.#cell.dataset.expr;\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\tif (expr) {\r\n\t\t\ttry {\r\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\r\n\t\t\t\t\t// 💡 상수가 정의되어 있다면 GROUP_IDX.ID 로 고유 ID 추출 (아니면 배열 인덱스 직접 참조)\r\n\t\t\t\t\t// 배열 구조체인 경우: rawRecord[0]이 groupId임\r\n\t\t\t\t\t//const groupId = Array.isArray(rawRecord) ? rawRecord[0] : (rawRecord.__ng?.id || rawRecord.m?.id);\r\n\r\n\t\t\t\t\t// 💡 매니저를 통해 해당 그룹의 자식 레코드 목록을 O(1)로 획득\r\n\t\t\t\t\t//const childRecords = this.#sheet.grouping.getChildrenRecords(\"g_0\");\r\n\t\t\t\t\t//trace.log(\"--========\", childRecords);\r\n\t\t\t\t\t// 그룹 전용 표현식 계산 메서드 호출\r\n\t\t\t\t\t//return \"\";//this.getGroupExprValue(expr, childRecords, row, this.#cell);\r\n\r\n\t\t\t\t\t//trace.log(this, this.#cell.dataset.bind);\r\n\t\t\t\t\t//return \"x\";//this.data.length;\r\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\r\n\r\n\t\t\t\t\t//return this.getExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\tconsole.trace(e);\r\n\t\t\t\t//console.error(\"Expr evaluation error:\", expr, e);\r\n\t\t\t\treturn defaultValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\ttrace.log(\"==============================\", bindKey, this.value);\r\n\r\n\t\tif (bindKey) {\r\n\t\t\tconst val = this.value; // 직통 읽기\r\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\r\n\t\t}\r\n\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\r\n\r\n\trefresh() {\r\n\r\n\t\tif (!this.#cell || !this.#tr) return;\r\n\r\n\t\tconst val = this.value; // 원시 배열 직통 조회\r\n\r\n\t\t[\"color\",\"background\",\"background-color\",\"class\",\"visible\",\"enable\"].forEach(v => {\r\n\t\t\tconst expr = this.#attr[v];\r\n\t\t\tif (expr) {\r\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\r\n\r\n\t\t\t\tif (v === \"visible\") {\r\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\r\n\t\t\t\t} else if (v === \"enable\") {\r\n\t\t\t\t\t// 💡 enable이 false면 비활성화(disabled = true), true면 활성화(disabled = false)\r\n\t\t\t\t\t//const isEnabled = !!result;\r\n\r\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\r\n\t\t\t\t\t\t$el.disabled = !result;\r\n\t\t\t\t\t});\r\n\r\n\r\n\t\t\t\t\tif (!!result) {\r\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#cell.style[v] = result;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn val;\r\n\t}\r\n\r\n\tgetExprValue(expr, data, row) {\r\n\t\t//trace.log(\"********************************************\", expr, data, row);\r\n\r\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\r\n\r\n\r\n\t\tif (expr === undefined) return expr;\r\n\t\tconsole.trace(\"********************************************\");\r\ntrace.log(\"********************************************\", expr);\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst trimmedExpr = expr.trim();\r\n\t\t\t//const fields = this.#host?.fields;\r\n\r\n\t\t\t// 🎯 1. 데이터가 원시 배열 구조인 경우 표현식 내부의 필드명을 인덱스로 자동 치환\r\n\t\t\t//const isRawArray = data && typeof data === 'object' && Array.isArray(data.v);\r\n\t\t\t//const compiledExpr = isRawArray ? this.#rewriteExpr(trimmedExpr, fields) : trimmedExpr;\r\n\t\t\t//trace.log(compiledExpr);\r\n\t\t\t// 2. 함수 호출식인 경우 (예: oppositeColor(...))\r\n\t\t\t//const match = trimmedExpr.match(/^([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\tconst match = trimmedExpr.match(/(?:[a-zA-Z_$][\\w$]*\\.)*([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\t//trace.log(trimmedExpr, match);\r\n\t\t\tif (match) {\r\n\t\t\t\tconst fnName = match[1].replace(\"host.\", \"\");\r\n\t\t\t\t//trace.log(fnName);\r\n\t\t\t\tif (this.#host && typeof this.#host[fnName] === 'function') {\r\n\r\n\t\t\t\t\tlet evalFn = hostFuncCache.get(trimmedExpr);\r\n\r\n\t\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\t\tconst openIdx = trimmedExpr.indexOf('(');\r\n\t\t\t\t\t\tconst closeIdx = trimmedExpr.lastIndexOf(')');\r\n\t\t\t\t\t\tconst argsString = (openIdx !== -1 && closeIdx !== -1) ? trimmedExpr.substring(openIdx + 1, closeIdx) : \"\";\r\n\r\n\t\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', 'host', `\r\n\t\t\t\t\t\t try {\r\n\t\t\t\t\t\t const data = rowItem;\r\n\t\t\t\t\t\t //console.log(data);\r\n\t\t\t\t\t\t \r\n\t\t\t\t\t\t //if (!data) return \"\";\r\n\t\t\t\t\t\t return host.${fnName}.call(host, ${argsString});\r\n\t\t\t\t\t\t } catch (err) {\r\n\t\t\t\t\t\t console.error(\"Expr eval error:\", err);\r\n\t\t\t\t\t\t return \"\";\r\n\t\t\t\t\t\t }\r\n\t\t\t\t\t `);\r\n\r\n\t\t\t\t\t\thostFuncCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn evalFn(data, row, cell, this.#host);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//trace.log(trimmedExpr);\r\n\t\t\t// 3. 일반 연산식인 경우 (예: data.v[0] + ' vs ' + data.v[1])\r\n\t\t\tif (trimmedExpr.includes(\"data.\") || trimmedExpr.includes(\"rowItem.v\") || trimmedExpr.includes(\"(\")) {\r\n\t\t\t\t//trace.log(\"=========================\")\r\n\t\t\t\tlet evalFn = exprCache.get(trimmedExpr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', `\r\n const data = rowItem;\r\n\r\n if (!data) return \"\";\r\n return ${trimmedExpr};\r\n `);\r\n\t\t\t\t\texprCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(data, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\treturn trimmedExpr;\r\n\t\t} catch (e) {\r\n\t\t\treturn [\"NG-COMBO\"].includes(this.tagName) ? \"\" : expr;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [신규] 그룹 행의 자식 데이터 목록(childRecords)을 기반으로 합계/평균/개수 등을 처리하는 메서드\r\n\t */\r\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\r\n\t\tif (!expr) return \"\";\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\r\n\r\n\t\t\t// 1. 호스트(컴포넌트)에 정의된 그룹 전용 커스텀 메서드가 있는 경우 우선 위임\r\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\r\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\t// 2. 기본 내장 집계 함수 파싱 처리 (예: sum(price), count(), avg(score) 등)\r\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\r\n\t\t\tif (match) {\r\n\t\t\t\t// 💡 groupRecord에서 자식 레코드 목록 안전하게 추출 (indices 배열 -> 실제 레코드 매핑)\r\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\r\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\r\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\r\n\r\n\t\t\t\tconst [, funcName, field] = match;\r\n\t\t\t\tconst host = this.#host;\r\n\r\n\t\t\t\tswitch (funcName.toLowerCase()) {\r\n\t\t\t\t\tcase 'count':\r\n\t\t\t\t\t\treturn childRecords.length;\r\n\r\n\t\t\t\t\tcase 'sum': {\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tcase 'avg': {\r\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t\treturn sum / childRecords.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 3. 호스트의 exprFunction 활용\r\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\r\n\t\t\t}\r\n\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (예: \"childRecords.reduce(...)\")\r\n\t\t\t// groupRecord 자체나 내부 자식들을 활용하는 표현식 문자열 처리\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (안전성 강화 버전)\r\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\r\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\r\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\r\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\r\n \r\n let childRecords = [];\r\n if (Array.isArray(indices)) {\r\n // indices가 숫자 인덱스 배열인지, rowid 문자열 배열인지 판별하여 안전하게 추출\r\n childRecords = indices.map(idx => {\r\n if (typeof idx === 'number') {\r\n return allRecords[idx];\r\n } else {\r\n // rowid 등 문자열 식별자인 경우 전체 배열에서 찾거나 dataManager 활용\r\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\r\n }\r\n }).filter(Boolean);\r\n }\r\n \r\n // 만약 위에서 못 찾았는데 host.grouping을 쓸 수 있다면 매니저 위임 시도\r\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\r\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\r\n }\r\n\r\n const data = childRecords; // data.length 등을 쓸 수 있도록 호환\r\n return ${expr};\r\n `);\r\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\r\n\t\t\t}\r\n\r\n\t\t\treturn expr;\r\n\t\t} catch (e) {\r\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\r\n\t\t\treturn expr;\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class EditableCellElement extends CellElement {\r\n\r\n\tget host() { return super.host; }\r\n\tget sheet() { return super.sheet; }\r\n\tget cell() { return super.cell; }\r\n\tget tr() { return super.tr; }\r\n\tget attr() { return super.attr; }\r\n\r\n\tgetExprValue(expr, data, row, cell) {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\t/**\r\n\t\tthis.querySelectorAll(\"input, textarea\").forEach($el => {\r\n\t\t\t$el.addEventListener(\"change\", (event) => {\r\n\t\t\t\tif (!this.closest(\"tbody\")) return;\r\n\r\n\t\t\t\tconst target = event.target;\r\n\t\t\t\tconst inputType = target.getAttribute('type');\r\n\r\n\t\t\t\tif (inputType === \"checkbox\") {\r\n\t\t\t\t\tconst trueVal = super.attr[\"true-value\"] || \"Y\";\r\n\t\t\t\t\tconst falseVal = super.attr[\"false-value\"] || \"N\";\r\n\t\t\t\t\tthis.value = target.checked ? trueVal : falseVal;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet v = target.value;\r\n\t\t\t\t\tconst maxbyte = super.attr[\"maxbyte\"];\r\n\r\n\t\t\t\t\ttrace.log(maxbyte);\r\n\r\n\t\t\t\t\tif (maxbyte) {\r\n\t\t\t\t\t\tconst byteLen = nine.getByteLength(v);\r\n\t\t\t\t\t\tif (byteLen >= parseInt(maxbyte, 10)) {\r\n\t\t\t\t\t\t\tv = nine.cut(v, parseInt(maxbyte, 10));\r\n\t\t\t\t\t\t\ttarget.value = v;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tthis.value = this.getAttribute(\"type\") === \"number\" ? (isNaN(v) ? \"\" : Number(v)) : v;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsuper.sheet.invalidate();\r\n\t\t\t});\r\n\t\t}); */\r\n\t}\r\n\r\n\trefresh() {\r\n\t\treturn super.refresh();\r\n\t}\r\n\r\n\tgetExprValue = (expr, data, row, cell) => {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputText extends EditableCellElement\n{\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\t\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#initEvent();\n\t};\n\n\trefresh = () => {\n\n\t\tsuper.refresh();\n\n\t\tthis.#target.value = this.value;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"input\", e => {\n\t\t\tconst maxbyte = this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\n\t\t\tif (maxbyte) {\n\t\t\t\tconst maxByteNum = Number(maxbyte);\n\t\t\t\tconst currentBytes = nine.getByteLength(e.target.value);\n\n\t\t\t\tif (currentBytes > maxByteNum) {\n\t\t\t\t\te.target.value = nine.cut(e.target.value, maxByteNum);\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<style>\n\t\t\t\tcell-input {\n\t\t\t\t\tinput {\n\t\t\t\t\t\tposition: relative;\n\t\t\t\t\t\t-moz-user-select: auto;\n\t\t\t\t\t\t-webkit-user-select: auto;\n\t\t\t\t\t\t-ms-user-select: auto;\n\t\t\t\t\t\tuser-select: auto;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 26px;\n\t\t\t\t\t\tborder: 1px solid #eee;\n\t\t\t\t\t\tborder-radius: 3px;\n\t\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t\t\toutline: 0;\n\t\t\t\t\t\tfont: inherit;\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\tbackground-color: white;\n\t\t\t\t\t\tcolor: #333;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tinput:read-only {\n\t\t\t\t\t\tborder-color: #fdfdfd;\n\t\t\t\t\t\tfilter: brightness(97%);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n\t\t\t<input type=\"text\" ondragstart=\"return false;\">\n\t\t`;\n\t};\n}\n\nif (!customElements.get('cell-input')) {\n\tcustomElements.define(\"cell-input\", CellInputText);\n}\n","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputNumber extends EditableCellElement\n{\n\t#target;\n\n\tconstructor () {\n\t\tsuper();\n\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\tthis.#target.addEventListener(\"keydown\", this.#onKeyDown);\n\n\t\t// change 대신 input 이벤트를 사용하면 색상을 고르는 즉시 바로 적용됩니다.\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tthis.value = event.target.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 만약 색상 선택 창을 닫을 때(확정할 때) 추가로 처리할 로직이 필요하다면 change에 남겨둘 수 있습니다.\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\t//this.#target.style.backgroundColor = this.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\t/**\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t}); */\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n \t\tcell-input-number {\n\t\t\t\t\tinput[type=text].border-left-none {\n\t\t\t\t\t\t border-left: 0;\n\t\t\t\t\t\t border-top-left-radius: 0;\n\t\t\t\t\t\t border-bottom-left-radius: 0;\n\t\t\t\t\t }\n\t\t\t\t\t input[type=text].border-right-none {\n\t\t\t\t\t\t border-right: 0;\n\t\t\t\t\t\t border-top-right-radius: 0;\n\t\t\t\t\t\t border-bottom-right-radius: 0;\n\t\t\t\t\t }\n\t\t\n\t\t\t\t\t input[type=text] {\n\t\t\t\t\t\t position: relative;\n\t\t\t\t\t\t -moz-user-select: auto;\n\t\t\t\t\t\t -webkit-user-select: auto;\n\t\t\t\t\t\t -ms-user-select: auto;\n\t\t\t\t\t\t user-select: auto;\n\t\t\t\t\t\t width: 100%;\n\t\t\t\t\t\t height: 26px;\n\t\t\t\t\t\t border: 1px solid #eee;\n\t\t\t\t\t\t border-radius: 3px;\n\t\t\t\t\t\t padding-left: 4px;\n\t\t\t\t\t\t outline: 0;\n\t\t\t\t\t\t font: inherit;\n\t\t\t\t\t\t box-sizing: border-box;\n\t\t\t\t\t\t background-color: white;\n\t\t\t\t\t\t color: #333;\n\t\t\t\t\t\t text-align: right; /* 숫자는 기본적으로 우측 정렬이 어울림 */\n\t\t\t\t\t }\n\t\n\t\t\t\t\t input[type=text]:read-only {\n\t\t\t\t\t\t border-color: #fdfdfd;\n\t\t\t\t\t\t filter: brightness(97%);\n\t\t\t\t\t }\n \t\t}\n </style>\n\n <input type=\"text\" ${attr.join(\" \")} ondragstart=\"return false;\">\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tthis.#target.value = v !== undefined && v !== null ? v : \"\";\n\t\t\tthis.#validateInput(this.#target.value);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\n\t\tif (!this.#target) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tconst num = Number(val);\n\t\t\tif (isNaN(num) ||\n\t\t\t\t(super.attr.max !== null && super.attr.max !== undefined && num > Number(super.attr.max)) ||\n\t\t\t\t(super.attr.min !== null && super.attr.min !== undefined && num < Number(super.attr.min))\n\t\t\t) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (super.attr.scale !== null && super.attr.scale !== undefined) {\n\t\t\t\tconst strVal = String(val);\n\t\t\t\tconst dotIdx = strVal.indexOf('.');\n\t\t\t\tif (dotIdx >= 0 && strVal.substring(dotIdx + 1).length > Number(super.attr.scale)) {\n\t\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t#onKeyDown = e => {\n\n\t\tif ([\"Escape\", \"Enter\", \"Tab\", \"Home\", \"End\", \"ArrowLeft\", \"ArrowRight\", \"PageUp\", \"PageDown\", \"Backspace\", \"Delete\"].includes(e.code)) return;\n\n\t\tconst target = e.target;\n\t\tconst value = target.value;\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst selectionEnd = target.selectionEnd;\n\t\tconst key = e.key;\n\n\t\tif (key === \"-\") {\n\t\t\t// 이미 마이너스가 존재하거나, 커서가 맨 앞(0)이 아니면 차단 (중간이나 끝에 입력 방지)\n\t\t\tif (value.includes(\"-\") || selectionStart !== 0) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (key === \".\") {\n\t\t\tconst scale = Number(super.attr.scale);\n\t\t\t// scale이 설정되지 않았거나(0 이하), 이미 소수점이 존재하면 차단\n\t\t\tif (isNaN(scale) || scale <= 0 || value.includes(\".\")) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// 마이너스만 있는 상태(\"-\")에서 바로 소수점이 찍히는 것(-.)을 막으려면 아래 조건 추가 가능\n\t\t\t// if (value === \"-\" && selectionStart === 1) { e.preventDefault(); return; }\n\t\t}\n\n\t\tlet validKey = [];\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && Number(super.attr.scale) > 0) validKey.push(\".\");\n\t\tif (super.attr.min === null || super.attr.min === undefined || Number(super.attr.min) > 0) validKey.push(\"-\");\n\n\t\t// 숫자 키패드 및 상단 숫자 키 허용 + 소수점/마이너스 허용\n\t\tconst isNumKey = (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105);\n\n\t\tif (!isNumKey && !validKey.includes(e.key)) {\n\t\t\te.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\t// 소수점 자리수(scale) 제한 체크\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && isNumKey && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\tconst s = e.target.value;\n\t\t\tconst idx = s.indexOf(\".\");\n\t\t\tif (idx >= 0 && e.target.selectionStart > idx) {\n\t\t\t\tconst decimalPart = s.substr(idx + 1);\n\t\t\t\tif (decimalPart.length >= Number(super.attr.scale)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (super.attr.maxbyte && nine.getByteLength(e.target.value) >= Number(super.attr.maxbyte) && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\te.preventDefault();\n\t\t}\n\t}\n}\n\nif (!customElements.get('cell-input-number')) {\n\tcustomElements.define(\"cell-input-number\", CellInputNumber);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputColor extends EditableCellElement\n{\n\t#target;\n\t#btn;\n\n\tconstructor () {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input[type=color]\");\n\t\tthis.#btn = this.querySelector(\"button\");\n\t\tif (!this.#target) return;\n\n\t\t// 버튼 클릭 시 컬러 input을 프로그래밍 방식으로 클릭하여 팝업 오픈\n\t\tif (this.#btn) {\n\t\t\tthis.#btn.addEventListener(\"click\", () => {\n\t\t\t\tthis.#target.click();\n\t\t\t});\n\t\t}\n\n\t\t// 색상 변경 즉시 반영\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\tthis.#target.click();\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-color {\n --position: relative;\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-color.invalid button {\n padding: 2px;\n }\n cell-input-color.invalid button:after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-input-color input[type=color] {\n width: 100%;\n height: 26px;\n padding: 0px;\n margin-left: unset;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-color: transparent;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color input[type=color]::-webkit-color-swatch {\n border: 0;\n border-top-left-radius: 2px;\n border-bottom-left-radius: 2px;\n }\n cell-input-color input[type=color]::-webkit-color-swatch-wrapper {\n padding: 1px;\n }\n\n cell-input-color button {\n display: inline-flex;\n width: 24px;\n height: 26px;\n margin-right: unset;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color button:after {\n content: \"\";\n border-top: 0.3em solid #333;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n cell-input-color input[type=color]:hover {\n filter: brightness(90%);\n }\n cell-input-color button:hover {\n filter: brightness(95%);\n }\n \n .CELL-INPUT-COLOR {\n \n }\n </style>\n\n <input type=\"color\" ${attr.join(\" \")} ondragstart=\"return false;\">\n <button tabindex=\"-1\" type=\"button\"></button>\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tconst val = v !== undefined && v !== null && v !== \"\" ? v : \"#ffffff\";\n\t\t\tthis.#target.value = val;\n\t\t\tthis.#validateInput(val);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\t\tthis.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tif (!this.#isValidColor(val)) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tthis.classList.add(\"invalid\");\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidColor = (v) => {\n\t\tif (typeof v !== \"string\" || v.length != 7 || !v.startsWith(\"#\")) return false;\n\n\t\tvar r = parseInt(v.substr(1, 2), 16);\n\t\tvar g = parseInt(v.substr(3, 2), 16);\n\t\tvar b = parseInt(v.substr(5, 2), 16);\n\n\t\tif (isNaN(r) || isNaN(g) || isNaN(b)) return false;\n\t\tif (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) return false;\n\n\t\treturn true;\n\t}\n}\n\nif (!customElements.get('cell-input-color')) {\n\tcustomElements.define(\"cell-input-color\", CellInputColor);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputDate extends EditableCellElement\n{\n\t#target;\n\t#type;\n\n\tconstructor () {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\n\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#type = super.attr[\"date-type\"] || \"date\";//this.getAttribute(\"date-type\") || \"date\";\n\t\tif (![\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(this.#type)) {\n\t\t\tthrow `invalid type : ${this.#type}`;\n\t\t}\n\n\t\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\t// 값 변경 시 즉시 반영 및 검증\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#target.classList.toggle(\"has-value\", !!val); // 💡 실시간 반영\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\t// 필요 시 추가 동작\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst height = parseInt(this.closest(\"tr\")?.style.height || \"26\", 10) - 1;\n\n\t\tlet attr = [];\n\t\tfor (var i = 0; i < cell.attributes.length; i++) {\n\t\t\tif ([\"value\", \"max\", \"min\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t//if ([\"value\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t\tattr.push(`${cell.attributes[i].name}=\"${cell.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-date {\n height: 100%;\n --width: calc(100% - 8px);\n width: 100%;\n display: flex;\n align-items: center;\n --margin-left: 4px;\n --margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-date input {\n position: relative;\n height: 26px;\n padding: 0;\n margin: 0;\n font: inherit;\n width: 100%;\n padding-left: 4px;\n border: 1px solid #f0f0f0;\n border-radius: 3px;\n outline: 0;\n background-color: transparent;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"black\" viewBox=\"0 0 16 16\"><path d=\"M11 7.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\"/><path d=\"M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M2 2a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/><path d=\"M2.5 4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5z\"/></svg>');\n background-repeat: no-repeat;\n background-position: right 2px center;\n background-size: 14px auto;\n color: #333;\n box-sizing: border-box;\n }\n\n cell-input-date input:hover {\n filter: brightness(95%);\n }\n \n cell-input-date input::-webkit-calendar-picker-indicator {\n position: absolute;\n right: 0;\n top: 0;\n width: 16px;\n height: 100%;\n background: transparent;\n --color: transparent;\n cursor: pointer;\n \t--opacity: 0.3;\n \t--filter: brightness(80%);\n }\n \n\t\t\t\n\t\t\t\n cell-input-date input::before {\n content: attr(data-placeholder);\n position: absolute;\n display: flex;\n align-items: center;\n width: calc(100% - 22px);\n height: 100%;\n background-color: white;\n left: 1px;\n top: 1px;\n pointer-events: none;\n }\n\n cell-input-date input.has-value::before,\n cell-input-date input:focus::before {\n display: none;\n }\n\n cell-input-date input:focus {\n border: 1px solid #28a745;\n border-radius: 3px;\n }\n \n \n </style>\n\n <input\n type=\"${cell.getAttribute('date-type') || 'date'}\"\n data-placeholder=\"${cell.getAttribute('placeholder') || 'Select'}\"\n ${attr.join(\" \")}\n required\n />\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (!this.#target) return v;\n\n\t\tlet formattedVal = v;\n\t\tif (formattedVal) {\n\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"date\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"time\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"00\" + d.getHours()).slice(-2) + \":\" + (\"00\" + d.getMinutes()).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"0000\" + d.getFullYear()).slice(-4) + \"-\" + (\"00\" + (d.getMonth() + 1)).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//trace.log(this.#type, formattedVal);\n\n\t\tthis.#target.value = formattedVal || \"\";\n\t\tthis.#target.classList.toggle(\"has-value\", !!formattedVal); // 💡 값이 있으면 클래스 추가\n\t\tthis.#validateInput(formattedVal);\n\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst min = cell?.getAttribute(\"min\");\n\t\tconst max = cell?.getAttribute(\"max\");\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tlet isValid = this.#isValidDate(val);\n\n\t\t\t// 💡 형식 검증을 통과했더라도 min/max 범위를 벗어났다면 invalid 처리\n\t\t\tif (isValid) {\n\t\t\t\tif (min && val < min) isValid = false;\n\t\t\t\tif (max && val > max) isValid = false;\n\t\t\t}\n\n\t\t\tif (!isValid) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidDate = (v) => {\n\t\t//if (ninegrid.isNull(v)) return true;\n\t\tif (typeof v !== \"string\") return false;\n\n\t\tlet isValid = true;\n\n\t\tswitch (this.#type) {\n\t\t\tcase \"date\":\n\t\t\tcase \"datetime-local\":\n\t\t\t\tconst year = Number(v.substr(0, 4));\n\t\t\t\tconst month = Number(v.substr(5, 2));\n\t\t\t\tconst day = Number(v.substr(8, 2));\n\n\t\t\t\tif (isNaN(year) || isNaN(month) || isNaN(day)) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month < 1 || month > 12 || day < 1 || day > 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if ([4, 6, 9, 11].includes(month) && day == 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month == 2) {\n\t\t\t\t\tlet isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));\n\t\t\t\t\tif (day > 29 || (day == 29 && !isleap)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (isValid) {\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tvar t = v.substr(10, 1);\n\t\t\t\t\tvar hour = Number(v.substr(11, 2));\n\t\t\t\t\tvar min = Number(v.substr(14, 2));\n\n\t\t\t\t\tif (t != \"T\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(hour) || isNaN(min)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (hour < 0 || hour > 23 || min < 0 || min > 59) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar month = Number(v.substr(5, 2));\n\n\t\t\t\t\tif (isNaN(year) || isNaN(month)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (month < 1 || month > 12) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"week\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar w = v.substr(5, 1);\n\t\t\t\t\tvar week = Number(v.substr(6, 2));\n\n\t\t\t\t\tif (w != \"W\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(year) || isNaN(week)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (week <= 0 || week > 53) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn isValid;\n\t}\n}\n\nif (!customElements.get('cell-input-date')) {\n\tcustomElements.define(\"cell-input-date\", CellInputDate);\n}","import { EditableCellElement } from \"./core/CellElement.js\";\nimport {trace} from \"@nopeer\";\n\nclass CellCheckbox extends EditableCellElement {\n #target;\n #label;\n #isRadio;\n #trueText;\n #falseText;\n\n constructor() {\n super();\n\n\n }\n\n connectedCallback() {\n this.#renderer();\n\n super.connectedCallback();\n\n this.#init();\n }\n\n get trueValue() {\n return super.attr[\"true-value\"] || \"Y\";\n }\n get falseValue() {\n return super.attr[\"false-value\"] || \"N\";\n }\n\n get dataSource() {\n return [\n { value: this.trueValue, text: this.#trueText },\n { value: this.falseValue, text: this.#falseText }\n ];\n }\n\n #init = () => {\n this.#target = this.querySelector(\"input\");\n this.#label = this.querySelector(\"span\");\n\n this.#trueText = super.attr[\"true-text\"] || \"\";\n this.#falseText = super.attr[\"false-text\"] || \"\";\n //this.#isRadio = super.attr[\"is-radio\"] || false;\n\n // 헤더에 있는 체크박스인 경우 (전체 선택/해제 기능)\n if (this.closest(\"thead\")) {\n this.#target.addEventListener(\"change\", (e) => {\n super.sheet.querySelector(`tbody.body [data-col=\"${super.cell.dataset.col}\"] cell-checkbox`)?.selectAll(e.target.checked);\n });\n }\n\n // 스페이스바 입력 시 값 토글 처리\n this.cell?.addEventListener(\"keydown\", (e) => {\n\n e.preventDefault();\n\n if (e.code === \"Space\") return;\n if (this.closest(\"thead\")) return; // 헤더는 제외\n if (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n if (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\n //this.value = newVal;\n if (this.#isRadio) {\n this.selectAll(false);\n }\n\n this.value = newVal;\n\n super.sheet.invalidate();\n });\n\n\n this.#target.addEventListener(\"change\", (event) => {\n if (!this.closest(\"tbody\")) return;\n\n //const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\n if (this.#isRadio) {\n this.selectAll(false);\n this.value = this.trueValue;\n }\n else {\n this.value = event.target.checked ? this.trueValue : this.falseValue;\n }\n\n super.sheet.rowManager.refresh(true);\n //super.sheet.invalidate();\n });\n }\n\n #renderer = () => {\n\n const $cell = this.closest(\"th,td\");\n\n this.#isRadio = $cell?.getAttribute(\"is-radio\") || false;\n\n const trueValue = $cell?.getAttribute(\"true-value\") || false;\n //const selectedBorderColor = this.getAttribute(\"selected-border-color\") || \"dimgray\";\n\n const originalContent = $cell?.getAttribute(\"content\") || \"\";\n const childHtml = this.#isRadio ? `<input type=\"radio\" value=\"${trueValue}\" />` : `<label><input type=\"checkbox\" /><span>${originalContent}</span></label>`;\n\n // 🎯 div.ng-wrap 없이 cell-checkbox(Host) 자체를 플렉스 컨테이너로 활용하여 중앙정렬 보장\n this.innerHTML = `\n <style>\n .CELL-CHECKBOX {\n cell-checkbox {\n justify-content: center;\n }\n label {\n display: flex;\n }\n input {\n background-color: #ffffff;\n }\n \n \n /* 라디오 버튼 스타일 */\n input[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n .CELL-CHECKBOX[text-align='left'] {\n cell-checkbox {\n justify-content: flex-start;\n }\n }\n .CELL-CHECKBOX[text-align='center'] {\n cell-checkbox {\n justify-content: center;\n }\n }\n .CELL-CHECKBOX[text-align='right'] {\n cell-checkbox {\n justify-content: flex-end;\n }\n label {\n flex-direction: row-reverse;\n }\n }\n \n \n \n cell-checkbox {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n }\n cell-checkbox label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n cursor: pointer;\n user-select: none;\n }\n cell-checkbox input {\n outline: none;\n }\n \n </style>\n ${childHtml}\n `;\n }\n\n refresh = () => {\n const val = super.refresh(); // CellElement의 원시값 직통 조회 활용\n\n if (!this.closest(\"tbody\") && !this.closest(\"thead\")) return val;\n\n // 체크박스 상태 동기화\n if (this.#target) {\n this.#target.checked = (val === this.trueValue);\n this.#validateInput(val);\n }\n\n // 라벨 텍스트 동기화\n if (this.#label) {\n const displayText = (val === this.trueValue) ? this.#trueText : ((val === this.falseValue) ? this.#falseText : val);\n this.#label.textContent = displayText;\n }\n\n return val;\n };\n\n #validateInput = (val) => {\n\n if (!this.#target) return;\n\n super.cell.classList.remove(\"invalid\");\n\n if (val !== \"\" && val !== null && val !== undefined) {\n if (val !== this.trueValue && val !== this.falseValue) {\n super.cell.classList.add(\"invalid\");\n }\n }\n };\n\n selectAll = (v) => {\n if (this.closest(\"thead\")) return; // 헤더 자신은 제외\n\n const data = super.host.data.getArray();\n const colIndex = super.host.fields.indexOf(super.cell.dataset.bind);\n\n if (colIndex < 0) return;\n\n for (let i = 0; i < data.length; i++) {\n if (super.attr.enable && super.getExprValue(super.attr.enable, data[i], i, super.cell) === false) continue;\n if (super.attr.readonly && super.getExprValue(super.attr.readonly, data[i], i, super.cell) === true) continue;\n if (super.attr.visible && super.getExprValue(super.attr.visible, data[i], i, super.cell) === false) continue;\n\n data[i].v[colIndex] = v ? this.trueValue : this.falseValue;\n }\n\n super.sheet.invalidate();\n };\n}\n\nif (!customElements.get('cell-checkbox')) {\n customElements.define(\"cell-checkbox\", CellCheckbox);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport {NINE_TABLE} from \"@\";\n\nclass CellRadio extends EditableCellElement {\n\t#target;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\n\t#host;\n\t#sheet;\n\t#cell;\n\t#tr;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#keyName = this.closest(\"th,td\").getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = this.closest(\"th,td\").getAttribute(\"value-name\") || \"v\";\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\n\n\t\tthis.#rendererRadio();\n\n\t\tthis.#initEvent();\n\n\t\t// 3. 사용자 인터랙션 (스페이스바로 라디오 순회 변경)\n\n\t}\n\n\t#initEvent = () => {\n\t\tsuper.cell.addEventListener(\"keydown\", e => {\n\n\t\t\te.preventDefault();\n\n\t\t\tif (e.code !== \"Space\") return;\n\t\t\tif (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n\t\t\tif (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n\t\t\tlet matchIndex = -1;\n\n\t\t\tconst targets = Array.from(this.querySelectorAll(\"input\"));\n\t\t\ttargets.forEach(($el,index) => {\n\t\t\t\tif (this.value === $el.getAttribute(\"value\")) {\n\t\t\t\t\tmatchIndex = index;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmatchIndex = (matchIndex === targets.length - 1) ? 0 : (matchIndex >= 0 ? matchIndex + 1 : 0);\n\t\t\tthis.value = targets[matchIndex].getAttribute(\"value\");\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#rendererRadio = () => {\n\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\ttrace.log(\"==============================================\");\n\t\ttrace.log(this.sheet, this.#dataSource);\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(\"1111\");\n\t\t}, 300)\n\n\t\tthis.#target.replaceChildren();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tconst codeVal = v[this.#keyName] !== undefined ? v[this.#keyName] : '';\n\t\t\t\tconst nameVal = v[this.#valueName] !== undefined ? v[this.#valueName] : '';\n\n\t\t\t\t// <label> 생성\n\t\t\t\tconst label = document.createElement('label');\n\n\t\t\t\t// <input type=\"radio\" value=\"...\"> 생성\n\t\t\t\tconst input = document.createElement('input');\n\t\t\t\tinput.type = 'radio';\n\t\t\t\tinput.value = codeVal;\n\n\t\t\t\t// <span>텍스트</span> 생성 (textContent를 써야 XSS 방어 및 안전합니다)\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = nameVal;\n\n\t\t\t\t// 조립\n\t\t\t\tlabel.appendChild(input);\n\t\t\t\tlabel.appendChild(span);\n\t\t\t\tfragment.appendChild(label);\n\t\t\t});\n\n\t\t\tthis.#target.appendChild(fragment);\n\n\t\t\tthis.querySelectorAll(\"input\").forEach($el => {\n\t\t\t\t$el.addEventListener(\"change\", (e) => {\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\n\t\t// 4. 마우스 클릭 시 값 변경 및 즉시 반영\n\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n <style>\n \t.CELL-RADIO {\n \t\t\tinput[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n \n \t.CELL-RADIO[text-align='left'] {\n cell-radio {\n justify-content: flex-start;\n }\n }\n .CELL-RADIO[text-align='center'] {\n cell-radio {\n justify-content: center;\n }\n }\n .CELL-RADIO[text-align='right'] {\n cell-radio {\n justify-content: flex-end;\n }\n }\n \n cell-radio {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n \n div {\n \tdisplay: flex;\n \t\t\t\t\tflex-direction: row;\n }\n }\n\n cell-radio.invalid::after {\n content: '';\n margin-left: 4px;\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-radio input {\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n padding: 0;\n margin: 0;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border: 1px solid dimgray;\n border-radius: 50%;\n outline: 0;\n cursor: pointer;\n }\n\n cell-radio input:checked {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3\" cx=\"50%\" cy=\"50%\" fill=\"dimgray\" /></svg>');\n }\n\n cell-radio label {\n display: flex;\n align-items: center;\n margin-right: 8px;\n cursor: pointer;\n user-select: none;\n }\n\n cell-radio label.disabled {\n pointer-events: none;\n opacity: 0.5;\n }\n\n cell-radio span {\n margin-left: 4px;\n font-size: 12px;\n }\n </style>\n \n <div></div>\n `;\n\n\t\tthis.#target = this.querySelector(\"div\");\n\t};\n\n\trerenderer = () => {\n\t\tthis.#rendererRadio();\n\t\tthis.refresh();\n\t};\n\n\trefresh = () => {\n\n\t\tconst v = super.refresh();\n\n\t\tif (!this.#target) return v;\n\n\t\tthis.querySelectorAll(\"input\").forEach($el => {\n\t\t\t$el.checked = (this.value == $el.getAttribute(\"value\")) ? true : false;\n\t\t});\n\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst idx = this.#dataSource.findIndex(m => this.value === m[this.#keyName]);\n\t\tif (idx < 0) {\n\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-radio')) {\n\tcustomElements.define(\"cell-radio\", CellRadio);\n}","import { trace } from \"@nopeer\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#parent;\n\t#keyName;\n\t#valueName;\n\t#isOpen = false;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tthis.#initEvents();\n\t}\n\n\t#initData = (dataSource, keyName, valueName, multi, separator) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource || dataSource.length === 0) return;\n\n\t\t// 1. 부모(parent)의 items 속성 확인 (예: \"CODE,NAME,DESC\" 형태)\n\t\tconst itemsAttr = this.#parent.getAttribute(\"items\");\n\t\tlet fieldKeys = [];\n\n\t\tif (itemsAttr) {\n\t\t\tfieldKeys = itemsAttr.split(\",\").map(s => s.trim());\n\t\t} else {\n\t\t\tfieldKeys = [valueName].filter(Boolean);\n\t\t}\n\n\t\tconst activeColumnCount = fieldKeys.length;\n\n\t\t// 2. 🎯 [수정] multi 모드 여부에 따라 0번 컬럼(체크박스) 가시성 제어\n\t\t//trace.log(grd.shadowRoot, grd.shadowRoot.querySelectorAll('nine-table-body table'));\n\t\tgrd.shadowRoot.querySelector(\".ng-container-left\").style.display = multi ? '' : 'none';\n\n\t\tgrd.shadowRoot.querySelectorAll('table colgroup col, tbody td').forEach(($el, idx) => {\n\t\t\ttrace.log($el);\n\n\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\tif (col >= 2) {\t// row-indicator, checkbox 제외\n\t\t\t\t$el.style.display = (col - 2 >= activeColumnCount) ? 'none' : '';\n\t\t\t}\n\t\t});\n\n\t\t// 3. 동적 데이터 매핑 (dataSource 원본 객체에서 fieldKeys 순서대로 tmp1 ~ tmpN에 매핑)\n\t\tconst formattedData = dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: keyName && item[keyName] !== undefined ? item[keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\tfieldKeys.forEach((key, idx) => {\n\t\t\t\trow[`tmp${idx + 1}`] = item[key] !== undefined ? item[key] : (item[idx] !== undefined ? item[idx] : \"\");\n\t\t\t});\n\t\t\treturn row;\n\t\t});\n\n\t\tgrd.data.set(formattedData);\n\n\t\t// 4. 멀티 모드일 때 기존 선택값 반영\n\t\tif (multi && this.#parent.value) {\n\t\t\tconst selectedKeys = String(this.#parent.value).split(separator || \",\");\n\t\t\tgrd.data.getValidData().forEach(m => {\n\t\t\t\tif (selectedKeys.includes(String(m.v[1]))) {\n\t\t\t\t\tm.v[0] = \"Y\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tgrd.refreshData();\n\t\t}\n\t};\n\n\topen = (parent, dataSource, keyName, valueName, multi, separator) => {\n\t\tthis.#parent = parent;\n\t\tthis.#keyName = keyName;\n\t\tthis.#valueName = valueName;\n\t\tthis.#isOpen = true;\n\n\t\ttrace.log(new Date());\n\n\t\tthis.classList.add(\"active\");\n\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource) return;\n\n\t\t// 🎯 패널을 열자마자 active를 주어 레이아웃(offsetHeight) 확보 및 초기화 수행\n\n\n\t\t// 검색어 초기화 및 체크박스 기본값 설정\n\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\t// 데이터 개수 및 모드에 따른 클래스 제어\n\t\tif (dataSource.length > 10) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tif (multi) {\n\t\t\tthis.classList.add(\"multi\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"multi\");\n\t\t}\n\n\t\t// 데이터 및 멀티컬럼 구조 초기화 실행\n\n\t\t// 🎯 [필터 패널 방식 위치 정렬 적용] 시트(sheet) 기준 상대 좌표계산\n\t\tconst sheet = parent.closest(\"nine-table-sheet\");\n\t\tconst btnEl = parent.querySelector(\".btn1\");\n\t\tif (!btnEl || !sheet) return;\n\n\t\tconst btnRect = btnEl.getBoundingClientRect();\n\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\tlet left = btnRect.left - sheetRect.left;\n\t\tlet top = btnRect.bottom - sheetRect.top + 2;\n\n\t\t// 화면 오른쪽 밖으로 넘칠 경우 보정\n\t\tconst panelWidth = this.offsetWidth || 250;\n\t\tconst panelHeight = this.offsetHeight || 250;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 5);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\tif (top + panelHeight > sheetRect.height) {\n\t\t\tconst upwardTop = (btnRect.top - sheetRect.top) - panelHeight - 2;\n\t\t\tif (upwardTop >= 0) {\n\t\t\t\ttop = upwardTop; // 위쪽 공간이 있으면 위로 팝업\n\t\t\t} else {\n\t\t\t\ttop = Math.max(0, sheetRect.height - panelHeight - 5); // 위아래 다 부족하면 시트 하단에 밀착\n\t\t\t}\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\t// 내부 그리드 행 클릭 이벤트 바인딩 (싱글 모드용)\n\t\ttrace.log(new Date());\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(new Date());\n\t\t\tthis.#initData(dataSource, keyName, valueName, multi, separator);\n\t\t\ttrace.log(new Date());\n\t\t\tconst viewContainer = grd.shadowRoot.querySelector(\".ng-container-body table tbody.body\");\n\n\t\t\t// 중복 바인딩 방지를 위한 플래그 체크 또는 기존 리스너 관리\n\t\t\tif (!viewContainer.__hasClickEvent) {\n\n\t\t\t\tviewContainer.addEventListener(\"mousedown\", (e) => {\n\t\t\t\t\ttrace.log(\"==========================================\", e.target);\n\n\t\t\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\t\t\tif (!tr) return;\n\n\t\t\t\t\ttrace.log(\"==========================================\", multi);\n\n\t\t\t\t\tif (!multi) {\n\t\t\t\t\t\tthis.#onClickRow(e);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tviewContainer.__hasClickEvent = true;\n\t\t\t}\n\n\t\t\ttrace.log(new Date());\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#isOpen = false;\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus();\n\t\t}\n\t}\n\n\t#onClickRow = (e) => {\n\n\t\tconst sheet = e.target.closest(\"nine-table-sheet\");\n\t\tconst tr = e.target.closest(\"tr\");\n\n\t\tconst rowIndex = parseInt(tr.dataset.row, 10);\n\t\tconst record = sheet.view.get(rowIndex);\n\n\t\tthis.#parent.value = record.k;\n\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onOk = () => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst data = grd.data.getValidData();\n\n\t\tconst selectedKeys = [];\n\t\tdata.forEach(o => {\n\t\t\tif (o.v[0] === \"Y\") {\n\t\t\t\tselectedKeys.push(o.v[1]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = selectedKeys.join(this.#parent.getAttribute(\"multi-separator\") || \",\");\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onSelectAll = (e) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst isChecked = e.target.checked ? \"Y\" : \"N\";\n\t\tgrd.data.getValidData().forEach(m => { m.v[0] = isChecked; });\n\t\tgrd.refreshData();\n\t}\n\n\t#onInput = (e) => {\n\t\tconst keyword = e.target.value.toLowerCase();\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\n\t\t// 동적 컬럼(모든 밸류) 대상 검색 대응\n\t\tgrd.data.getValidDataNF().forEach(m => {\n\t\t\tconst match = Object.values(m.v).some(val =>\n\t\t\t\tval !== null && val !== undefined && String(val).toLowerCase().includes(keyword)\n\t\t\t);\n\t\t\tm.__ng.filtered = !match;\n\t\t});\n\n\t\tgrd.data.resetRecords();\n\t\tgrd.dataManager.viewRecords.reset();\n\t}\n\n\tget isOpen() {\n\t\treturn this.#isOpen;\n\t}\n\n\tget targetCell() {\n\t\treturn this.#parent;\n\t}\n\n\t#initEvents = () => {\n\t\tthis.querySelector(\".search-input\").addEventListener(\"input\", this.#onInput);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\n\n\t\t// 🎯 [개선] open() 할 때마다 붙일 필요 없이, 내부 그리드 영역에 이벤트 위임 처리\n\n\t\t/**\n\t\t// shadowRoot 내부 또는 컴포넌트 전체 영역을 감싸는 리스너 등록\n\t\tthis.querySelector(\"nine-table-simple\").addEventListener(\"click\", (e) => {\n\t\t\ttrace.log(e);\n\n\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\tif (!tr) return;\n\n\t\t\t// 멀티 모드가 아닐 때만 행 클릭 동작 수행\n\t\t\tconst isMulti = this.classList.contains(\"multi\");\n\t\t\tif (!isMulti) {\n\t\t\t\tthis.#onClickRow(e, false, grd);\n\t\t\t}\n\t\t}); */\n\n\t\t// 패널 외부 클릭 시 닫기\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\t\t\tconst path = e.composedPath ? e.composedPath() : [];\n\n\t\t\t// 패널 자신이나 현재 열려 있는 필터 버튼이 경로에 포함되어 있다면 닫지 않음\n\t\t\tif (path.includes(this)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.close();\n\t\t});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n \n cell-combo-panel.active {\n display: flex;\n }\n cell-combo-panel .head {\n display: none;\n padding: 6px;\n background: #f8f9fa;\n border-bottom: 1px solid #e5e7eb;\n }\n cell-combo-panel .head input[type=\"text\"] {\n width: 100%;\n height: 26px;\n padding: 0 6px;\n box-sizing: border-box;\n border: 1px solid #d1d5db;\n border-radius: 3px;\n outline: none;\n font-size: 12px;\n }\n cell-combo-panel.expand .head {\n display: flex;\n }\n cell-combo-panel nine-table-simple {\n width: 100%;\n flex: 1;\n border: none;\n }\n cell-combo-panel .footer {\n display: none;\n height: 32px;\n background: #f3f4f6;\n border-top: 1px solid #e5e7eb;\n align-items: center;\n padding: 0 8px;\n box-sizing: border-box;\n }\n cell-combo-panel.multi .footer {\n display: flex;\n justify-content: space-between;\n }\n cell-combo-panel .footer label {\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n }\n cell-combo-panel .footer button {\n height: 22px;\n padding: 0 12px;\n font-size: 11px;\n cursor: pointer;\n background: #2563eb;\n color: white;\n border: none;\n border-radius: 3px;\n }\n cell-combo-panel .footer button:hover {\n background: #1d4ed8;\n }\n </style>\n \n <div class=\"head\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\n </div>\n \n <nine-table-simple class=\"combo-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"30\" fixed=\"left\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"0\" />\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"tmp1\" />\n <td data-bind=\"tmp2\" />\n <td data-bind=\"tmp3\" />\n <td data-bind=\"tmp4\" />\n <td data-bind=\"tmp5\" />\n <td data-bind=\"tmp6\" />\n <td data-bind=\"tmp7\" />\n <td data-bind=\"tmp8\" />\n <td data-bind=\"tmp9\" />\n <td data-bind=\"tmp10\" />\n <td data-bind=\"k\" />\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n \n <div class=\"footer\">\n <div>\n <input id=\"chkAll\" type=\"checkbox\" checked>\n <label for=\"chkAll\">Select All</label>\n </div>\n <button id=\"btnOk\">OK</button>\n </div>\n `;\n\t};\n}\n\nif (!customElements.get('cell-combo-panel')) {\n\tcustomElements.define(\"cell-combo-panel\", CellComboPanel);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport \"./cell-combo-panel.js\";\n\nexport class CellCombo extends EditableCellElement {\n\t#targetBtn;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\t#multi;\n\t#multiSeparator;\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tthis.#keyName = super.cell.getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = super.cell.getAttribute(\"value-name\") || \"v\";\n\t\tthis.#multi = super.cell.getAttribute('multi') === \"true\";\n\t\tthis.#multiSeparator = super.cell.getAttribute(\"multi-separator\") || \",\";\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\trerenderer = () => {\n\t\ttrace.log(\"rerenderer\");\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\t#initData = () => {\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\t// 🎯 공통 표현식 평가기를 통해 데이터 소스(배열 또는 함수 결과) 획득\n\t\t//this.#host.exprEngine.evaluate(dataSource, data, row);\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\t//trace.log(\"*******************************\", this.#dataSource);\n\t}\n\n\t#initEvent = () => {\n\t\t// 엔터 키 입력 시 드롭다운 토글\n\t\tthis.addEventListener(\"keydown\", e => {\n\t\t\tif (e.code === \"Enter\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.#togglePanel();\n\t\t\t}\n\t\t});\n\n\t\t// Light DOM 기준이므로 this 안에서 버튼 탐색\n\t\tthis.querySelectorAll(\"button\").forEach(btn => {\n\t\t\tbtn.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\t}\n\n\t#togglePanel = () => {\n\t\ttrace.log(new Date());\n\t\tif (!this.#panel) {\n\t\t\t// 🎯 필터링 패널 방식과 동일하게 현재 셀이 속한 sheet(또는 그리드) 탐색\n\t\t\tthis.#panel = super.sheet.querySelector(\"cell-combo-panel\");\n\t\t\tif (!this.#panel) {\n\t\t\t\tthis.#panel = document.createElement(\"cell-combo-panel\");\n\t\t\t\tsuper.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\ttrace.log(new Date());\n\n\t\tif (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\t\tthis.#panel.close();\n\t\t} else {\n\t\t\tthis.#panel.open(this, this.#dataSource, this.#keyName, this.#valueName, this.#multi, this.#multiSeparator);\n\t\t}\n\n\t\ttrace.log(new Date());\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-combo {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n cell-combo.invalid .btn2::after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n cell-combo button {\n outline: none;\n cursor: pointer;\n font: inherit;\n }\n cell-combo button.btn1 {\n width: calc(100% - 24px);\n height: 26px;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n text-align: left;\n background-color: white;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 4px;\n color: #000;\n }\n cell-combo button.btn2 {\n padding: 3px;\n width: 24px;\n height: 26px;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #333;\n }\n cell-combo button.btn2:after {\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n </style>\n <button class=\"btn1\" type=\"button\" tabindex=\"-1\">Select</button>\n <button class=\"btn2\" type=\"button\" tabindex=\"-1\"></button>\n `;\n\n\t\t// Light DOM 구조이므로 this에서 직접 쿼리\n\t\tthis.#targetBtn = this.querySelector(\".btn1\");\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tif (!this.#targetBtn) return v;\n\n\t\t// 현재 값에 매칭되는 텍스트(표시명) 계산\n\t\tthis.#targetBtn.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#getDisplayText = () => {\n\t\tif (!this.value || !Array.isArray(this.#dataSource)) return \"\";\n\n\t\tif (this.#multi) {\n\t\t\tconst keys = String(this.value).split(this.#multiSeparator);\n\t\t\treturn this.#dataSource\n\t\t\t\t.filter(m => keys.includes(String(m[this.#keyName])))\n\t\t\t\t.map(m => m[this.#valueName])\n\t\t\t\t.join(this.#multiSeparator);\n\t\t} else {\n\t\t\tconst found = this.#dataSource.find(m => String(m[this.#keyName]) === String(this.value));\n\t\t\treturn found ? found[this.#valueName] : this.value;\n\t\t}\n\t}\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst list = this.#multi ? String(this.value).split(this.#multiSeparator) : [this.value];\n\t\tfor (const v of list) {\n\t\t\tconst idx = this.#dataSource.findIndex(m => String(v) === String(m[this.#keyName]));\n\t\t\tif (idx < 0) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-combo')) {\n\tcustomElements.define(\"cell-combo\", CellCombo);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\"; // Inherits from CellElement instead of EditableCellElement\n\nclass CellRenderer extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\t// Debug trace for inspecting component context and parent elements\n\t\t// trace.log(\"******************\", this, this.host, this.sheet, this.tr, this.cell);\n\n\t\tthis.#renderer();\n\n\t\t// Cache the internal text span target element\n\t\tthis.#target = this.querySelector(\"span\");\n\t}\n\n\t/**\n\t * Refreshes the cell display value based on binding and expression evaluations.\n\t */\n\trefresh = () => {\n\n\t\tsuper.refresh();\n\n\t\tif (this.cell.getAttribute(\"html\") === \"true\") {\n\t\t\tthis.#target.innerHTML = this.getDisplayText();\n\t\t} else {\n\t\t\tthis.#target.textContent = this.getDisplayText();\n\t\t}\n\t};\n\n\t/**\n\t * Renders the internal markup and CSS layout rules for the cell renderer.\n\t */\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <span></span>\n `;\n\t};\n}\n\n// Register the custom element if not already defined\nif (!customElements.get(\"cell-renderer\")) {\n\tcustomElements.define(\"cell-renderer\", CellRenderer);\n}","import { CellElement } from \"./core/CellElement.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { trace } from \"@nopeer\";\n\nexport class CellButton extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\t// 부모 클래스의 connectedCallback 호출 (필수)\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"button\");\n\n\t\tthis.#target.removeEventListener(\"click\", this.#cellButtonClick);\n\t\tthis.#target.addEventListener(\"click\", this.#cellButtonClick);\n\t}\n\n\t#cellButtonClick = e => {\n\t\te.stopPropagation();\n\n\t\tconst rowid = parseInt(this.cell.dataset.row, 10);\n\n\t\tconst customEvent = new CustomEvent(NINE_TABLE.EVENT.CELL_BUTTON_CLICK, {\n\t\t\tbubbles: true,\n\t\t\tcomposed: true,\n\t\t\tdetail: {\n\t\t\t\toriginalEvent: e,\n\t\t\t\tcell: this.cell,\n\t\t\t\trow: rowid,\n\t\t\t\tcol: parseInt(this.cell.dataset.col, 10),\n\t\t\t\tbind: this.dataset.bind,\n\t\t\t\tdata: this.host.data.get(rowid),\n\t\t\t\tvalue: this.value,\n\t\t\t}\n\t\t});\n\n\t\tthis.dispatchEvent(customEvent);\n\t};\n\n\t/**\n\t * 레거시 dataRefresh 패턴 반영 (표현식 동적 평가 및 스타일링)\n\t */\n\trefresh = () => {\n\t\tconst rawValue = super.refresh ? super.refresh() : this.value;\n\t\t//let displayValue = this.getDisplayText(rawValue);\n\t\tthis.#target.innerHTML = this.getDisplayText(rawValue);\n\n\t\t/**\n\t\t// 행 데이터 및 인덱스 확보\n\t\tconst rowIdx = parseInt(super.cell.dataset.row, 10);\n\t\tconst rowData = super.host?.data?.get ? super.host.data.get(rowIdx) : (this.closest(\"tr\")?.data);\n\n\t\tif (rowData && !isNaN(rowIdx)) {\n\t\t\t[\"color\", \"background\", \"border\"].forEach(attrName => {\n\t\t\t\tconst expr = this.getAttribute(attrName);\n\t\t\t\tif (expr && this.#target) {\n\t\t\t\t\tconst evaluatedVal = super.getExprValue ? super.getExprValue(expr, rowData, rowIdx, super.cell) : expr;\n\t\t\t\t\tthis.#target.style[attrName] = evaluatedVal;\n\t\t\t\t}\n\t\t\t});\n\t\t} */\n\t};\n\n\t#renderer = () => {\n\t\t/**\n\t\tconst allowedAttrs = [\"color\", \"background\", \"border\", \"class\", \"style\"];\n\t\tconst attrList = [];\n\n\t\tfor (let i = 0; i < this.attributes.length; i++) {\n\t\t\tconst attr = this.attributes[i];\n\t\t\tif (allowedAttrs.includes(attr.name)) {\n\t\t\t\tattrList.push(`${attr.name}=\"${attr.value}\"`);\n\t\t\t}\n\t\t} */\n\n\t\tconst cell = this.closest(\"th,td\");\n\n\t\tconst buttonText = \"...\";//this.getAttribute(\"text\") || super.attr[\"text\"] || \"\";\n\t\tconst height = (parseInt(cell.offsetHeight, 10) || 32) - 8;\n\n\t\tthis.innerHTML = `\n <style>\n /* 셀(td, th) 내부 패딩 제거 및 꽉 채우기 설정 */\n cell-button {\n display: flex;\n align-items: stretch;\n justify-content: stretch;\n width: 100%;\n height: ${height}px;\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n cell-button .button {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n border-radius: 0; /* 셀에 꽉 차게 보이려면 0이 깔끔할 수 있음 */\n border: 1px solid #d1d5db;\n background-color: #f3f4f6;\n color: #1f2937;\n outline: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n cell-button .button:hover {\n background-color: #e5e7eb;\n }\n cell-button .button:active {\n background-color: #d1d5db;\n }\n </style>\n <button class=\"button\">${buttonText}</button>\n `;\n\t};\n}\n\nif (!customElements.get('cell-button')) {\n\tcustomElements.define(\"cell-button\", CellButton);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRowIndicator extends CellElement {\n\t#mainTarget;\n\t#subTarget;\n\t#statusTarget;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback?.();\n\n\t\tif (this.cell) {\n\t\t\tthis.cell.removeAttribute(\"tabindex\");\n\t\t\tthis.cell.dataset.bind = \"rowState\";\n\n\t\t\tif (!this.cell.dataset.expr) {\n\t\t\t\tthis.cell.dataset.expr = \"data.__ng._[ninegrid.ROW.ORDER]\";\n\t\t\t}\n\n\t\t\tthis.cell.setAttribute(\"text-align\", \"center\");\n\t\t}\n\n\t\tthis.#mainTarget = this.querySelector(\".ng-row-main\");\n\t\tthis.#subTarget = this.querySelector(\".ng-row-sub\");\n\t\tthis.#statusTarget = this.querySelector(\".ng-row-status\");\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-row-indicator {\n display: block;\n position: absolute; /* 💡 셀 전체를 강제로 꽉 채움 */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n box-sizing: border-box;\n user-select: none;\n }\n /* 메인 행 번호 (중앙 정렬을 위해 플렉스 적용) */\n .ng-row-main {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n text-align: center;\n overflow: hidden;\n }\n \n /* 🎯 천단위 콤마 및 분할 스타일링 */\n .ng-row-prefix {\n \tfont-weight: normal;\n font-size: 0.40rem; /* 앞자리(천단위 이상)는 아주 작게 */\n }\n .ng-row-suffix {\n font-size: 0.55rem; /* 마지막 3자리 및 콤마는 현재 셀 기본 폰트 크기 유지 */\n }\n \n /* 우측 하단: 원본/이빨빠진 번호 */\n .ng-row-sub {\n position: absolute;\n right: 2px;\n bottom: 1px;\n font-size: 0.40rem;\n line-height: 1;\n opacity: 0.2;\n pointer-events: none;\n }\n /* 우측 상단: 상태 표시 */\n .ng-row-status {\n position: absolute;\n right: 2px;\n top: 1px;\n font-size: 0.55rem;\n line-height: 1;\n pointer-events: none;\n }\n </style>\n \n <span class=\"ng-row-main\"></span>\n <span class=\"ng-row-sub\"></span>\n <span class=\"ng-row-status\"></span>\n `;\n\t}\n\n\t/**\n\t * 행 번호 및 상태 갱신\n\t */\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tconst row = this.row;\n\t\tif (isNaN(row)) return;\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord && rawRecord.__ng) {\n\t\t\tconst rowState = rawRecord.__ng.rowState;\n\n\t\t\t/**\n\t\t\t// 1. 행 상태에 따른 클래스 제어 및 우측 상단 상태 표시\n\t\t\tif (rowState === ninegrid.ROW_STATE.INSERT) {\n\t\t\t\tthis.classList.add('added');\n\t\t\t\tthis.classList.remove('updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"➕\";\n\t\t\t} else if (rowState === ninegrid.ROW_STATE.UPDATE) {\n\t\t\t\tthis.classList.add('updated');\n\t\t\t\tthis.classList.remove('added');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"✏️\";\n\t\t\t} else {\n\t\t\t\tthis.classList.remove('added', 'updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"\";\n\t\t\t} */\n\n\t\t\t/**\n\t\t\t// 2. 필터링 등으로 순번이 밀렸을 때 우측 하단에 원본 번호 표시\n\t\t\tif (rawRecord.__ng.i !== undefined) {\n\t\t\t\tconst currentSeq = row + 1;\n\t\t\t\tconst originalSeq = rawRecord.__ng.i + 1;\n\n\t\t\t\tif (this.#subTarget) {\n\t\t\t\t\tif (currentSeq !== originalSeq) {\n\t\t\t\t\t\tthis.#subTarget.textContent = originalSeq;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#subTarget.textContent = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} */\n\t\t}\n\n\t\tconst displayNum = this.index + 1;\n\n\t\t// 천단위 콤마 포맷팅 (예: 1234567 -> \"1,234,567\")\n\t\tconst formattedNum = displayNum.toLocaleString();\n\n\t\t// 3자리 이상일 경우 마지막 3자리(와 콤마 포함된 덩어리)를 기준으로 앞자리와 분리\n\t\tif (displayNum >= 10000) {\n\t\t\t// 뒤에서 4글자(콤마 + 3자리)를 기준으로 분리합니다. (예: \"1,234\" 와 \"567\")\n\t\t\tconst splitIndex = formattedNum.length - 4;\n\t\t\tconst prefixPart = formattedNum.substring(0, splitIndex + 1); // 천단위 이상 (작은 폰트)\n\t\t\tconst suffixPart = formattedNum.substring(splitIndex + 1); // 마지막 콤마 + 3자리 (기본 폰트)\n\n\t\t\tthis.#mainTarget.innerHTML = `\n <span class=\"ng-row-prefix\">${prefixPart}</span>\n <span class=\"ng-row-suffix\">${suffixPart}</span>\n `;\n\t\t} else {\n\t\t\t// 1000 미만인 경우 콤마만 있거나 일반 숫자로 그대로 표시\n\t\t\tthis.#mainTarget.innerHTML = `${formattedNum}`;\n\t\t}\n\n\t\tconst isSorted = this.sheet.querySelector(\"thead .asc,thead .desc\") ? true : false;\n\t\tconst isFitered = this.sheet.querySelector(\"thead nine-table-filter-button.filtered\") ? true : false;\n\n\t\tthis.#subTarget.innerHTML = row;\n\t\tthis.#subTarget.style.display = (isSorted || isFitered) ? \"\" : \"none\";\n\t};\n}\n\nif (!customElements.get('cell-row-indicator')) {\n\tcustomElements.define(\"cell-row-indicator\", CellRowIndicator);\n}","// ui/col/col-expand.js\nimport { TableCompiler, COLLAPSED_WIDTH } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColExpand extends HTMLElement {\n #sheet;\n #cell;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#cell = this.closest('th, td');\n this.#sheet = this.closest('nine-table-sheet');\n\n if (this.#cell) {\n this.#cell.style.position = 'relative';\n }\n\n const isCollapsed =\n this.getAttribute('collapsed') === 'true' ||\n this.#cell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n requestAnimationFrame(() => {\n this.collapse(true);\n });\n } else {\n this.classList.remove('collapsed');\n this.classList.add('expand');\n }\n\n this.removeEventListener('click', this.#onClick);\n this.addEventListener('click', this.#onClick);\n }\n\n #onClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.classList.contains('expand')) {\n this.collapse();\n } else {\n this.expand();\n }\n };\n\n /**\n * 🎯 원래 너비(dataset.expandWidth)로 복구\n */\n expand = () => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n this.classList.remove('collapsed');\n this.classList.add('expand');\n this.#cell.setAttribute('collapsed', 'false');\n this.#cell.style.color = '';\n\n const targetWidth = parseInt(this.#cell.dataset.expandWidth, 10) || 100;\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, targetWidth);\n } else {\n const singleWidth = Math.max(30, Math.floor(targetWidth / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, singleWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n collapse = (isInitialInit = false) => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n if (this.classList.contains('expand')) {\n const col = this.#sheet.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n const currentW = col ? parseInt(col.getAttribute('width'), 10) : 0;\n if (currentW > COLLAPSED_WIDTH) {\n this.#cell.dataset.expandWidth = String(currentW * colSpan);\n }\n }\n\n this.classList.remove('expand');\n this.classList.add('collapsed');\n this.#cell.setAttribute('collapsed', 'true');\n this.#cell.style.color = 'transparent';\n\n // 🎯 colSpan이 1이면 16px(COLLAPSED_WIDTH)을 그대로 적용, 2 이상이면 균등 분할\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, COLLAPSED_WIDTH);\n } else {\n const splitWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, splitWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n disconnectedCallback() {\n this.removeEventListener('click', this.#onClick);\n }\n}\n\nif (!customElements.get('nine-table-col-expand')) {\n customElements.define('nine-table-col-expand', ColExpand);\n}","// ui/menu/nine-table-menu.js (수정본)\n\nimport { trace } from \"@nopeer\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nexport class ContextMenu extends HTMLElement {\n #tableHost;\n #panel;\n\n connectedCallback() {\n const root = this.getRootNode();\n this.#tableHost = root instanceof ShadowRoot ? root.host : (this.closest('nine-table') || root.host);\n\n if (!this.#tableHost) {\n this.#tableHost = this.parentElement?.closest('nine-table') || this.assignedSlot?.closest('nine-table');\n }\n\n if (!this.#tableHost) return;\n\n //this.#tableHost.addEventListener('contextmenu', this.#onContextMenu);\n }\n\n #onContextMenu = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n const targetCell = path.find(el => el.tagName === 'TH' || el.tagName === 'TD');\n\n if (!targetCell) return;\n\n const targetTable = path.find(el => el.tagName === 'TABLE') || targetCell.closest('table');\n\n e.preventDefault();\n e.stopPropagation();\n\n this.openMenu(e.clientX, e.clientY, targetCell, targetTable);\n };\n\n /**\n * 🎯 우클릭이 발생한 대상 시트(NineTableSheet) 구하기\n */\n #getTargetSheet(targetCell) {\n return targetCell?.closest('nine-table-sheet') || this.#tableHost.activeSheet || this.#tableHost;\n }\n\n #getFixManager(targetCell) {\n const sheet = this.#getTargetSheet(targetCell);\n if (!sheet) return null;\n\n if (!sheet.colFix) {\n sheet.colFix = new ColFixManager(sheet);\n }\n return sheet.colFix;\n }\n\n #parseCustomMenuItems(containerElement, activeTable) {\n const items = [];\n const activeTableId = activeTable?.id;\n const allUls = Array.from(containerElement.querySelectorAll(':scope > ul'));\n\n allUls.forEach(rootUl => {\n const targetTableAttr = rootUl.getAttribute('target-table');\n\n if (!targetTableAttr || (activeTableId && targetTableAttr === activeTableId)) {\n const parsedList = this.#traverseUl(rootUl);\n items.push(...parsedList);\n }\n });\n\n return items;\n }\n\n #traverseUl(ulEl) {\n const list = [];\n Array.from(ulEl.children).forEach(child => {\n const tagName = child.tagName.toLowerCase();\n\n if (tagName === 'hr' || child.classList.contains('separator')) {\n list.push({ type: 'separator' });\n return;\n }\n\n if (tagName === 'li') {\n let name = '';\n const spanEl = child.querySelector(':scope > span');\n if (spanEl) {\n name = spanEl.textContent.trim();\n } else {\n name = Array.from(child.childNodes)\n .filter(n => n.nodeType === Node.TEXT_NODE)\n .map(n => n.textContent.trim())\n .join('');\n }\n\n const subUl = child.querySelector(':scope > ul');\n const item = {\n menuId: child.id || name,\n name: name,\n className: child.className || '',\n disabled: child.hasAttribute('disabled') || child.getAttribute('disabled') === 'true',\n isCustom: true\n };\n\n if (subUl) {\n item.items = this.#traverseUl(subUl);\n }\n\n list.push(item);\n }\n });\n return list;\n }\n\n #buildMenuItems(activeTable, isHeaderCell, targetCell) {\n const useDefault = this.getAttribute('use-default-menu') !== 'false';\n let rawItems = [];\n\n const customItems = this.#parseCustomMenuItems(this, activeTable);\n if (customItems.length > 0) {\n rawItems.push(...customItems);\n }\n\n const fixManager = this.#getFixManager(targetCell);\n const currentFixState = fixManager?.getFixState(targetCell, activeTable) ?? 'none';\n const isFixable = isHeaderCell && (fixManager?.canFixColumn(targetCell, activeTable) ?? false);\n\n let fixMenuItem = null;\n if (currentFixState === 'left' || currentFixState === 'right') {\n fixMenuItem = {\n menuId: 'unfix-column',\n name: 'Unfix Column',\n className: 'ng-menu-unfix-col',\n disabled: !isHeaderCell\n };\n } else {\n fixMenuItem = {\n menuId: 'fix-column',\n name: 'Fix Column',\n className: 'ng-menu-fix-col',\n disabled: !isFixable\n };\n }\n\n if (useDefault) {\n rawItems.push(\n { type: 'separator' },\n {\n menuId: 'sort',\n name: 'Sort',\n className: 'ng-menu-sort',\n disabled: !isHeaderCell\n },\n fixMenuItem,\n { type: 'separator' },\n { menuId: 'filtering', name: 'Filtering', className: 'ng-menu-filtering' },\n { menuId: 'maximize', name: 'Maximize', className: 'maximize' },\n {\n menuId: 'export',\n name: 'Export',\n className: 'export',\n items: [\n { menuId: 'export-excel', name: 'Excel', className: 'export-excel' },\n { menuId: 'export-pdf', name: 'PDF', className: 'export-pdf', disabled: true }\n ]\n },\n {\n menuId: 'properties',\n name: 'Options',\n className: 'options',\n items: [\n { menuId: 'show-title-bar', name: 'Title Bar Show/Hide', className: 'show-title-bar' },\n { menuId: 'show-status-bar', name: 'Status Bar Show/Hide', className: 'show-status-bar' },\n { menuId: 'auto-fit-col', name: 'Auto Fit Columns', className: 'auto-fit-col' }\n ]\n }\n );\n }\n\n const cleanedItems = [];\n rawItems.forEach((item) => {\n if (item.type === 'separator') {\n if (cleanedItems.length === 0 || cleanedItems[cleanedItems.length - 1].type === 'separator') {\n return;\n }\n }\n cleanedItems.push(item);\n });\n\n if (cleanedItems.length > 0 && cleanedItems[cleanedItems.length - 1].type === 'separator') {\n cleanedItems.pop();\n }\n\n return cleanedItems;\n }\n\n openMenu(x, y, targetCell, targetTable) {\n const targetParent = this.#tableHost.shadowRoot || this.#tableHost;\n\n if (!this.#panel) {\n this.#panel = document.createElement('nine-table-menu-panel');\n targetParent.appendChild(this.#panel);\n }\n\n const isHeaderCell = !!targetCell.closest('thead');\n const menuItems = this.#buildMenuItems(targetTable, isHeaderCell, targetCell);\n\n this.#panel.render(menuItems, (e) => this.#handleMenuClick(e, targetCell, targetTable));\n\n const targetSheet = this.#getTargetSheet(targetCell);\n this.#syncMenuStates(targetSheet);\n\n // 🎯 targetCell을 3번째 인자로 전달하여 셀 우측선 정렬\n this.#panel.openAt(x, y);\n }\n\n /**\n * 🎯 메뉴 항목 활성화 체크 표시(✓) 동기화\n */\n #syncMenuStates(targetSheet) {\n if (!this.#panel || !targetSheet) return;\n\n // 🎯 클릭된 개별 시트의 filtering 상태 검사\n const isFiltering = targetSheet.filtering?.isFiltering?.() || false;\n this.#panel.toggleItemState('filtering', 'on', isFiltering);\n\n const autoFit = this.#tableHost.getAttribute('auto-fit-col') === 'true';\n this.#panel.toggleItemState('auto-fit-col', 'on', autoFit);\n\n const showTitle = this.#tableHost.getAttribute('show-title-bar') === 'true';\n this.#panel.toggleItemState('show-title-bar', 'on', showTitle);\n }\n\n #handleMenuClick(e, targetCell, targetTable) {\n const menuId = e.menuId;\n\n const customEvent = new CustomEvent('menu-click', {\n detail: { menuId, targetCell, targetTable, originalEvent: e },\n bubbles: true,\n composed: true\n });\n this.dispatchEvent(customEvent);\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n\n // 🎯 클릭된 셀의 소속 시트 인스턴스 타겟팅\n const targetSheet = this.#getTargetSheet(targetCell);\n\n switch (menuId) {\n case 'fix-column':\n case 'unfix-column':\n const fixManager = this.#getFixManager(targetCell);\n fixManager?.executeFixToggle(menuId, targetCell);\n break;\n\n case 'sort':\n if (!isNaN(baseCol)) {\n targetSheet.sorting?.handleSortFromMenu?.(baseCol, targetCell);\n }\n break;\n\n case 'filtering':\n targetSheet?.filtering?.toggle();\n break;\n\n case 'auto-fit-col':\n this.#tableHost.setAttribute('auto-fit-col', this.#tableHost.getAttribute('auto-fit-col') === 'true' ? 'false' : 'true');\n break;\n\n case 'show-title-bar':\n this.#tableHost.setAttribute('show-title-bar', this.#tableHost.getAttribute('show-title-bar') === 'true' ? 'false' : 'true');\n break;\n }\n\n this.#panel.close();\n }\n\n disconnectedCallback() {\n this.#tableHost?.removeEventListener('contextmenu', this.#onContextMenu);\n }\n}\n\nif (!customElements.get('nine-table-menu')) {\n customElements.define('nine-table-menu', ContextMenu);\n}","// ui/menu/nine-table-menu-panel.js\n\nexport class MenuPanel extends HTMLElement {\n #onCallback;\n #closeHandler = null; // 🎯 이벤트 누수 방지용 리스너 참조\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n // 🎯 [보정 1] 패널 자체의 기본 레이아웃 스타일은 element style로 직접 지정\n this.style.position = 'fixed';\n this.style.display = 'none';\n this.style.zIndex = '99999';\n\n this.innerHTML = `\n <style>\n \n nine-table-menu-panel .menu-wrapper {\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 150px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 12px;\n }\n nine-table-menu-panel ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n nine-table-menu-panel li {\n position: relative;\n padding: 6px 16px;\n cursor: pointer;\n color: #374151;\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n }\n nine-table-menu-panel li:hover {\n background-color: #f3f4f6;\n color: #111827;\n }\n nine-table-menu-panel li.on::before {\n content: '✓';\n position: absolute;\n left: 4px;\n font-weight: bold;\n }\n nine-table-menu-panel li.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background: transparent !important;\n }\n nine-table-menu-panel li.ng-menu-separator {\n height: 1px;\n background: #e5e7eb;\n margin: 4px 0;\n padding: 0;\n cursor: default;\n }\n nine-table-menu-panel li.submenu::after {\n content: '▶';\n font-size: 9px;\n margin-left: 8px;\n color: #9ca3af;\n }\n nine-table-menu-panel .ng-menu-sublist {\n display: none;\n position: absolute;\n top: -4px;\n left: 100%;\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 140px;\n }\n nine-table-menu-panel li.submenu:hover > .ng-menu-sublist {\n display: block;\n }\n </style>\n <div class=\"menu-wrapper\">\n <ul class=\"menu-container\"></ul>\n </div>\n `;\n }\n\n render(items, callback) {\n this.#onCallback = callback;\n const container = this.querySelector('.menu-container');\n if (!container) return;\n\n container.innerHTML = '';\n\n this.#appendItems(container, items);\n this.#bindClickEvents();\n }\n\n /**\n * 🎯 패널의 우측선과 targetCell의 우측선을 일치시키는 포지셔닝\n */\n openAt(x, y, targetCell = null) {\n this.style.display = 'block';\n\n if (targetCell) {\n const cellRect = targetCell.getBoundingClientRect();\n // 셀의 오른쪽 경계선 좌표\n const cellRightX = cellRect.right;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const panelWidth = wrapper.getBoundingClientRect().width;\n\n // 패널 우측선을 셀 우측선에 맞춤 (Left = cellRight - panelWidth)\n let calculatedLeft = cellRightX - panelWidth;\n\n // 뷰포트 왼쪽 밖으로 벗어나는 예외 처리\n if (calculatedLeft < 0) {\n calculatedLeft = cellRect.left; // 공간이 부족하면 셀 좌측선에 맞춤\n }\n\n // 뷰포트 아래쪽 벗어남 처리\n const panelHeight = wrapper.getBoundingClientRect().height;\n let calculatedTop = y;\n if (y + panelHeight > window.innerHeight) {\n calculatedTop = y - panelHeight;\n }\n\n this.style.left = `${calculatedLeft}px`;\n this.style.top = `${calculatedTop}px`;\n });\n } else {\n // 기본 마우스 클릭 좌표 기반 (Fallback)\n this.style.left = `${x}px`;\n this.style.top = `${y}px`;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n\n if (x + rect.width > window.innerWidth) {\n this.style.left = `${x - rect.width}px`;\n }\n if (y + rect.height > window.innerHeight) {\n this.style.top = `${y - rect.height}px`;\n }\n });\n }\n\n // 바깥 클릭 핸들러 등록\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n }\n\n this.#closeHandler = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (!path.includes(this) && !this.contains(e.target)) {\n this.close();\n }\n };\n\n setTimeout(() => {\n window.addEventListener('pointerdown', this.#closeHandler);\n }, 0);\n }\n\n close() {\n this.style.display = 'none';\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n this.#closeHandler = null;\n }\n }\n\n toggleItemState(menuId, className, condition) {\n const li = this.querySelector(`li[menu-id=\"${menuId}\"]`);\n if (li) {\n condition ? li.classList.add(className) : li.classList.remove(className);\n }\n }\n\n #appendItems(parentUl, items) {\n items.forEach(item => {\n if (item.type === 'separator') {\n const sep = document.createElement('li');\n sep.className = 'ng-menu-separator';\n parentUl.appendChild(sep);\n return;\n }\n\n const li = document.createElement('li');\n li.setAttribute('menu-id', item.menuId);\n li.className = `${item.className || ''} ${item.items ? 'submenu' : ''} ${item.disabled ? 'disabled' : ''}`.trim();\n\n const span = document.createElement('span');\n span.textContent = item.name;\n li.appendChild(span);\n\n if (item.items && item.items.length > 0) {\n const subUl = document.createElement('ul');\n subUl.className = 'ng-menu-sublist';\n this.#appendItems(subUl, item.items);\n li.appendChild(subUl);\n }\n\n parentUl.appendChild(li);\n });\n }\n\n #bindClickEvents() {\n this.querySelectorAll('li[menu-id]').forEach(li => {\n li.addEventListener('click', (e) => {\n e.stopPropagation();\n if (li.classList.contains('disabled')) return;\n\n const menuId = li.getAttribute('menu-id');\n this.#onCallback?.({ menuId, target: li });\n this.close();\n });\n });\n }\n\n disconnectedCallback() {\n this.close();\n }\n}\n\nif (!customElements.get('nine-table-menu-panel')) {\n customElements.define('nine-table-menu-panel', MenuPanel);\n}"],"names":["target","start","end","mid","elementDebounceState","dblClickEvent","dblClickFn","pointerEvent","pointerFn","debounceTime","el","state","e","_text","_font","stripHtml","__name","html","tmp","canvas","context","w","h","v","cleanText","metrics","ascent","descent","_Trace","traceOrigin","Trace","trace","NINE_TABLE","_ngRow","parent","__privateAdd","_parent","_newrow","__publicField","__privateGet","__privateSet","ngRow","_ngData","host","_host","_nextId","_defaultHeight","_getValidRecords","o","_a","at","colnm","validRecords","targetRecord","idx","rowIndex","colIndex","value","rowData","_conv","fields","_initialize","templateElements","_getDefaultMeta","_invalidate","$sheets","$el","dataSource","loadData","rowid","_json2Array","jsonArray","arr","json","_defaultInsert","updateState","row","_","a","b","rowidx","targetId","item","COL_IDX","oldValue","isSingle","targetArr","result","t","i","__privateWrapper","ngData","_ngDataManager","ds","nRow","rowIdx","_b","ngDataManager","_fields","type","fName","f","_adjust","map","name","_init","rawTables","tbl","fieldName","fieldType","attr","expr","lastIndex","targetField","found","_NineTableSheets","NineTableSheets","_NineTableSheetsFooter","_NineTableSheetsFooter_instances","__privateMethod","render_fn","isMultiSelect","tabItem","index","_switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","tab","isActive","clickedTab","activeTabs","targetSheet","tabsHtml","table","className","tabName","NineTableSheetsFooter","_SheetTabItem","SheetTabItem","_Toolbar","_Toolbar_instances","_customContainer","bindEvents_fn","element","text","titleEl","syncStateFromHost_fn","isSimple","showToolbar","showMenu","caption","link","currentCaption","menuBtn","Toolbar","_NineTableHScrollBar","_owner","_dragging","_elements","_interval1","_interval2","_resizeObserver","_observeResize","track","thumb","bodyWidth","tableWidth","needsHScroll","trackWidth","thumbWidth","currentLeft","maxScrollLeft","l","maxThumbLeft","_thumbMoveTo","x","trackBound","targetX","newScrollLeft","headerBody","footerBody","delayScroll","pos","thumbLeft","currentThumbLeft","clearTimer","evt","trackRect","onMouseMove","moveEvent","onMouseUp","initWhenReady","NineTableHScrollBar","_NineTableVScrollBar","_sheet","_startY","_startScrollTop","_startThumbTop","_getScaleInfo","viewRecords","totalCount","scrollHolder","rawContentHeight","rowHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","_getViewHeight","thead","_c","tfoot","_f","_e","_d","tbodyHead","_j","_i","_h","_g","fixedHeight","bodyHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","deltaY","targetThumbTop","ratio","viewHeight","visibleRowCount","targetRow","clickY","currentTopRow","NineTableVScrollBar","GROUP_IDX","_GroupingManager","_groupColumns","_groupMap","_isApplying","groupColumns","sourceTable","$tr","$cell","groupId","rowIds","dataManager","GroupingManager","_Grouping","rawRecords","validRaw","groupMap","nestedTree","_Grouping_static","buildNestedMap_fn","flatResult","renderItems","flattenTree_fn","mapOrArray","depth","resultArr","parentId","counter","isLastLevel","groupKey","subMapOrRecords","collectLeafRowIds_fn","groupRecord","collectLeafRecords_fn","record","records","remainingCols","key","subRecords","subVal","r","Grouping","_RowManager","_BUFFER_ROW_COUNT","_element","_containerTemplates","_templateRowHeights","_cachedTemplateHeight","_sheetHeight","_cachedRowCount","_isProgrammaticScroll","_isGrouped","force","bodyViewport","_measureAndCacheHeight","_renderAllContainers","_handleScroll","scrollTop","_handleGroupedScroll","templateLength","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","renderOffsetTop","firstTr","currentStartIndex","$tbody","tbodyIdx","dataIndex","_bindRowData","allRenderItems","totalVirtualCount","bodyContent","getItemHeight","dataRowsHeight","groupHeightsTotal","itemHeights","viewportClientHeight","accumulatedHeight","offsetY","visibleRowsCount","dynamicBuffer","targetStart","targetEnd","renderedItems","selector","container","trs","itemIndex","chunkTrs","tr","subIdx","virtualIndex","isTrGroup","_bindGroupRowData","subRowIndex","matrixRow","indices","allRecords","childrenRecords","customComp","tableEl","tbody","templateTrs","trTemplates","fragment","renderedTrs","sum","_updateRowCount","visibleRows","groupDepth","_renderRows","_syncRowHeights","targetFixedType","clonedTr","targetTbody","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","_initResizeObserver","entries","entry","height","dataRow","align","onRendered","targetScrollTop","rawTargetScrollTop","RowManager","COLLAPSED_WIDTH","_TableCompiler","$srcTable","$table","_TableCompiler_static","syncColAttributes_fn","cols","grid","rowSpan","colSpan","c","$col","fixed","TableCompiler","_CellSelection","_CellSelection_instances","_range","startRow","startCol","endRow","endCol","containers","getMatrixRow_fn","cell","col","cellEndRow","cellEndCol","$focusTd","initEvents_fn","$td","r1","r2","c1","c2","expanded","loopCount","nsR","neR","nsC","neC","sameGroupTrs","mainZone","lastMatrixRow","lastCol","targetEl","targetCell","allCells","rect","targetTr","CellSelection","_CellNavigation","_CellNavigation_instances","_currentCell","_currentTr","_currentRow","_currentCol","_getMinCol","cells","minCol","_getMaxCol","maxCol","_getMaxColCell","targetTrs","_getNextCol","td","next","_getPreviousCol","currentCol","currentTrCells","_findTargetTrsByMatrix","smallerCols","matchedTrs","mRow","getMatrixRowFromTr_fn","foundInSpan","_getNearElement","targetMatrixRow","searchedTrs","trDataRow","trSubIdx","span","cellDataRowStart","cellSubRowStart","cellStartMatrix","cellEndMatrix","nextMatrixRow","nextCol","prevTrs","maxColCell","maxMatrixRowLimit","maxMatrixRow","nextDataRow","nextSubRowIndex","retries","actualMatrixRow","ensureCellVisible_fn","retryCell","mRowAttr","bodyContainer","cellRect","viewportRect","containerRect","headerRect","isAbove","isBelow","subrow","CellNavigation","RESIZE_OFFSET","_ColResizer","_ColResizer_instances","_panel","_tooltip","_targetColIndex","_nextColIndex","_targetContainerType","_targetCell","_startX","_startColWidth","_nextColStartWidth","_startCellWidth","_startLeft","_onPointerMove","headerPart","offsetX","isLeftEdge","isRightEdge","prevCell","_onPointerDown","getContainerType_fn","baseColIndex","checkIsAutoFit_fn","nextColEl","targetRect","sheetRect","targetColEl","attrW","updatePositions_fn","_onDragMove","_onDragEnd","diff","isAutoFit","finalWidth","newColWidth","newNextWidth","_onDblClick","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","val","size","calculatedWidth","containerType","firstColgroup","totalWidth","colWidths","colIdx","tables","globalColIndex","width","targetCols","firstContainer","resolvedContainerType","sourceCol","clientX","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","ColResizer","_ColMover","_ColMover_instances","_grip","_indi","_isDragging","_sourceCell","_sourceColIndex","_shiftX","_timer","checkIsMovable_fn","startX","startY","cancelTimer","onPointerMovePending","startDrag_fn","updateGripPosition_fn","targetElement","getDeepElementFromPoint_fn","targetColIndex","colMinLeft","colMaxRight","cCol","cSpan","cEnd","cRect","midX","calculatedTargetCol","indicatorLeft","sourceGroup","getColGroupRange_fn","movingSpan","sourceRowStart","sourceRowSpan","sourceRowEnd","targetRowStart","targetRowSpan","targetRowEnd","isRowSpanCompatible","isOutOfBoundsOfParent","pStart","pEnd","isDroppingInsideOtherGroup","spannedCells","sCell","sRowStart","sRowSpan","sRowEnd","sStart","sSpan","sEnd","moveEndCol","isSelfGroup","relativeTop","fullHeight","_onPointerUp","fromColIndex","toColIndex","colgroup","targetCol","spanCount","isInRange","targetViewportCol","fixedType","group","targetRowCell","y","root","nested","headerCells","hasStrictChildren","isValidGroup","parentGroupRange","subCell","subStart","subSpan","subEnd","isRealGroup","createGroupHeaderPreview_fn","groupRange","isGroup","origTable","minLeft","maxRight","minTop","maxBottom","targetCells","computedStyle","groupWidth","groupHeight","headerContent","style","clonedCell","preview","bounds","left","ColMover","_ColFixManager","baseCol","colEl","fixedAttr","targetBoundaryCol","theadTrs","cellBoundaryFound","cEndCol","action","fixType","cIdx","minBaseCol","rIdx","rSpan","trIndex","isBroken","correspondingCol","isColFixed","ColFixManager","_NineTableFilterPanel","_NineTableFilterPanel_instances","_nineTable","_view","_button","_renderer","_onInput","_onSelectAll","_onOk","_closeHandler","path","filterRecords","checkedRecords","chk","filterParams","colInfo","filterKey","selectedVals","btn","query","data2Idx","matchedValues","isChecked","chkIdx","_onCancel","filterBtn","panelWidth","top","searchBox","loadVirtualFilterItems_fn","filteredRecords","activeFilters","exprEngine","bindKey","exprKey","activeSelectedVals","uniqueMap","rawVal","displayVal","uniqueList","selectAllChk","NineTableFilterPanel","_NineTableFilterButton","_columns","isFiltered","_onClick","panel","seen","uniqueKey","NineTableFilterButton","_Filtering","_Filtering_instances","_isFiltering","_filterPanel","_filters","_initFilterPanel","applyFiltering_fn","oFilter","jsonFilter","k","sheetIndex","filterRules","targetKey","allowedValues","isExpr","recordIdx","isPass","allowedSet","Filtering","_Sorting","_Sorting_instances","syncHeaderUI_fn","handleSort_fn","colName","exprVal","isAsc","isDesc","existingColIndex","m","ruleData","applySorting_fn","colRule","asc","Sorting","_SheetView","_sortingColumns","_filterRules","_viewIndexes","_cachedVisibleRecords","visibleRecords","_convSingle","filterSlot","_applySorting","groupResult","columns","rulesWithIdx","rule","idxA","idxB","valA","valB","isEmptyA","isEmptyB","strA","strB","SheetView","_PreCompiler","_PreCompiler_static","ensureColgroup_fn","ensureThead_fn","ensureSectionTbodys_fn","ensureRowIndicator_fn","normalizeColAttributes_fn","createColIndicator_fn","normalizeCollapsibleAttributes_fn","generateCell_fn","initColExpanders_fn","initFilterButtons_fn","_k","applyInitialCellWidths_fn","tdTmpl","firstRow","cnt","numToExcelCol_fn","background","num","n","headTbody","footTbody","colCount","containerWidth","defaultWidth","widthVal","$tbl","targetAttributes","autoIdCounter","tagName","$datalist","$option","uniqueFuncName","innerAttrs","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","section","rows","indicatorCell","startColIdx","targetIdx","PreCompiler","_NineTableSheet","_NineTableSheet_instances","_index","_rowManager","_cellSelection","_cellNavigation","_colResizer","_colMover","_colFix","_sorting","_filtering","_grouping","_source","_adjustOverlay","$thead","$overlay","enable","_autoFit","totalOriginalWidth","colList","headerCell","collapsedTotalWidth","availableWidth","allocatedTotal","calculatedCols","exactWidth","baseWidth","remainderPixels","uncollapsedCols","finalSumWidth","_renderSplitContainers","_updateContainerWidths","_syncHeaderAndFooterHeights","_initRowHoverEvent","prefix","firstTable","_createSplitTable","scrollLeft","_render","isSimple_get","leftHeaderRows","bodyHeaderRows","rightHeaderRows","_applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","attrTrue","sourceTableTrue","NineTableSheet","_LayoutManager","owner","_applyAutoHeight","maxDisplayRows","maxRowHeight","toolbarEl","footerEl","toolbarHeight","footerHeight","calculatedHeight","isAutoHeight","sheetCount","sheetsHtml","sheetId","sheetTag","splitterTag","cssFiles","npmCssImports","file","customCssImports","LayoutManager","_ExprEngine","_exprCache","match","rowItem","trimmedExpr","compiledExpr","evalFn","ExprEngine","_NineTable","_NineTable_instances","_shadowRoot","_dataManager","_layoutManager","_templateCnt","_dispatchLoad","checkCount","maxChecks","checkTimer","loadSheetCnt","$sheet","idOrIndex","fn","bindDynamicSetters_fn","extractedMethodNames","matches","methodName","internalValue","newValue","NineTable","_BasicCellElement","BasicCellElement","exprCache","_CellElement","_tr","_cell","_attr","defaultValue","rawRecord","cleanExpr","childRecords","funcName","field","acc","button","curRow","renderer","prop","updateRowState","data","CellElement","_EditableCellElement","EditableCellElement","_CellInputText","_target","_initEvent","maxbyte","maxByteNum","event","CellInputText","_CellInputNumber","_validateInput","strVal","dotIdx","_onKeyDown","selectionStart","scale","validKey","isNumKey","CellInputNumber","_CellInputColor","_btn","_isValidColor","g","CellInputColor","_CellInputDate","_type","formattedVal","d","min","max","isValid","_isValidDate","year","month","day","isleap","hour","week","CellInputDate","_CellCheckbox","_label","_isRadio","_trueText","_falseText","newVal","trueValue","childHtml","displayText","CellCheckbox","_CellRadio","_dataSource","_keyName","_valueName","matchIndex","targets","_rendererRadio","codeVal","nameVal","label","input","CellRadio","_CellComboPanel","_isOpen","_initData","keyName","valueName","multi","separator","grd","itemsAttr","fieldKeys","activeColumnCount","formattedData","selectedKeys","btnEl","btnRect","panelHeight","upwardTop","viewContainer","_onClickRow","keyword","_initEvents","CellComboPanel","_CellCombo","_targetBtn","_multi","_multiSeparator","_togglePanel","_getDisplayText","keys","list","CellCombo","_CellRenderer","CellRenderer","_CellButton","_cellButtonClick","customEvent","rawValue","buttonText","CellButton","_CellRowIndicator","_mainTarget","_subTarget","_statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","CellRowIndicator","_ColExpand","singleWidth","isInitialInit","currentW","splitWidth","ColExpand","_ContextMenu","_ContextMenu_instances","_tableHost","_onContextMenu","targetTable","targetParent","isHeaderCell","menuItems","buildMenuItems_fn","handleMenuClick_fn","getTargetSheet_fn","syncMenuStates_fn","getFixManager_fn","parseCustomMenuItems_fn","containerElement","activeTable","items","activeTableId","rootUl","targetTableAttr","parsedList","traverseUl_fn","ulEl","child","spanEl","subUl","useDefault","rawItems","customItems","fixManager","currentFixState","isFixable","fixMenuItem","cleanedItems","isFiltering","autoFit","showTitle","menuId","ContextMenu","_MenuPanel","_MenuPanel_instances","_onCallback","callback","appendItems_fn","bindClickEvents_fn","cellRightX","wrapper","calculatedLeft","calculatedTop","condition","li","parentUl","sep","MenuPanel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nine-table.umd.js","sources":["../src/core/protype.js","../src/external/NoPeer.js","../src/core/constants.js","../src/data/ngData.js","../src/data/ngDataManager.js","../src/data/Fields.js","../src/ui/layout/nine-table-sheets.js","../src/ui/layout/nine-table-sheets-footer.js","../src/ui/layout/nine-table-toolbar.js","../src/ui/layout/nine-table-hscrollbar.js","../src/ui/layout/nine-table-vscrollbar.js","../src/data/Grouping.js","../src/ui/layout/core/RowManager.js","../src/ui/layout/core/TableCompiler.js","../src/ui/cell-manager/CellSelection.js","../src/ui/cell-manager/CellNavigation.js","../src/ui/col/ColResizer.js","../src/ui/col/ColMover.js","../src/ui/col/ColFixManager.js","../src/data/Filtering.js","../src/data/Sorting.js","../src/data/SheetView.js","../src/ui/layout/core/PreCompiler.js","../src/ui/layout/nine-table-sheet.js","../src/ui/layout/core/LayoutManager.js","../src/core/ExprEngine.js","../src/core/nine-table.js","../src/ui/cell/core/BasicCellElement.js","../src/ui/cell/core/CellElement.js","../src/ui/cell/cell-input-text.js","../src/ui/cell/cell-input-number.js","../src/ui/cell/cell-input-color.js","../src/ui/cell/cell-input-date.js","../src/ui/cell/cell-checkbox.js","../src/ui/cell/cell-radio.js","../src/ui/cell/cell-combo-panel.js","../src/ui/cell/cell-combo.js","../src/ui/cell/cell-renderer.js","../src/ui/cell/cell-button.js","../src/ui/cell/cell-row-indicator.js","../src/ui/col/col-expand.js","../src/ui/menu/nine-table-menu.js","../src/ui/menu/nine-table-menu-panel.js"],"sourcesContent":["Array.prototype.nineBinarySearch = function(target) {\n //this.sort((a, b) => { return a > b ? 1 : -1; });\n\n let start = 0;\n let end = this.length - 1;\n let mid;\n\n while (start <= end) {\n mid = parseInt((start + end) / 2);\n\n if (target === this[mid]) {\n return mid;\n } else {\n if (target < this[mid]) {\n end = mid - 1;\n } else {\n start = mid + 1;\n }\n }\n }\n\n return -1;\n};\n\n// 엘리먼트별 디바운스/취소 상태를 격리하기 위한 WeakMap\nconst elementDebounceState = new WeakMap();\n\nHTMLElement.prototype.addDebounseEventListener = function(\n dblClickEvent,\n dblClickFn,\n pointerEvent,\n pointerFn,\n debounceTime = 500\n) {\n const el = this;\n\n if (!elementDebounceState.has(el)) {\n elementDebounceState.set(el, { timer: null, cancelFn: null });\n }\n const state = elementDebounceState.get(el);\n\n // 1. 포인터(다운) 이벤트: 즉시 실행하지 않고 debounceTime 동안 지연시킴\n el.addEventListener(pointerEvent, (e) => {\n e.actualTarget = e.target;\n\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n\n // 💡 500ms 동안 대기한 뒤에야 실제 pointerFn이 실행됨\n state.timer = setTimeout(() => {\n state.timer = null;\n state.cancelFn = pointerFn.call(el, e);\n }, debounceTime);\n });\n\n // 2. 더블클릭 이벤트: 대기 시간 내에 들어오면 예약되어 있던 pointerdown 자체를 원천 차단\n el.addEventListener(dblClickEvent, (e) => {\n //trace.log(e);\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null; // 💡 pointerdown 실행 예약이 아예 취소됨!\n }\n\n // 혹시 이미 실행되어 버린 경우의 안전장치 롤백\n if (state.cancelFn) {\n state.cancelFn();\n state.cancelFn = null;\n }\n\n dblClickFn.call(el, e);\n });\n};\n\n\nnine.measureTextSize = (_text, _font = '12px sans-serif') => {\n if (typeof _text === 'number') _text = _text + \"\";\n if (!_text) return { width: null, height: null };\n\n // 🎯 브라우저 DOM 파싱을 이용한 완벽한 HTML 태그 제거 함수\n const stripHtml = (html) => {\n const tmp = document.createElement(\"DIV\");\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || \"\";\n };\n\n // 줄바꿈 처리 전 HTML 정제 또는 줄바꿈 단위별 정제\n _text = _text.replaceAll(\"\\n\", \"<br>\");\n\n // 🎯 공용 숨김 캔버스를 querySelector로 찾거나 없으면 생성\n let canvas = document.body.querySelector('canvas#_nine_measure_canvas_');\n if (!canvas) {\n canvas = document.createElement('canvas');\n canvas.id = '_nine_measure_canvas_';\n canvas.style.cssText = 'position: absolute; visibility: hidden; pointer-events: none; left: -9999px;';\n document.body.appendChild(canvas);\n }\n\n const context = canvas.getContext('2d');\n context.font = _font;\n\n let w = 0;\n let h = 0;\n\n for (let v of _text.split(\"<br>\")) {\n // 브라우저 파서로 HTML 태그를 완전히 제거한 순수 텍스트 획득\n const cleanText = stripHtml(v);\n const metrics = context.measureText(cleanText);\n\n //trace.log(cleanText);\n\n w = Math.max(w, metrics.width);\n\n const ascent = metrics.fontBoundingBoxAscent || 10;\n const descent = metrics.fontBoundingBoxDescent || 3;\n h += ascent + descent;\n }\n\n return {\n width: w,\n height: h\n };\n};","import { trace as traceOrigin } from '@ninebone/util';\n\n/**\n// 1. 내부 프라이빗 필드 문제를 피하기 위해 래퍼 객체 생성\nexport const trace = {\n init(prefix, color) {\n // 필요하다면 여기서 초기화 로직 수행 가능\n if (traceOrigin.init) {\n try { traceOrigin.init(prefix, color); } catch (e) {}\n }\n },\n log(...args) {\n return traceOrigin.log(...args);\n },\n warn(...args) {\n return traceOrigin.warn(...args);\n },\n error(...args) {\n return traceOrigin.error(...args);\n }\n};\n\n// 2. 모듈 로드 시점에 네임스페이스 초기화 시도\ntry {\n traceOrigin.init(\"nine-table\", \"green\");\n} catch (e) {}\n*/\n\n\nexport class Trace extends traceOrigin.constructor {\n constructor() {\n super();\n this.init(\"nine-table\", \"green\");\n }\n}\n\nexport const trace = new Trace();\n\n\n//trace.init(\"nine-table\", \"green\");","export const NINE_TABLE = {\n META: {\n INDEX: {\n ROWID: 0,\n FILTER: 1, // 멀티뷰 필터 통과 여부 (true/false)\n GROUP: 2,\n // SELECT: 2,\n // EXPAND: 3\n }\n },\n ROW_STATE: {\n EMPTY: 'EMPTY',\n NORMAL: 'NORMAL',\n INSERT: 'INSERT',\n UPDATE: 'UPDATE',\n DELETE: 'DELETE'\n },\n EVENT: {\n LOAD: \"load\",\n CELL_BUTTON_CLICK: \"cell-button-click\",\n },\n};","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\n\r\nexport class ngRow {\r\n\t#parent;\r\n\t#newrow = -1;\r\n\r\n\tconstructor(parent) {\r\n\t\tthis.#parent = parent;\r\n\t}\r\n\r\n\tget at() {\r\n\t\treturn this.#newrow;\r\n\t}\r\n\tset at(v) {\r\n\t\tthis.#newrow = parseInt(v, 10);\r\n\t}\r\n\r\n\tcount = () => this.#parent.rawRecords.length;\r\n}\r\n\r\nexport class ngData {\r\n\t#host;\r\n\t#parent;\r\n\t#nextId = 0;\r\n\t#defaultHeight = [];\r\n\r\n\tstatic META_INDEX = {\r\n\t\tFILTER: 0, // 멀티뷰 필터 통과 여부 (true/false)\r\n\t\t// ── 추후 확장 예시 ──\r\n\t\t// GROUP: 1,\r\n\t\t// SELECT: 2,\r\n\t\t// EXPAND: 3\r\n\t};\r\n\r\n\t// 🎯 행 상태 정의 상수 내재화\r\n\tstatic ROW_STATE = {\r\n\t\tEMPTY: 'EMPTY',\r\n\t\tNORMAL: 'NORMAL',\r\n\t\tINSERT: 'INSERT',\r\n\t\tUPDATE: 'UPDATE',\r\n\t\tDELETE: 'DELETE'\r\n\t};\r\n\r\n\tconstructor(host, parent) {\r\n\t\tthis.#host = host;\r\n\t\tthis.#parent = parent;\r\n\t\tthis.#initialize();\r\n\t}\r\n\r\n\r\n\r\n\t/**\r\n\t * 🎯 [내부 공통] 삭제되지 않은 유효 레코드 목록 반환 (중복 제거 및 캡슐화)\r\n\t */\r\n\t#getValidRecords = () => {\r\n\t\tconst rawRecords = this.#parent.rawRecords || [];\r\n\t\treturn rawRecords.filter(o => !o.__ng?.deleted);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 행 개수 반환 (속성 및 메서드 형태 모두 지원)\r\n\t */\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tcount = () => {\r\n\t\treturn this.length;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [내부 엔진/고성능용] 변환 오버헤드 없이 순수 데이터(v 배열 등) 그대로 반환\r\n\t * - data.getArray() : 유효한 전체 내부 레코드 배열 반환\r\n\t * - data.getArray(at) : 특정 행의 내부 레코드 객체({ v: [...] }) 반환\r\n\t * - data.getArray(at, colnm) : 특정 행의 특정 컬럼 원시 값 반환\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn validRecords; // 변환 없이 배열 그대로 반환 (렌더링 최적화)\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord; // { v: [...], __ng: {...} } 원본 형태 반환\r\n\t};\r\n\r\n\tsetArray = (rowIndex, colIndex, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\r\n\t\tconst oldValue = rowData.v[colIndex];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\t// 변경 전 값 보존 우선 주석처리\r\n\t\t\t//rowData.o[colIndex] = value;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[colIndex] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\r\n\t/**\r\n\t * 🎯 [외부 개발자/비즈니스 로직용] 개발자가 활용하기 편한 JSON 객체 형태로 변환하여 반환\r\n\t * - data.get() : 전체 유효 데이터를 JSON 객체 배열로 변환\r\n\t * - data.get(at) : 특정 행을 JSON 객체로 변환\r\n\t * - data.get(at, colnm) : 특정 컬럼 값 반환\r\n\t */\r\n\tget = (at, colnm) => {\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn this.#conv(validRecords);\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= validRecords.length) return null;\r\n\r\n\t\tconst targetRecord = validRecords[at];\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#conv(targetRecord);\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 [저장/서버 전송용] 삭제된 행을 포함한 전체 원본 배열 반환\r\n\t */\r\n\tgetAll = () => {\r\n\t\treturn this.#parent.rawRecords || [];\r\n\t};\r\n\r\n\tgetHostFields = () => {\r\n\t\treturn typeof this.#host.fields?.get === 'function' ? this.#host.fields.get() : [];\r\n\t};\r\n\r\n\t#initialize = () => {\r\n\t\tthis.#defaultHeight = [];\r\n\t\tconst templateElements = this.#host.template || [];\r\n\t\tArray.from(templateElements).forEach(el => {\r\n\t\t\tthis.#defaultHeight.push(el.getBoundingClientRect?.().height || 24);\r\n\t\t});\r\n\r\n\t\t(this.#parent.rawRecords || []).forEach(v => {\r\n\t\t\tif (!v.__ng) v.__ng = this.#getDefaultMeta();\r\n\t\t\tv.__ng.height = this.#defaultHeight.slice();\r\n\t\t});\r\n\t};\r\n\r\n\tget source() {\r\n\t\treturn this.#conv(this.#parent.rawRecords);\r\n\t}\r\n\tset source(v) {\r\n\t\tthis.set(v);\r\n\t\t//this.clear();\r\n\t\t//this.add(v, false);\r\n\t}\r\n\r\n\t#invalidate = () => {\r\n\t\tconst $sheets = this.#host.shadowRoot.querySelector(\"nine-table-sheets\");\r\n\t\t$sheets?.classList.toggle(\"nodata\", this.length === 0);\r\n\r\n\t\tthis.#host.shadowRoot.querySelectorAll(\"nine-table-sheet\").forEach($el => {\r\n\t\t\t$el.invalidate();\r\n\t\t});\r\n\r\n\t\tthis.#host.shadowRoot.querySelector(\"nine-table-sheets-footer\")?.refresh();\r\n\t};\r\n\r\n\tset = (dataSource) => {\r\n\r\n\t\tconst loadData = () => {\r\n\t\t\tthis.clear();\r\n\t\t\tthis.add(dataSource, false);\r\n\t\t\tthis.#invalidate();\r\n\t\t}\r\n\r\n\t\tif (this.#host.loaded) {\r\n\t\t\tloadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.#host.addEventListener(NINE_TABLE.EVENT.LOAD, e => {\r\n\t\t\t\tloadData();\r\n\t\t\t}, { once: true });\r\n\t\t}\r\n\t};\r\n\r\n\tget nextId() {\r\n\t\treturn this.#nextId++;\r\n\t}\r\n\r\n\tget length() {\r\n\t\treturn this.#getValidRecords().length;\r\n\t}\r\n\r\n\tget count() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\tgetRowCount() {\r\n\t\treturn this.length;\r\n\t}\r\n\r\n\t#getDefaultMeta = (rowid = 0) => {\r\n\t\treturn {\r\n\t\t\trowState: ngData.ROW_STATE.EMPTY,\r\n\t\t\tdeleted: false,\r\n\t\t\tfiltered: false,\r\n\t\t\theight: this.#defaultHeight.slice(),\r\n\t\t\to: {},\r\n\t\t\tc: {},\r\n\t\t\t__: [0, 0, 0, 0, ngData.ROW_STATE.EMPTY, false, false, true, false, true, true, false, this.#defaultHeight.slice(), -1, {}, {}],\r\n\t\t\t_: [rowid, [], ],\r\n\t\t};\r\n\t};\r\n\r\n\treset = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tclear = () => {\r\n\t\tthis.#parent.rawRecords = [];\r\n\t\tif (this.#parent.viewRecords?.reset) {\r\n\t\t\tthis.#parent.viewRecords.reset();\r\n\t\t}\r\n\r\n\t\tthis.#nextId = 0;\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\t#json2Array = (jsonArray) => {\r\n\t\tif (!Array.isArray(jsonArray)) jsonArray = [jsonArray];\r\n\r\n\t\tconst fields = this.getHostFields().length > 0 ? this.getHostFields() : Object.keys(jsonArray[0] || {});\r\n\t\tconst arr = [];\r\n\r\n\t\tjsonArray.forEach(json => {\r\n\t\t\tconst o = { v: [] };\r\n\t\t\tfields.forEach(colnm => {\r\n\t\t\t\to.v.push(json[colnm] !== undefined && json[colnm] !== null ? json[colnm] : \"\");\r\n\t\t\t});\r\n\t\t\tarr.push(o);\r\n\t\t});\r\n\r\n\t\treturn arr;\r\n\t};\r\n\r\n\t#defaultInsert = (arr) => {\r\n\t\tif (!Array.isArray(arr)) arr = [arr];\r\n\t\tarr.forEach(o => {\r\n\t\t\tconst rowid = this.nextId;\r\n\r\n\t\t\to.m = this.#getDefaultMeta(rowid);\r\n\t\t\to.__ng = o.m;\r\n\t\t\to.__ng.rowid = rowid;\r\n\t\t\to.__ng.rowState = ngData.ROW_STATE.INSERT;\r\n\t\t\to.__ng._[0] = rowid;\r\n\t\t});\r\n\t\treturn arr;\r\n\t};\r\n\r\n\tadd = (dataSource, updateState = true) => {\r\n\t\tif (dataSource === undefined) dataSource = {};\r\n\t\tconst arr = this.#json2Array(dataSource);\r\n\r\n\t\tthis.#parent.rawRecords = this.#parent.rawRecords.concat(this.#defaultInsert(arr));\r\n\r\n\t\tconst row = this.count() - 1;\r\n\t\tif (!updateState) {\r\n\t\t\tarr.forEach((_, idx) => {\r\n\t\t\t\tconst target = this.#parent.rawRecords[this.#parent.rawRecords.length - 1 - idx];\r\n\t\t\t\tif (target) target.__ng.rowState = ngData.ROW_STATE.EMPTY;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#invalidate();\r\n\t\treturn row;\r\n\t};\r\n\r\n\tdelete = (at) => {\r\n\t\tlet arr = [];\r\n\t\tif (Array.isArray(at)) {\r\n\t\t\tarr = at;\r\n\t\t} else if (typeof at === \"undefined\") {\r\n\t\t\tarr = [this.#parent.host.row.at];\r\n\t\t} else {\r\n\t\t\tarr = [parseInt(at, 10)];\r\n\t\t}\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\r\n\t\tarr.sort((a, b) => b - a).forEach(rowidx => {\r\n\t\t\tif (validRecords[rowidx]) {\r\n\t\t\t\tconst targetId = validRecords[rowidx].__ng.rowid;\r\n\t\t\t\tif (validRecords[rowidx].__ng.rowState === ngData.ROW_STATE.INSERT) {\r\n\t\t\t\t\tthis.#parent.rawRecords = this.#parent.rawRecords.filter(item => item.__ng.rowid !== targetId);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#parent.rawRecords.forEach(item => {\r\n\t\t\t\t\t\tif (item.__ng.rowid === targetId) {\r\n\t\t\t\t\t\t\titem.__ng.deleted = true;\r\n\t\t\t\t\t\t\titem.__ng.rowState = ngData.ROW_STATE.DELETE;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#invalidate();\r\n\t};\r\n\r\n\tsetValue = (rowIndex, colnm, value) => {\r\n\t\t//trace.log(rowIndex, colnm, value)\r\n\t\trowIndex = parseInt(rowIndex, 10);\r\n\t\tconst fields = this.getHostFields();\r\n\t\tconst COL_IDX = fields.indexOf(colnm);\r\n\t\tif (COL_IDX < 0) return;\r\n\r\n\t\tconst validRecords = this.#getValidRecords();\r\n\t\tconst rowData = validRecords[rowIndex];\r\n\t\tif (!rowData) return;\r\n\r\n\r\n\r\n\t\tconst oldValue = rowData.v[COL_IDX];\r\n\t\tif (oldValue !== value && rowData.__ng.rowState !== ngData.ROW_STATE.INSERT) {\r\n\t\t\tif (!rowData.__ng.o.hasOwnProperty(colnm)) rowData.__ng.o[colnm] = oldValue;\r\n\t\t\trowData.__ng.rowState = ngData.ROW_STATE.UPDATE;\r\n\t\t}\r\n\r\n\t\trowData.v[COL_IDX] = value;\r\n\t\t//trace.log(rowData, COL_IDX);\r\n\t};\r\n\r\n\t#conv = (arr) => {\r\n\t\tif (!arr) return arr;\r\n\r\n\t\tconst isSingle = !Array.isArray(arr);\r\n\t\tconst targetArr = isSingle ? [arr] : arr;\r\n\t\tconst fields = this.getHostFields();\r\n\r\n\t\tconst result = targetArr.filter(o => !o.__ng?.deleted).map(o => {\r\n\t\t\tconst t = {};\r\n\t\t\tfields.forEach((colnm, i) => {\r\n\t\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t\t});\r\n\t\t\tt.__ng = o.__ng;\r\n\t\t\treturn t;\r\n\t\t});\r\n\r\n\t\treturn isSingle ? result[0] : result;\r\n\t};\r\n}\r\n","import { ngRow, ngData } from \"./ngData.js\";\r\n\r\nexport class ngDataManager {\r\n\t#host;\r\n\r\n\tconstructor(host) {\r\n\t\tthis.#host = host;\r\n\r\n\t\tthis.row = new ngRow(this);\r\n\t\tthis.data = new ngData(this.#host, this);\r\n\r\n\t\tthis.rawRecords = [];\r\n\t\tthis.viewRecords = [];\r\n\t\tthis.delRecords = [];\r\n\t\tthis.pageCnt = 25;\r\n\r\n\t\tthis.viewRecords.reset = () => {\r\n\t\t\tif (this.#host.view?.redraw) this.#host.view.redraw();\r\n\t\t};\r\n\r\n\t\tthis.setDataSource = (ds) => {\r\n\t\t\tif (this.data) this.data.reset();\r\n\r\n\t\t\tthis.rawRecords = [];\r\n\t\t\tthis.viewRecords = [];\r\n\t\t\tthis.delRecords = [];\r\n\r\n\t\t\tthis.data.set(ds || []);\r\n\t\t};\r\n\r\n\t\tthis.getRowState = (nRow) => {\r\n\t\t\tconst rowIdx = parseInt(nRow, 10);\r\n\t\t\tif (rowIdx >= this.data.count()) return;\r\n\t\t\treturn this.data.getValidData()[rowIdx]?.__ng?.rowState;\r\n\t\t};\r\n\r\n\t\tthis.getRowPosition = () => this.row.at;\r\n\t\tthis.setRowPosition = (nRow) => { this.row.at = nRow; };\r\n\r\n\t\tthis.scrollTo_V1 = (nRow) => {\r\n\t\t\tif (nRow < 0) nRow = 0;\r\n\t\t\tif (nRow >= this.rawRecords.length) nRow = this.rawRecords.length - 1;\r\n\r\n\t\t\tthis.viewRecords.rawIndex = nRow;\r\n\t\t\tif (this.viewRecords.reset) this.viewRecords.reset();\r\n\r\n\t\t\treturn (nRow <= 0 || nRow >= this.rawRecords.length - 1) ? false : true;\r\n\t\t};\r\n\r\n\t\tthis.getColumn = (rowidx, colnm) => this.data.get(rowidx, colnm);\r\n\r\n\t\tthis.setColumn = (rowidx, colnm, v) => {\r\n\t\t\trowidx = parseInt(rowidx, 10);\r\n\t\t\tthis.data.setValue(rowidx, colnm, v);\r\n\t\t};\r\n\r\n\t\t// 초기 빈 데이터 바인딩\r\n\t\tthis.setDataSource([]);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\n\nexport class fields {\n\t#host;\n\t#fields = []; // 🎯 이제 { name: string, type: string } 객체들의 배열로 관리합니다.\n\n\tconstructor(host) {\n\t\tthis.#host = host;\n\t\tthis.#init();\n\t};\n\n\t// 🎯 기존에 필드 이름만 쓰던 곳들과의 호환을 위해 이름 배열만 리턴하는 메서드 유지\n\tget() {\n\t\treturn this.#fields.map(f => f.name);\n\t};\n\n\t// 🎯 내부 객체 통째로 얻기\n\tgetFields() {\n\t\treturn this.#fields;\n\t}\n\n\t// 🎯 특정 필드의 데이터 타입 조회\n\tgetType(fieldName) {\n\t\tconst found = this.#fields.find(f => f.name === fieldName);\n\t\treturn found ? found.type : 'string';\n\t}\n\n\tadd = (arr, type = 'string') => {\n\t\tarr.forEach(fName => {\n\t\t\tif (!this.#fields.some(f => f.name === fName)) {\n\t\t\t\tthis.#fields.push({ name: fName, type: type });\n\t\t\t}\n\t\t});\n\t\tthis.#adjust();\n\t};\n\n\tindexOf(v) {\n\t\treturn this.#fields.findIndex(f => f.name === v);\n\t};\n\n\tincludes(v) {\n\t\treturn this.#fields.some(f => f.name === v);\n\t};\n\n\t#adjust = () => {\n\t\t// 🎯 이름 기준으로 중복 제거 (Map을 활용하여 마지막에 들어온 타입 유지)\n\t\tconst map = new Map();\n\t\tthis.#fields.forEach(f => {\n\t\t\tmap.set(f.name, f.type);\n\t\t});\n\n\t\tthis.#fields = Array.from(map, ([name, type]) => ({ name, type }));\n\n\t\t// 🎯 빈 문자열이나 __ng 필터링\n\t\tthis.#fields = this.#fields.filter(f => f.name !== \"\" && f.name !== \"__ng\");\n\n\t\t// 🎯 긴 이름순 정렬\n\t\tthis.#fields.sort((a, b) => { return (a.name.length < b.name.length) ? 1 : -1; });\n\t};\n\n\t#init = () => {\n\t\tthis.#fields = [];\n\n\t\ttrace.log(this.#host.querySelectorAll(\"table\"));\n\n\t\tconst rawTables = Array.from(this.#host.querySelectorAll(\"table\"));\n\n\t\tif (!rawTables || rawTables.length === 0) return;\n\n\t\tfor (const tbl of rawTables) {\n\t\t\ttrace.log(tbl);\n\n\t\t\t// 1. [data-bind] 속성 탐색 및 타입 수집\n\t\t\ttbl.querySelectorAll('[data-bind]').forEach((el) => {\n\t\t\t\tconst fieldName = el.dataset.bind;\n\t\t\t\tconst fieldType = el.getAttribute(\"data-type\") || 'string';\n\n\t\t\t\tif (fieldName) {\n\t\t\t\t\tthis.#fields.push({ name: fieldName, type: fieldType });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// 2. 표현식 속성들 탐색 (순수 자바스크립트로 변환)\n\t\t\tconst exprAttrs = [\n\t\t\t\t\"data-expr\", \"background-color\", \"color\", \"tooltip\",\n\t\t\t\t\"visible\", \"readonly\", \"enable-button\", \"enable-check\",\n\t\t\t\t\"class-expr\", \"icon-color\", \"icon-src\"\n\t\t\t];\n\n\t\t\texprAttrs.forEach(attr => {\n\t\t\t\t// 💡 jQuery의 $([attr], tbl).each(...)를 순수 querySelectorAll로 대체\n\t\t\t\ttbl.querySelectorAll(`[${attr}]`).forEach((el) => {\n\t\t\t\t\tlet expr = el.getAttribute(attr);\n\t\t\t\t\tif (!expr) return;\n\n\t\t\t\t\tif (expr.indexOf(\"data.\") < 0) {\n\t\t\t\t\t\tconst lastIndex = expr.search(/[(]/g);\n\n\t\t\t\t\t\tif (lastIndex > 0) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\texpr = String(window[expr.substring(0, lastIndex).trim()]);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texpr = \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\texpr.split(\"data.\").forEach(v => {\n\t\t\t\t\t\tif (v.trim() != \"\") {\n\t\t\t\t\t\t\tconst lastIndex = v.search(/[^_A-Za-z0-9]/g);\n\t\t\t\t\t\t\tlet targetField = '';\n\n\t\t\t\t\t\t\tif (lastIndex >= 0) {\n\t\t\t\t\t\t\t\ttargetField = v.substring(0, lastIndex);\n\t\t\t\t\t\t\t} else if (expr.startsWith(\"data.\")) {\n\t\t\t\t\t\t\t\ttargetField = v.replace(\"data.\", \"\");\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (targetField) {\n\t\t\t\t\t\t\t\tthis.#fields.push({ name: targetField, type: 'string' });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\tthis.#adjust();\n\t};\n};","export class NineTableSheets extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n #init = () => {\n\n };\n\n}\n\nif (!customElements.get('nine-table-sheets')) {\n customElements.define('nine-table-sheets', NineTableSheets);\n}","export class NineTableSheetsFooter extends HTMLElement {\n #host;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#init();\n }\n\n refresh = () => {\n this.querySelector(\"#row-count\").innerHTML = this.#host.data.count().toLocaleString();\n };\n\n #init = () => {\n this.#host = this.getRootNode().host;\n\n this.#render();\n\n this.querySelector('.nine-tab-bar')?.addEventListener('click', (e) => {\n const isMultiSelect = e.ctrlKey || e.metaKey || e.shiftKey;\n const tabItem = e.target.closest('nt-sheets-tab-item');\n\n if (!tabItem) return;\n\n const index = parseInt(tabItem.dataset.index, 10);\n this.#switchSheet(index, isMultiSelect);\n });\n\n this.#switchSheet(0, false);\n };\n\n #switchSheet = (index, isMultiSelect = false) => {\n\n const updateSplitters = () => {\n const sheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet'));\n const splitters = Array.from(this.#host.shadowRoot.querySelectorAll('nine-splitter'));\n\n // 1. 모든 스플리터 일단 숨김 처리\n splitters.forEach(s => s.style.setProperty('display', 'none'));\n\n // 2. 현재 active 상태인 시트들을 인덱스 오름차순으로 정렬\n const activeSheets = sheets\n .map((sheet, idx) => ({ sheet, idx }))\n .filter(({ sheet }) => sheet.classList.contains('active'));\n\n if (activeSheets.length < 2) return;\n\n // 3. 인접한 활성화 시트 쌍 사이에 정확히 하나의 스플리터만 노출\n for (let i = 0; i < activeSheets.length - 1; i++) {\n const currentIdx = activeSheets[i].idx;\n\n const targetSplitter = this.#host.shadowRoot.querySelector(`nine-splitter[data-split-index=\"${currentIdx}\"]`);\n if (targetSplitter) {\n targetSplitter.style.setProperty('display', '');\n }\n }\n };\n\n const tabBar = this.querySelector('.nine-tab-bar');\n const body = this.#host.shadowRoot.querySelector('nine-table-sheets-body');\n const tabItems = tabBar.querySelectorAll('nt-sheets-tab-item');\n const sheetElements = body.querySelectorAll('nine-table-sheet');\n\n if (!tabItems[index]) return;\n\n if (!isMultiSelect) {\n tabItems.forEach((tab, idx) => {\n tab.setActive(idx === index);\n });\n\n sheetElements.forEach((sheet, idx) => {\n const isActive = idx === index;\n sheet.classList.toggle('active', isActive);\n sheet.style.flex = isActive ? '1 1 100%' : '';\n });\n } else {\n const clickedTab = tabItems[index];\n const activeTabs = tabBar.querySelectorAll('nt-sheets-tab-item.active');\n\n if (clickedTab.classList.contains('active') && activeTabs.length <= 1) {\n return;\n }\n\n clickedTab.classList.toggle('active');\n const targetSheet = body.querySelector(`nine-table-sheet[data-index=\"${index}\"]`);\n if (targetSheet) {\n targetSheet.classList.toggle('active');\n if (!targetSheet.classList.contains('active')) {\n targetSheet.style.flex = '';\n }\n }\n }\n\n const activeSheets = body.querySelectorAll('nine-table-sheet.active');\n\n activeSheets?.forEach(sheet => {\n sheet.style.flex = (activeSheets.length > 1) ? '1 1 0%' : '1 1 100%';\n\n if (typeof sheet.refreshLayout === 'function') {\n sheet.refreshLayout();\n } else {\n sheet.invalidate?.();\n }\n });\n\n updateSplitters();\n };\n\n #render() {\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE'));\n\n const tabsHtml = rawTables.map((table, idx) => {\n const className = idx === 0 ? 'active' : '';\n const tabName = table.getAttribute('caption') || `Sheet ${idx + 1}`;\n\n return `<nt-sheets-tab-item class=\"${className}\" data-index=\"${idx}\">${tabName}</nt-sheets-tab-item>`;\n }).join('');\n\n this.innerHTML = `\n <div class=\"nine-tab-bar\">${tabsHtml}</div>\n <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n `;\n };\n}\n\nexport class SheetTabItem extends HTMLElement {\n constructor() {\n super();\n }\n\n connectedCallback() {\n\n }\n\n setActive(isActive) {\n this.classList.toggle('active', isActive);\n }\n}\n\nif (!customElements.get('nt-sheets-tab-item')) {\n customElements.define('nt-sheets-tab-item', SheetTabItem);\n}\n\nif (!customElements.get('nine-table-sheets-footer')) {\n customElements.define('nine-table-sheets-footer', NineTableSheetsFooter);\n}","import { trace } from \"@nopeer\";\n\nexport class Toolbar extends HTMLElement {\n #host;\n #customContainer;\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#render();\n this.#bindEvents();\n }\n\n #render() {\n this.innerHTML = `\n <div class=\"ng-toolbar-left\">\n <button type=\"button\" class=\"ng-toolbar-menu-btn\" title=\"Menu\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#374151\" stroke-width=\"2\">\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>\n </svg>\n </button>\n <span class=\"ng-toolbar-title\"></span>\n </div>\n\n <div class=\"ng-toolbar-custom\" id=\"custom-container\"></div>\n `;\n\n this.#customContainer = this.querySelector('#custom-container');\n this.#syncStateFromHost();\n }\n\n #syncStateFromHost() {\n const isSimple = this.#host.getAttribute('theme') === 'simple' || this.#host.classList.contains('simple');\n const showToolbar = this.#host.getAttribute('show-toolbar') !== 'false';\n const showMenu = this.#host.getAttribute('show-menu') !== 'false';\n const caption = this.#host.getAttribute('caption') || '';\n\n if (isSimple || !showToolbar) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n\n this.setAttribute('show-menu', showMenu ? 'true' : 'false');\n this.updateCaption(caption);\n }\n\n #bindEvents() {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) {\n titleEl.addEventListener('dblclick', () => {\n const link = '<font color=\"green\">https://www.ninegrid.net</font>';\n const currentCaption = this.#host.getAttribute('caption') || '';\n titleEl.innerHTML = titleEl.innerHTML === link ? currentCaption : link;\n });\n }\n\n const menuBtn = this.querySelector('.ng-toolbar-menu-btn');\n if (menuBtn) {\n menuBtn.addEventListener('click', () => {\n this.#host.dispatchEvent(new CustomEvent('toolbar-menu-click', {\n bubbles: true,\n composed: true,\n detail: { targetTable: this.#host }\n }));\n });\n }\n }\n\n addCustomElement(element) {\n if (this.#customContainer) {\n this.#customContainer.append(element);\n }\n }\n\n updateCaption(text) {\n const titleEl = this.querySelector('.ng-toolbar-title');\n if (titleEl) titleEl.textContent = text;\n }\n}\n\nif (!customElements.get('nine-table-toolbar')) {\n customElements.define('nine-table-toolbar', Toolbar);\n}","// ui/nine-table-hscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableHScrollBar extends HTMLElement {\n #owner;\n #dragging = false;\n #elements;\n #interval1;\n #interval2;\n #resizeObserver;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#owner = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\n if (!this.#owner) return;\n\n this.innerHTML = `\n <style>\n nine-table-hscrollbar {\n display: flex;\n flex-direction: row;\n width: 100%;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-hscrollbar button {\n width: 16px;\n height: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-hscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-hscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-hscrollbar .ng-scroll-left .ng-scroll-icon { transform: rotate(-135deg); }\n nine-table-hscrollbar .ng-scroll-right .ng-scroll-icon { transform: rotate(45deg); }\n nine-table-hscrollbar .ng-scroll-track {\n flex: 1;\n height: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-hscrollbar .ng-scroll-thumb {\n position: absolute;\n top: 2px;\n bottom: 2px;\n left: 0px;\n width: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-hscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-left' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-right' disabled><div class='ng-scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container : body,\n track : this.querySelector(\".ng-scroll-track\"),\n thumb : this.querySelector(\".ng-scroll-thumb\"),\n left : this.querySelector(\".ng-scroll-left\"),\n right : this.querySelector(\".ng-scroll-right\"),\n };\n\n this.#init();\n this.#observeResize();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n disconnectedCallback() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n }\n }\n\n #observeResize = () => {\n if (!this.#owner) return;\n const body = this.#owner.querySelector(\".ng-sheet-body .ng-container-body\");\n if (!body) return;\n\n this.#resizeObserver = new ResizeObserver(() => {\n this.refresh();\n });\n this.#resizeObserver.observe(body);\n };\n\n refresh = () => {\n\n if (!this.#owner || !this.#elements || this.#dragging) return;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return;\n\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n\n //trace.log(bodyWidth, tableWidth, bodyWidth);\n\n // 🎯 [순수 클래스 연동] 인라인 스타일 조작 없이 오직 클래스 토글만 수행\n const needsHScroll = (bodyWidth !== 0 && tableWidth > bodyWidth);\n this.#owner.classList.toggle('hscroll-visible', needsHScroll);\n\n if (!needsHScroll) {\n return;\n }\n\n const trackWidth = track.clientWidth;\n if (trackWidth <= 0) return;\n\n const thumbWidth = Math.max(Math.min(trackWidth * (bodyWidth / tableWidth), trackWidth), 20);\n thumb.style.width = `${thumbWidth}px`;\n\n const currentLeft = body.scrollLeft;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n let l = 0;\n if (maxScrollLeft > 0) {\n l = parseInt((currentLeft / maxScrollLeft) * (trackWidth - thumbWidth), 10);\n }\n if (l < 0) l = 0;\n\n const maxThumbLeft = trackWidth - thumbWidth;\n if (l > maxThumbLeft) l = maxThumbLeft;\n\n thumb.style.left = `${l}px`;\n\n this.#elements.left.disabled = (l === 0);\n this.#elements.right.disabled = (l >= maxThumbLeft - 1);\n };\n\n #thumbMoveTo = (x) => {\n if (!this.#elements) return false;\n\n const body = this.#elements.container;\n const table = body.querySelector(\"table\");\n if (!table) return false;\n\n const trackBound = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n\n let targetX = x;\n if (targetX < 0) targetX = 0;\n const maxThumbLeft = trackBound.width - thumbWidth;\n if (targetX > maxThumbLeft) targetX = maxThumbLeft;\n targetX = parseInt(targetX, 10);\n\n this.#elements.thumb.style.left = `${targetX}px`;\n\n this.#elements.left.disabled = (targetX === 0);\n this.#elements.right.disabled = (targetX >= maxThumbLeft - 1);\n\n const bodyWidth = body.clientWidth;\n const tableWidth = table.scrollWidth;\n const maxScrollLeft = tableWidth - bodyWidth;\n\n if (maxThumbLeft > 0 && maxScrollLeft > 0) {\n const newScrollLeft = (targetX / maxThumbLeft) * maxScrollLeft;\n body.scrollLeft = newScrollLeft;\n\n const headerBody = this.#owner.querySelector(\".ng-sheet-header .ng-container-body\");\n const footerBody = this.#owner.querySelector(\".ng-sheet-footer .ng-container-body\");\n if (headerBody) headerBody.scrollLeft = newScrollLeft;\n if (footerBody) footerBody.scrollLeft = newScrollLeft;\n }\n\n return (targetX > 0 && targetX < maxThumbLeft - 1);\n };\n\n #init = () => {\n const delayScroll = (pos) => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n\n const thumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n this.#thumbMoveTo(thumbLeft + pos);\n\n this.#interval1 = setInterval(() => {\n clearInterval(this.#interval1);\n\n this.#interval2 = setInterval(() => {\n const currentThumbLeft = parseInt(this.#elements.thumb.style.left || 0, 10);\n if (!this.#thumbMoveTo(currentThumbLeft + pos)) {\n clearInterval(this.#interval2);\n }\n }, 50);\n }, 500);\n };\n\n const clearTimer = () => {\n clearInterval(this.#interval1);\n clearInterval(this.#interval2);\n };\n\n ['mouseup', 'mouseleave', 'touchend'].forEach(evt => {\n this.#elements.left.addEventListener(evt, clearTimer);\n this.#elements.right.addEventListener(evt, clearTimer);\n this.#elements.track.addEventListener(evt, clearTimer);\n });\n\n this.#elements.left.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(-20); });\n this.#elements.right.addEventListener(\"mousedown\", e => { if (e.button !== 0) return; delayScroll(20); });\n this.#elements.left.addEventListener(\"touchstart\", () => delayScroll(-20));\n this.#elements.right.addEventListener(\"touchstart\", () => delayScroll(20));\n\n this.#elements.track.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.preventDefault();\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbWidth = this.#elements.thumb.clientWidth;\n this.#thumbMoveTo(e.clientX - trackRect.left - (thumbWidth / 2));\n });\n\n this.#elements.thumb.addEventListener(\"mousedown\", e => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n this.shiftX = e.clientX - this.#elements.thumb.getBoundingClientRect().left;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n this.#thumbMoveTo(moveEvent.clientX - trackRect.left - this.shiftX);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n clearTimer();\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n };\n}\n\nif (!customElements.get('nine-table-hscrollbar')) {\n customElements.define(\"nine-table-hscrollbar\", NineTableHScrollBar);\n}","// ui/nine-table-vscrollbar.js\nimport { trace } from \"@nopeer\";\n\nexport class NineTableVScrollBar extends HTMLElement {\n #host;\n #sheet;\n #dragging = false;\n #elements;\n #startY = 0;\n #startScrollTop = 0;\n #startThumbTop = 0;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#host = this.getRootNode().host;\n this.#sheet = this.closest(\"nine-table-sheet\");\n\n this.innerHTML = `\n <style>\n nine-table-vscrollbar {\n display: flex;\n flex-direction: column;\n width: 16px;\n height: 100%;\n background: #f9fafb;\n box-sizing: border-box;\n user-select: none;\n position: relative;\n }\n nine-table-vscrollbar button {\n height: 16px;\n width: 100%;\n background: #f3f4f6;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n flex-shrink: 0;\n z-index: 2;\n }\n nine-table-vscrollbar button:disabled {\n opacity: 0.4;\n cursor: default;\n }\n nine-table-vscrollbar .ng-scroll-icon {\n width: 6px;\n height: 6px;\n border-top: 2px solid #6b7280;\n border-right: 2px solid #6b7280;\n }\n nine-table-vscrollbar .ng-scroll-top .ng-scroll-icon { transform: rotate(-45deg); margin-top: 2px; }\n nine-table-vscrollbar .ng-scroll-bottom .ng-scroll-icon { transform: rotate(135deg); margin-bottom: 2px; }\n \n nine-table-vscrollbar .ng-scroll-track {\n flex: 1;\n width: 100%;\n position: relative;\n background: #f3f4f6;\n overflow: hidden;\n }\n nine-table-vscrollbar .ng-scroll-thumb {\n position: absolute;\n left: 2px;\n right: 2px;\n top: 0px;\n height: 30px;\n background: #9ca3af;\n border-radius: 4px;\n cursor: pointer;\n z-index: 1;\n }\n nine-table-vscrollbar .ng-scroll-thumb:hover {\n background: #6b7280;\n }\n </style>\n <button class='ng-scroll-top' disabled><div class='ng-scroll-icon'></div></button>\n <div class='ng-scroll-track'><div class='ng-scroll-thumb'></div></div>\n <button class='ng-scroll-bottom' disabled><div class='ng-scroll-icon'></div></button>\n `;\n\n const initWhenReady = () => {\n const body = this.#sheet.querySelector(\".ng-sheet-body\");\n if (!body) {\n setTimeout(initWhenReady, 10);\n return;\n }\n\n this.#elements = {\n container: body,\n track: this.querySelector(\".ng-scroll-track\"),\n thumb: this.querySelector(\".ng-scroll-thumb\"),\n top: this.querySelector(\".ng-scroll-top\"),\n bottom: this.querySelector(\".ng-scroll-bottom\"),\n };\n\n this.#init();\n this.refresh();\n };\n\n initWhenReady();\n }\n\n #getScaleInfo = () => {\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords ? viewRecords.length : 0;\n\n // 🎯 [핵심] 그룹핑이든 일반이든 스크롤홀더(scrollHolder)가 가진 실제 가상 총 높이를 최우선으로 반영\n const scrollHolder = this.#sheet.elements?.scrollHolder;\n let rawContentHeight = scrollHolder ? parseFloat(scrollHolder.style.height) || 0 : 0;\n\n if (!rawContentHeight || rawContentHeight <= 0) {\n const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n if (isGrouped && this.#sheet.rowManager) {\n // RowManager가 관리하는 누적 높이 활용 또는 fallback\n rawContentHeight = (body.scrollHeight > body.clientHeight) ? body.scrollHeight : (totalCount * 30);\n } else {\n const rowHeight = this.#sheet.getRowHeight() || 1;\n rawContentHeight = totalCount * rowHeight;\n }\n }\n\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawContentHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let contentHeight = rawContentHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawContentHeight;\n contentHeight = MAX_BROWSER_HEIGHT;\n }\n\n return { rawContentHeight, contentHeight, scaleFactor, useScaling, totalCount };\n };\n\n #getViewHeight = () => {\n const body = this.#elements.container;\n if (!body) return 0;\n\n const thead = this.#sheet.elements?.body?.thead?.offsetHeight || 0;\n const tfoot = this.#sheet.elements?.body?.tfoot?.offsetHeight || 0;\n const tbodyHead = this.#sheet.elements?.body?.tbody?.head?.offsetHeight || 0;\n const fixedHeight = thead + tfoot + tbodyHead;\n\n return body.clientHeight - fixedHeight;\n };\n\n refresh = () => {\n trace.log(\"=================\", \"vscrollbar.refresh\");\n // 💡 드래그 중에는 refresh에 의한 썸 위치 덮어쓰기 차단\n if (this.#dragging) return;\n\n if (!this.#sheet || !this.#sheet.elements || !this.#elements) return;\n\n const body = this.#elements.container;\n const track = this.#elements.track;\n const thumb = this.#elements.thumb;\n\n /**\n * const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n * (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n * this.#sheet.elements.body.tbody.head.offsetHeight;\n *\n * const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n * // 1. 전체 실제 데이터의 높이 계산\n * const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + rowHeight + fixedHeight - viewHeight, 0);\n * @type {number|*}\n */\n\n const bodyHeight = this.#getViewHeight();\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n\n const needsVScroll = (rawContentHeight > bodyHeight && rawContentHeight > 0 && bodyHeight > 0);\n this.#sheet.classList.toggle('vscroll-visible', needsVScroll);\n\n if (!needsVScroll) {\n return;\n }\n\n const trackHeight = track.clientHeight;\n if (trackHeight <= 0) return;\n\n const thumbHeight = Math.max(Math.min(trackHeight * (bodyHeight / contentHeight), trackHeight), 20);\n thumb.style.height = `${thumbHeight}px`;\n\n const currentScrollTop = body.scrollTop;\n //const maxScrollTop = Math.max(contentHeight - bodyHeight, 1);\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 1);\n\n let thumbTop = 0;\n if (maxScrollTop > 0) {\n thumbTop = (currentScrollTop / maxScrollTop) * (trackHeight - thumbHeight);\n }\n\n const maxThumbTop = trackHeight - thumbHeight;\n if (thumbTop < 0) thumbTop = 0;\n if (thumbTop > maxThumbTop) thumbTop = maxThumbTop;\n\n thumb.style.top = `${thumbTop}px`;\n\n /**\n // 🎯 [디버깅 로그] 스크롤바가 리프레시될 때 현재 상태 로깅\n trace.log(\"🔍 [VScroll Refresh]\", {\n isGrouped: this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false,\n totalCount,\n bodyScrollTop: currentScrollTop,\n maxScrollTop,\n thumbTop,\n maxThumbTop\n }); */\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n #init = () => {\n trace.log(\"nine-table-vscrollbar.#init\");\n\n const body = this.#elements.container;\n\n this.#elements.thumb.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n this.#dragging = true;\n\n this.#startY = e.clientY;\n this.#startThumbTop = parseFloat(this.#elements.thumb.style.top) || 0;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const trackHeight = trackRect.height;\n const thumbHeight = this.#elements.thumb.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n const onMouseMove = (moveEvent) => {\n if (!this.#dragging) return;\n if (maxThumbTop <= 0) return;\n\n //this.#elements.container.scrollTop = 0;\n\n const deltaY = moveEvent.clientY - this.#startY;\n let targetThumbTop = this.#startThumbTop + deltaY;\n\n if (targetThumbTop < 0) targetThumbTop = 0;\n if (targetThumbTop > maxThumbTop) targetThumbTop = maxThumbTop;\n\n // 썸 위치 즉시 고정\n this.#elements.thumb.style.top = `${targetThumbTop}px`;\n\n const ratio = targetThumbTop / maxThumbTop;\n\n const rowHeight =this.#sheet.getRowHeight();\n const viewHeight = (this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0) -\n (this.#sheet.elements.body.thead?.offsetHeight || 0) -\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) -\n (this.#sheet.elements.body.tbody.head.offsetHeight || 0);\n\n const visibleRowCount = Math.floor(viewHeight / rowHeight);\n\n const { totalCount } = this.#getScaleInfo();\n //const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n const targetRow = Math.floor(ratio * (totalCount - visibleRowCount + 1));\n // 1000010 - 6\n this.#sheet.rowManager.scrollToDataRow(targetRow);\n\n const { rawContentHeight, contentHeight } = this.#getScaleInfo();\n const currentScrollTop = this.#elements.container.scrollTop;\n const maxScrollTop = Math.max(contentHeight - this.#sheet.rowManager.getRowHeight(), 0);\n\n //trace.log(\"*****************\", visibleRowCount, ratio, totalCount, targetRow);\n\n this.#elements.top.disabled = (currentScrollTop <= 0);\n this.#elements.bottom.disabled = (currentScrollTop >= maxScrollTop - 1);\n };\n\n const onMouseUp = () => {\n this.#dragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n //this.refresh();\n };\n\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n });\n\n this.#elements.track.addEventListener(\"mousedown\", (e) => {\n if (e.button !== 0 || e.target === this.#elements.thumb) return;\n const trackRect = this.#elements.track.getBoundingClientRect();\n const thumbHeight = this.#elements.thumb.clientHeight;\n const trackHeight = this.#elements.track.clientHeight;\n const maxThumbTop = trackHeight - thumbHeight;\n\n if (maxThumbTop > 0) {\n const clickY = e.clientY - trackRect.top - (thumbHeight / 2);\n const ratio = Math.max(0, Math.min(1, clickY / maxThumbTop));\n\n const { totalCount } = this.#getScaleInfo();\n const targetRow = Math.max(0, Math.min(Math.floor(ratio * (totalCount - 1)), totalCount - 1));\n\n trace.log(\"🎯 [VScroll Track Click]\", { ratio, clickY, totalCount, targetRow });\n\n if (targetRow >= 0 && this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n }\n this.refresh();\n });\n\n this.#elements.top.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = Math.max(0, currentTopRow - 1);\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n\n this.#elements.bottom.addEventListener(\"click\", () => {\n const currentTopRow = Math.floor(body.scrollTop / this.#sheet.getRowHeight());\n const targetRow = currentTopRow + 1;\n if (this.#sheet.rowManager && typeof this.#sheet.rowManager.scrollToDataRow === 'function') {\n this.#sheet.rowManager.scrollToDataRow(targetRow, 'top');\n }\n });\n };\n}\n\nif (!customElements.get('nine-table-vscrollbar')) {\n customElements.define(\"nine-table-vscrollbar\", NineTableVScrollBar);\n}","import { trace } from \"@nopeer\";\r\n\r\n// 💡 배열 인덱스 상수 정의\r\nexport const GROUP_IDX = {\r\n\tID: 0,\r\n\tDEPTH: 1,\r\n\tNAME: 2,\r\n\tCHILDREN: 3,\r\n};\r\n\r\nexport class GroupingManager {\r\n\t#sheet;\r\n\t#host;\r\n\t#groupColumns = [];\r\n\t#groupMap = new Map(); // 그룹별 자식 ID 매핑 관리용\r\n\t#isApplying = false;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t}\r\n\r\n\tget columns() {\r\n\t\treturn this.#groupColumns;\r\n\t}\r\n\r\n\tget groupMap() {\r\n\t\treturn this.#groupMap;\r\n\t}\r\n\r\n\tinitialize = () => {\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\t};\r\n\r\n\tapply() {\r\n\r\n\t\ttrace.log(\"==================\", \"Grouping.Apply\");\r\n\r\n\t\tif (this.#isApplying) return;\r\n\t\tthis.#isApplying = true;\r\n\r\n\t\tlet groupColumns = [];\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (sourceTable) {\r\n\t\t\tsourceTable.querySelectorAll('tbody tr[grouping=\"true\"]').forEach(($tr) => {\r\n\t\t\t\tconst $cell =$tr.querySelector(`[cell-type=\"tree\"]`);\r\n\t\t\t\tif ($cell &&$cell.dataset.bind) {\r\n\t\t\t\t\tgroupColumns.push($cell.dataset.bind);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#groupColumns = groupColumns;\r\n\r\n\t\t// 💡 데이터 캐시와 렌더링 아이템은 이제 SheetView 단일 파이프라인에서 관리하므로\r\n\t\t// 그룹핑 설정이 바뀌면 SheetView.refresh()를 호출해 전체 흐름을 일괄 재계산합니다.\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh(); // 🎯 SheetView에서 필터/정렬/그룹핑 일괄 처리\r\n\t}\r\n\r\n\tclear() {\r\n\t\tthis.#groupColumns = [];\r\n\t\tthis.#groupMap.clear();\r\n\t\tthis.#isApplying = false;\r\n\t\tthis.#sheet.scrollToY(0);\r\n\t\tthis.#sheet.view.refresh();\r\n\t}\r\n\r\n\t// SheetView가 그룹핑 연산 후 groupMap을 공유할 수 있도록 설정 메서드 제공\r\n\tsetGroupMap(map) {\r\n\t\tthis.#groupMap = map;\r\n\t}\r\n\r\n\tgetChildrenRowIds(groupId) {\r\n\t\treturn this.#groupMap.get(groupId) || [];\r\n\t}\r\n\r\n\tgetChildrenRecords(groupId) {\r\n\t\tconst rowIds = this.getChildrenRowIds(groupId);\r\n\t\tconst dataManager = this.#host.data;\r\n\t\treturn rowIds.map(rowid => dataManager.getArray(rowid)).filter(Boolean);\r\n\t}\r\n}\r\n\r\nexport class Grouping {\r\n\r\n\tstatic apply(rawRecords, groupColumns = [], fields = []) {\r\n\t\tif (!groupColumns || groupColumns.length === 0) {\r\n\t\t\treturn { headers: [], renderItems: [], groupMap: new Map() };\r\n\t\t}\r\n\r\n\t\tconst validRaw = rawRecords.filter(o => !o.__ng?.deleted);\r\n\t\tconst groupMap = new Map();\r\n\r\n\t\tconst nestedTree = Grouping.#buildNestedMap(validRaw, groupColumns, fields);\r\n\t\tconst flatResult = [];\r\n\t\tconst renderItems = [];\r\n\r\n\t\tGrouping.#flattenTree(nestedTree, 0, groupColumns, flatResult, renderItems, groupMap, \"\");\r\n\r\n\t\treturn { headers: flatResult, renderItems, groupMap };\r\n\t}\r\n\r\n\tstatic #flattenTree(mapOrArray, depth, groupColumns, resultArr, renderItems, groupMap, parentId) {\r\n\t\tlet counter = 0;\r\n\t\tconst isLastLevel = (depth === groupColumns.length - 1); // 💡 연산자 수정 반영\r\n\r\n\t\tfor (let [groupKey, subMapOrRecords] of mapOrArray.entries()) {\r\n\t\t\tconst groupId = parentId ? `${parentId}_${counter++}` : `g_${counter++}`;\r\n\r\n\t\t\tconst rowIds = Grouping.#collectLeafRowIds(subMapOrRecords);\r\n\t\t\tgroupMap.set(groupId, rowIds);\r\n\r\n\t\t\tconst groupRecord = [];\r\n\t\t\tgroupRecord[GROUP_IDX.ID] = groupId;\r\n\t\t\tgroupRecord[GROUP_IDX.DEPTH] = depth;\r\n\t\t\tgroupRecord[GROUP_IDX.NAME] = groupKey;\r\n\t\t\tgroupRecord[GROUP_IDX.CHILDREN] = rowIds;\r\n\r\n\t\t\tgroupRecord.__isGroupHeader = true;\r\n\t\t\tgroupRecord.__groupId = groupId;\r\n\r\n\t\t\tresultArr.push(groupRecord);\r\n\r\n\t\t\trenderItems.push({\r\n\t\t\t\ttype: 'group',\r\n\t\t\t\trecord: groupRecord,\r\n\t\t\t\tgroupId: groupId\r\n\t\t\t});\r\n\r\n\t\t\tif (!isLastLevel && subMapOrRecords instanceof Map) {\r\n\t\t\t\tGrouping.#flattenTree(subMapOrRecords, depth + 1, groupColumns, resultArr, renderItems, groupMap, groupId);\r\n\t\t\t} else {\r\n\t\t\t\tconst leafRecords = Grouping.#collectLeafRecords(subMapOrRecords);\r\n\t\t\t\tleafRecords.forEach(record => {\r\n\t\t\t\t\trecord.__isGroupHeader = false;\r\n\t\t\t\t\trecord.__groupId = groupId;\r\n\t\t\t\t\tresultArr.push(record);\r\n\r\n\t\t\t\t\trenderItems.push({\r\n\t\t\t\t\t\ttype: 'data',\r\n\t\t\t\t\t\trecord: record,\r\n\t\t\t\t\t\tgroupId: groupId\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tstatic #buildNestedMap(records, groupColumns, fields) {\r\n\t\tconst colIndex = fields.indexOf(groupColumns[0]);\r\n\t\tconst remainingCols = groupColumns.slice(1);\r\n\t\tconst map = new Map();\r\n\r\n\t\trecords.forEach(record => {\r\n\t\t\tconst key = colIndex >= 0 ? record.v[colIndex] : '(Unknown)';\r\n\t\t\tif (!map.has(key)) map.set(key, []);\r\n\t\t\tmap.get(key).push(record);\r\n\t\t});\r\n\r\n\t\tif (remainingCols.length > 0) {\r\n\t\t\tconst result = new Map();\r\n\t\t\tfor (let [key, subRecords] of map.entries()) {\r\n\t\t\t\tresult.set(key, Grouping.#buildNestedMap(subRecords, remainingCols, fields));\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n\tstatic #collectLeafRowIds(subMapOrRecords) {\r\n\t\tlet rowIds = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trowIds = rowIds.concat(Grouping.#collectLeafRowIds(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trowIds = rowIds.concat(subMapOrRecords.map(r => r.__ng?.rowid ?? r.m?._?.[0]));\r\n\t\t}\r\n\t\treturn rowIds;\r\n\t}\r\n\r\n\tstatic #collectLeafRecords(subMapOrRecords) {\r\n\t\tlet records = [];\r\n\t\tif (subMapOrRecords instanceof Map) {\r\n\t\t\tfor (let subVal of subMapOrRecords.values()) {\r\n\t\t\t\trecords = records.concat(Grouping.#collectLeafRecords(subVal));\r\n\t\t\t}\r\n\t\t} else if (Array.isArray(subMapOrRecords)) {\r\n\t\t\trecords = records.concat(subMapOrRecords);\r\n\t\t}\r\n\t\treturn records;\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { GROUP_IDX } from \"@/data/Grouping.js\";\n\nexport class RowManager {\n #BUFFER_ROW_COUNT = 3;\n\n #host;\n #sheet;\n #element;\n\n #containerTemplates = new Map();\n\n #templateRowHeights = []; // 💡 [추가] 템플릿 행별 개별 높이 보관 ([그룹1, 그룹2, 데이터])\n #cachedTemplateHeight = null;\n\n #resizeObserver = null;\n #sheetHeight = 0;\n #cachedRowCount;\n\n #isProgrammaticScroll = false;\n #isGrouped = false;\n\n constructor(sheet) {\n this.#host = sheet.getRootNode().host;\n this.#sheet = sheet;\n\n this.#initResizeObserver();\n }\n\n // ==========================================\n // 🎯 Public APIs & Getters\n // ==========================================\n\n getRowHeight() {\n return this.#templateRowHeights.reduce((sum, h) => sum + h, 0);//this.#cachedTemplateHeight;\n }\n\n\n refresh = (force = false) => {\n //trace.log(\"rowManager.refresh\", { force });\n\n //this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[group='true']\") ? true : false;\n\n if (!this.#sheet.classList.contains('active')) return;\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n const wasInvalidHeight = !this.#cachedTemplateHeight || this.#cachedTemplateHeight <= 0;\n\n if (wasInvalidHeight) {\n this.#measureAndCacheHeight();\n if (this.#cachedTemplateHeight && this.#cachedTemplateHeight > 0) {\n this.#renderAllContainers();\n }\n }\n\n\n //this.#updateFooterSpacing();\n\n this.#handleScroll(bodyViewport.scrollTop, force);\n\n this.#sheet.querySelector('nine-table-vscrollbar')?.refresh();\n };\n\n #handleScroll = (scrollTop, force = false) => {\n\n //this.#sheet.querySelector('.ng-sheet-body').scrollTop = 0;\n\n\n if (this.#isGrouped) {\n this.#handleGroupedScroll(scrollTop, force);\n return;\n }\n\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) return;\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords.length;\n\n if (totalCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n // 🎯 [핵심] 브라우저 DOM 최대 높이 제한 대응 (약 1,500만 픽셀 상한선)\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n let totalVirtualHeight = rawTotalVirtualHeight;\n\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n totalVirtualHeight = MAX_BROWSER_HEIGHT;\n }\n //trace.log(totalCount, rowHeight, rawTotalVirtualHeight, MAX_BROWSER_HEIGHT);\n // 스크롤홀더에는 브라우저가 소화할 수 있는 최대 높이만 부여\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n //trace.log(\"*************\",this.#sheet.querySelector('.ng-sheet-body').clientHeight, this.#sheet.querySelector('.ng-sheet-body').offsetHeight, viewHeight, fixedHeight, rawTotalVirtualHeight, totalVirtualHeight);\n\n //trace.log(totalVirtualHeight);\n // 🎯 스크롤바 위치(scrollTop)를 실제 데이터 좌표계로 역환산\n const actualScrollTop = useScaling ? (scrollTop / scaleFactor) : scrollTop;\n\n const maxStartIndex = Math.max(0, totalCount - 1);\n const clampedScrollTop = Math.min(actualScrollTop, rawTotalVirtualHeight);\n\n // 실제 데이터 좌표 기준으로 시작 인덱스 산출 (원하시는 -1 보정 유지)\n const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight) - 1, maxStartIndex));\n // 🎯 -1 보정을 제거하여 최하단까지 정확히 매핑되도록 수정\n //const startIndex = Math.max(0, Math.min(Math.floor(clampedScrollTop / rowHeight), maxStartIndex));\n\n //trace.log(startIndex, clampedScrollTop, totalVirtualHeight, fixedHeight, rowHeight);\n\n // 🎯 화면 렌더링 오프셋도 '실제 데이터 좌표(clampedScrollTop)' 기준의 모듈러 연산 적용\n const renderOffsetTop = clampedScrollTop % rowHeight;\n this.#sheet.elements.left.tbody.body.style.top =\n this.#sheet.elements.body.tbody.body.style.top =\n this.#sheet.elements.right.tbody.body.style.top = `-${renderOffsetTop}px`;\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.row !== undefined ? parseInt(firstTr.dataset.row, 10) : -1;\n\n if (!force && currentStartIndex === startIndex) {\n //trace.log(`[Perf ${getTimestamp()}] ⏭️ 인덱스 동일로 스킵! 총 소요: ${(performance.now() - startTime).toFixed(2)}ms`);\n return;\n }\n\n //trace.log(`${getTimestamp()}`);\n\n\n // [범인 구간 추적]\n [\n this.#sheet.elements.left.tbody.body,\n this.#sheet.elements.body.tbody.body,\n this.#sheet.elements.right.tbody.body\n ].forEach(($tbody, tbodyIdx) => {\n if (!$tbody) return;\n\n const rows = $tbody.querySelectorAll('tbody.body tr');\n\n //trace.log(`${getTimestamp()}`);\n\n rows.forEach(($tr, index) => {\n const dataIndex = startIndex + Math.floor(index / templateLength);\n\n if (dataIndex >= totalCount) {\n $tr.style.display = 'none';\n $tr.dataset.matrixRow = null;\n $tr.dataset.row = null;\n return;\n }\n\n // trace.log(`${getTimestamp()}`);\n const record = viewRecords[dataIndex];//this.#sheet.view.getArray(dataIndex);\n //trace.log(`${getTimestamp()}`);\n\n if (!record) {\n $tr.style.display = 'none';\n return;\n }\n\n const rowid = record.m._[NINE_TABLE.META.INDEX.ROWID];\n\n $tr.style.display = '';\n\n // 💡 만약 개별 바인딩 안에서 느린지 확인하려면 여기서 측정 가능\n this.#bindRowData($tr, record, rowid, dataIndex);\n });\n });\n\n // 셀렉션 갱신\n this.#sheet.selection.refresh();\n };\n\n\n #handleGroupedScroll = (scrollTop, force = false) => {\n\n trace.log(\"handleGroupdScroll() start\")\n\n const allRenderItems = this.#sheet.view.getArray() || [];\n const totalVirtualCount = allRenderItems.length;\n\n if (totalVirtualCount === 0) {\n this.#sheet.elements.scrollHolder.style.height = '0px';\n return;\n }\n\n //trace.log(allRenderItems);\n\n const bodyContent = this.#sheet.querySelector('.ng-sheet-body .ng-sheet-body-content');\n const templateLength = this.#sheet.templateLength || 1;\n\n const getItemHeight = (item) => {\n if (item.type === 'group') {\n const depth = item.record[GROUP_IDX.DEPTH] || 0;\n // 💡 해당 뎁스 그룹 행의 높이가 정확히 잡히는지 확인 (없으면 첫 번째 템플릿 높이)\n const groupHeight = this.#templateRowHeights[depth] || this.#cachedTemplateHeight / templateLength;\n return groupHeight;\n } else {\n // 💡 데이터 행은 전체 템플릿 높이에서 그룹 TR들을 제외한 순수 데이터 TR들의 높이 합산이어야 합니다.\n // 만약 templateLength가 1이고 일반 행이라면 아래와 같이 처리\n let dataRowsHeight = 0;\n // templateRowHeights 전체 중에서 그룹이 아닌 데이터 행들의 높이만 합산하거나,\n // 단일 데이터 템플릿 높이를 정확히 반환해야 합니다.\n const templateLength = this.#sheet.templateLength || 1;\n\n // 간단하게 전체 캐시된 템플릿 높이에서 그룹 높이들을 뺀 나머지를 데이터 높이로 산정\n let groupHeightsTotal = 0;\n for(let i = 0; i < templateLength - 1; i++) {\n groupHeightsTotal += this.#templateRowHeights[i] || 0;\n }\n dataRowsHeight = this.#cachedTemplateHeight - groupHeightsTotal;\n\n return dataRowsHeight > 0 ? dataRowsHeight : this.#cachedTemplateHeight;\n }\n };\n\n\n let totalVirtualHeight = 0;\n const itemHeights = new Array(totalVirtualCount);\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = getItemHeight(allRenderItems[i]);\n itemHeights[i] = h;\n totalVirtualHeight += h;\n }\n\n this.#sheet.elements.scrollHolder.style.height = `${totalVirtualHeight}px`;\n\n trace.log(\"*************\", totalVirtualHeight);\n\n const viewportClientHeight = this.#sheet.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = 0;\n\n for (let i = 0; i < totalVirtualCount; i++) {\n const h = itemHeights[i];\n if (accumulatedHeight + h > scrollTop) {\n startIndex = i;\n break;\n }\n accumulatedHeight += h;\n startIndex = i;\n }\n\n //trace.log(startIndex);\n\n const offsetY = scrollTop - accumulatedHeight;\n if (bodyContent) {\n bodyContent.querySelectorAll(\"tbody\").forEach(($tbody) => {\n $tbody.style.top = `-${Math.max(0, offsetY)}px`;\n });\n }\n\n const firstTr = this.#element.firstTr;\n const currentStartIndex = firstTr && firstTr.dataset.virtualIndex !== undefined\n ? parseInt(firstTr.dataset.virtualIndex, 10)\n : -1;\n\n if (!force && currentStartIndex === startIndex) {\n return;\n }\n\n const visibleRowsCount = Math.ceil(viewportClientHeight / (this.#cachedTemplateHeight / templateLength));\n const dynamicBuffer = (this.#sheet.grouping.columns?.length || 1) * 15;\n const targetStart = startIndex;\n const targetEnd = Math.min(totalVirtualCount, startIndex + visibleRowsCount + dynamicBuffer);\n\n\n\n\n const renderedItems = allRenderItems.slice(targetStart, targetEnd);\n\n //trace.log(\"handleGroupdScroll() 22\", renderedItems);\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const trs = Array.from(container.querySelectorAll('tbody.body tr'));\n\n for (let i = 0; i < trs.length; i += templateLength) {\n const itemIndex = Math.floor(i / templateLength);\n const item = renderedItems[itemIndex];\n const chunkTrs = trs.slice(i, i + templateLength);\n\n if (!item || itemIndex >= renderedItems.length) {\n chunkTrs.forEach(tr => {\n tr.dataset.matrixRow = null;\n tr.dataset.row = null;\n tr.style.display = 'none';\n });\n continue;\n }\n\n const dataIndex = startIndex + itemIndex;\n\n chunkTrs.forEach((tr, subIdx) => {\n const virtualIndex = startIndex + itemIndex;\n tr.dataset.virtualIndex = virtualIndex;\n tr.dataset.row = (item.type === 'data') ? dataIndex : '';\n\n const isTrGroup = tr.getAttribute('grouping') === 'true';\n\n if (item.type === 'group') {\n if (isTrGroup) {\n const depth = item.record[GROUP_IDX.DEPTH];\n if (subIdx === depth) {\n tr.style.display = '';\n this.#bindGroupRowData(tr, allRenderItems, item.record, virtualIndex);\n } else {\n tr.style.display = 'none';\n }\n } else {\n tr.style.display = 'none';\n }\n } else {\n if (isTrGroup) {\n tr.style.display = 'none';\n } else {\n tr.style.display = '';\n\n //trace.log(item.record)\n const rowid = item.record.m?.rowid ?? 0;\n this.#bindRowData(tr, item.record, rowid, virtualIndex);\n }\n }\n });\n }\n });\n\n this.#sheet.selection.refresh();\n\n trace.log(\"handleGroupdScroll() end\")\n };\n\n #bindGroupRowData = ($tr, allRenderItems, groupRecord, virtualIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (virtualIndex * templateLength) + subRowIndex;\n\n const indices = groupRecord[GROUP_IDX.CHILDREN]; // 인덱스 배열이 들어있는 위치 (정확한 인덱스는 구조에 맞게 조절)\n const allRecords = this.#host.data.getArray();\n const childrenRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\n\n // 필요하다면 groupRecord나 tr에 자식 레코드들을 캐싱해 둘 수도 있습니다.\n //groupRecord.childrenRecords = childrenRecords;\n\n //trace.log(allRecords, childrenRecords);\n\n\n $tr.dataset.virtualIndex = virtualIndex;\n $tr.dataset.row = '';\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = childrenRecords;//groupRecord;\n $tr.dataset.groupId = groupRecord[GROUP_IDX.ID];\n\n //trace.log(tr, groupRecord)\n\n Array.from($tr.cells).forEach(($cell) => {\n\n $cell.dataset.row = virtualIndex;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') || typeof $el.refresh === 'function'\n );\n\n //trace.log(customComp)\n\n if (customComp !== undefined && typeof customComp.refresh === 'function') {\n customComp?.refresh();\n }\n });\n };\n\n #bindRowData = ($tr, record, rowid, dataIndex) => {\n const templateLength = this.#sheet.templateLength || 1;\n const subRowIndex = parseInt($tr.dataset.subrow, 10) || 0;\n const matrixRow = (dataIndex * templateLength) + subRowIndex;\n\n $tr.dataset.index = dataIndex;\n $tr.dataset.row = rowid;\n $tr.dataset.matrixRow = matrixRow;\n $tr.data = record;\n\n Array.from($tr.cells).forEach(($cell) => {\n $cell.dataset.index = dataIndex;\n $cell.dataset.row = rowid;\n\n const customComp = Array.from($cell.children).find($el =>\n $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.refresh === 'function'\n );\n\n customComp?.refresh();\n });\n };\n\n initialize = () => {\n //trace.log(\"rowManager.initialize\");\n\n this.#isGrouped = this.#sheet.sourceTable.querySelector(\"tbody tr[grouping='true']\") ? true : false;\n\n this.#cachedTemplateHeight = null;\n this.#containerTemplates.clear();\n\n this.#element = {\n scrollTables: this.#sheet.querySelectorAll('.ng-sheet-body table'),\n firstTr: this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body tr'),\n };\n\n // 컨테이너 템플릿 수집 부분도 tbody.body 기준으로 변경\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (!container) return;\n\n const tableEl = container.querySelector('table');\n if (!tableEl) return;\n\n const tbody = tableEl.querySelector('tbody.body'); // 👈 .bindable-tbody 대신 tbody.body\n if (!tbody) return;\n\n const trs = Array.from(tbody.querySelectorAll('tr'));\n const templateTrs = trs.map(tr => tr.cloneNode(true));\n this.#containerTemplates.set(selector, templateTrs);\n });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n\n if (bodyViewport) {\n this.#sheetHeight = bodyViewport.clientHeight;\n\n this.#measureAndCacheHeight();\n this.#renderAllContainers();\n this.#handleScroll(bodyViewport.scrollTop, true);\n\n bodyViewport.addEventListener('scroll', () => {\n if (this.#isProgrammaticScroll) return;\n\n const rowHeight = this.#cachedTemplateHeight || 0;\n const totalCount = this.#sheet.view.getArray()?.length || 0;\n const rawTotalVirtualHeight = totalCount * rowHeight;\n\n if (rawTotalVirtualHeight <= bodyViewport.clientHeight) {\n return;\n }\n\n this.#handleScroll(bodyViewport.scrollTop);\n\n this.#sheet.querySelector('nine-table-vscrollbar').refresh();\n //this.#sheet.querySelector('nine-table-hscrollbar').refresh();\n }, { passive: true });\n }\n };\n\n scrollToDataRow(dataRow, align = 'top', onRendered) {\n //trace.log(\"🔍 [scrollToDataRow ENTER]\", { dataRow, isGrouped: this.#isGrouped });\n\n const bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\n if (!bodyViewport) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const viewRecords = this.#sheet.view.getArray();\n const totalCount = viewRecords?.length || 0;\n if (totalCount === 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n const targetRow = Math.max(0, Math.min(dataRow, totalCount - 1));\n let targetScrollTop = 0;\n\n // 🎯 [핵심] 그룹핑 모드일 때는 실제 scrollHeight(또는 렌더링된 총 높이)를 기준으로 비율 계산\n if (this.#isGrouped) {\n const maxScrollTop = Math.max(bodyViewport.scrollHeight - bodyViewport.clientHeight, 1);\n // targetRow가 전체 totalCount에서 차지하는 비율(ratio)만큼 실제 스크롤 최대 높이에 곱해줌\n const ratio = targetRow / Math.max(totalCount - 1, 1);\n targetScrollTop = ratio * maxScrollTop;\n } else {\n const rowHeight = this.#cachedTemplateHeight;\n if (!rowHeight || rowHeight <= 0) {\n if (typeof onRendered === 'function') onRendered();\n return;\n }\n\n let rawTargetScrollTop = targetRow * rowHeight;\n\n /**\n if (align === 'bottom') {\n const viewportHeight = bodyViewport.clientHeight;\n const visibleRowsCount = Math.floor(viewportHeight / rowHeight);\n const adjustedRow = Math.max(0, targetRow - visibleRowsCount + 1);\n rawTargetScrollTop = adjustedRow * rowHeight;\n } */\n\n const templateLength = this.#sheet.templateLength;\n\n const fixedHeight = (this.#sheet.elements.body.thead?.offsetHeight || 0) +\n (this.#sheet.elements.body.tfoot?.offsetHeight || 0) +\n this.#sheet.elements.body.tbody.head.offsetHeight;\n\n const viewHeight = this.#sheet.querySelector('.ng-sheet-body').offsetHeight || 0;\n // 1. 전체 실제 데이터의 높이 계산\n const rawTotalVirtualHeight = Math.max(totalCount * rowHeight + (rowHeight*2) + fixedHeight - viewHeight, 0);\n\n //const rawTotalVirtualHeight = totalCount * rowHeight;\n const MAX_BROWSER_HEIGHT = 15000000;\n const useScaling = rawTotalVirtualHeight > MAX_BROWSER_HEIGHT;\n\n let scaleFactor = 1;\n if (useScaling) {\n scaleFactor = MAX_BROWSER_HEIGHT / rawTotalVirtualHeight;\n }\n\n targetScrollTop = rawTargetScrollTop * scaleFactor;\n }\n\n //trace.log(\"🔍 [scrollToDataRow CALC FIXED]\", { targetRow, totalCount, targetScrollTop });\n\n this.#isProgrammaticScroll = true;\n bodyViewport.scrollTop = targetScrollTop;\n this.#handleScroll(targetScrollTop);\n //trace.log(targetScrollTop);\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.#isProgrammaticScroll = false;\n if (typeof onRendered === 'function') onRendered();\n });\n });\n }\n\n\n\n destroy = () => {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n };\n\n #measureAndCacheHeight = () => {\n if (!this.#sheet.classList.contains('active')) return;\n\n if (!this.#sheet.sourceTable) return;\n\n const trTemplates = this.#sheet.sourceTable?.querySelectorAll('tbody.body tr');\n //trace.log(\"[DEBUG #measureAndCacheHeight] bodyTemplates count:\", trTemplates?.length);\n //if (!trTemplates || trTemplates.length === 0) return;\n\n const $tbody = this.#sheet.querySelector('.ng-sheet-body .ng-container-body tbody.body');\n //if (!tbody) return -1;\n\n $tbody.querySelectorAll('tr').forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n trTemplates.forEach($tr => fragment.appendChild($tr.cloneNode(true)));\n $tbody.appendChild(fragment);\n\n //let totalHeight = 0;\n const renderedTrs = $tbody.querySelectorAll('tr');\n\n this.#templateRowHeights = [];\n renderedTrs.forEach($tr => {\n //const h = $tr.offsetHeight;\n //trace.log(`[DEBUG #measureAndCacheHeight] tr[${idx}] height:`, h);\n //totalHeight += h;\n\n this.#templateRowHeights.push($tr.offsetHeight);\n });\n\n renderedTrs.forEach(tr => tr.remove());\n\n this.#cachedTemplateHeight = this.#templateRowHeights.reduce((sum, h) => sum + h, 0);\n\n this.#updateRowCount();\n };\n\n #updateRowCount = () => {\n trace.log(\"[DEBUG #updateRowCount] sheetHeight:\", this.#sheetHeight, \"cachedTemplateHeight:\", this.#cachedTemplateHeight);\n if (this.#sheetHeight > 0 && this.#cachedTemplateHeight > 0) {\n const visibleRows = Math.ceil(this.#sheetHeight / this.#cachedTemplateHeight);\n\n // 💡 [유연한 개선] 그룹화가 켜져 있다면 그룹 컬럼 깊이(다단 레벨)에 따라 버퍼를 동적으로 확장\n let dynamicBuffer = this.#BUFFER_ROW_COUNT;\n if (this.#isGrouped && this.#sheet.grouping) {\n const groupDepth = this.#sheet.grouping.columns?.length || 1;\n // 그룹 단계가 깊을수록 헤더 행이 많이 차지하므로 여유분을 비례해서 늘림 (예: 기본 버퍼 + (뎁스당 추가 여유))\n dynamicBuffer += (groupDepth * 15);\n }\n\n this.#cachedRowCount = visibleRows + dynamicBuffer;\n trace.log(\"[DEBUG #updateRowCount] calculated cachedRowCount:\", this.#cachedRowCount);\n }\n };\n\n #renderAllContainers = () => {\n trace.log(\"rowManager.#renderAllContainers\");\n\n ['.ng-container-body', '.ng-container-left', '.ng-container-right'].forEach(selector => {\n const container = this.#sheet.querySelector(`.ng-sheet-body ${selector}`);\n if (container && container.querySelector('tbody')) {\n this.#renderRows(container); // selector 인자 제거!\n }\n });\n\n this.#syncRowHeights();\n };\n\n #renderRows = (container) => {\n let targetFixedType = null;\n if (container.classList.contains('ng-container-left')) targetFixedType = 'left';\n else if (container.classList.contains('ng-container-right')) targetFixedType = 'right';\n\n // 🎯 [수정] 원본 테이블에서 tbody.body에 해당하는 tr들만 복제\n const templateTrs = Array.from(this.#sheet.sourceTable.querySelectorAll('tbody.body tr')).map(tr => {\n const clonedTr = tr.cloneNode(true);\n\n if (targetFixedType === 'left') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'left') $cell.remove();\n });\n } else if (targetFixedType === 'right') {\n clonedTr.querySelectorAll('th,td').forEach($cell => {\n if ($cell.getAttribute('fixed') !== 'right') $cell.remove();\n });\n } else {\n clonedTr.querySelectorAll('[fixed=left], [fixed=right]').forEach($cell => {\n $cell.remove();\n });\n }\n\n return clonedTr;\n });\n\n if (templateTrs.length === 0) return;\n\n // 🎯 [수정] targetTbody도 일반 tbody가 아니라 tbody.body를 정확히 타겟팅\n const targetTbody = container.querySelector('tbody.body');\n if (!targetTbody) return;\n\n targetTbody.querySelectorAll(\"tr\").forEach(tr => tr.remove());\n\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < this.#cachedRowCount; i++) {\n templateTrs.forEach(tmpl => fragment.appendChild(tmpl.cloneNode(true)));\n }\n\n\n targetTbody.appendChild(fragment);\n\n if (container.classList.contains('ng-container-body')) {\n this.#element.firstTr = targetTbody.querySelector('tr');\n }\n };\n\n\n\n #syncRowHeights = () => {\n const leftTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-left table');\n const bodyTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-body table');\n const rightTable = this.#sheet.querySelector('.ng-sheet-body .ng-container-right table');\n\n if (bodyTable) {\n const leftRows = leftTable ? Array.from(leftTable.querySelectorAll('tbody tr')) : [];\n const bodyRows = Array.from(bodyTable.querySelectorAll('tbody tr'));\n const rightRows = rightTable ? Array.from(rightTable.querySelectorAll('tbody tr')) : [];\n\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n }\n };\n\n #initResizeObserver = () => {\n\n if (!this.#sheet || !(this.#sheet instanceof HTMLElement)) return;\n\n this.#resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const sheetEl = entry.target;\n if (!sheetEl.classList.contains('active')) continue;\n\n const height = entry.contentRect.height;\n const width = entry.contentRect.width;\n\n if (width > 0 && this.#sheet.isAutoFitCol) {\n this.#sheet.autoFit(true);\n }\n\n if (height > 0 && this.#sheetHeight !== height) {\n this.#sheetHeight = height;\n this.#updateRowCount();\n\n if (this.#cachedTemplateHeight !== null) {\n this.#renderAllContainers();\n this.refresh();\n }\n }\n }\n });\n\n this.#resizeObserver.observe(this.#sheet);\n };\n}","import { trace } from \"@nopeer\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class TableCompiler {\n\n static compile($srcTable) {\n\n const $table = $srcTable.cloneNode(true);\n\n // 1. 헤더 컴파일\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n // 4. colgroup과 인덱스/fixed 속성 동기화\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n static recompile($table) {\n\n /** 너비조정은 필요없을듯 */\n /**\n const cols = Array.from($table.querySelectorAll('colgroup col'));\n cols.forEach((col, idx) => {\n //trace.log(col.cloneNode(true));\n\n col.setAttribute('data-col', idx);\n\n let w = col.getAttribute('width');\n if (!w || isNaN(parseFloat(w))) {\n w = parseFloat(col.style.width);\n }\n if (w && !isNaN(parseFloat(w))) {\n const numericWidth = Math.round(parseFloat(w));\n //trace.log(w, numericWidth);\n\n col.setAttribute('width', numericWidth);\n col.style.width = `${numericWidth}px`;\n }\n }); */\n\n TableCompiler.resetColIndex($table, $table.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex($table, $table.querySelectorAll('tfoot tr'));\n\n TableCompiler.#syncColAttributes($table);\n\n return $table;\n }\n\n\n\n static #syncColAttributes($table) {\n\n $table.querySelectorAll('colgroup col').forEach(($col, i) => {\n $col.setAttribute('data-col', i);\n const fixed = $col.getAttribute('fixed');\n\n $table.querySelectorAll(`[data-col=\"${i}\"]`).forEach($el => {\n fixed ? $el.setAttribute('fixed', fixed) : $el.removeAttribute('fixed');\n });\n });\n }\n\n static resetColIndex($table, trs) {\n\n const cols = $table.querySelectorAll('colgroup col');\n const grid = Array.from({ length: trs.length }, () => Array(cols.length).fill(null));\n\n trs.forEach(($tr, index) => {\n\n $tr.dataset.subrow = index;\n\n let colIndex = 0;\n\n $tr.querySelectorAll('th, td').forEach($cell => {\n\n while (colIndex < cols.length && grid[index][colIndex] !== null) {\n colIndex++;\n }\n\n $cell.dataset.col = colIndex;\n\n const rowSpan = $cell.rowSpan || 1;\n const colSpan = $cell.colSpan || 1;\n\n for (let r = 0; r < rowSpan; r++) {\n for (let c = 0; c < colSpan; c++) {\n if (index + r < trs.length && colIndex + c < cols.length) {\n grid[index + r][colIndex + c] = $cell;\n }\n }\n }\n\n colIndex += colSpan;\n });\n });\n }\n\n\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellSelection {\r\n\t#sheet;\r\n\t#range = { startRow: -1, startCol: -1, endRow: -1, endCol: -1 };\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#initEvents();\r\n\r\n\t\t/**\r\n\t\t// 🎯 [신규 구조 대응] .ng-sheet-body 및 내부 컨테이너 스크롤 감지\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (bodyViewport) {\r\n\t\t\tbodyViewport.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t} */\r\n\r\n\t\t/**\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.addEventListener('scroll', () => {\r\n\t\t\t\tif (this.#range.startRow >= 0 && this.#range.startCol >= 0) {\r\n\t\t\t\t\tthis.render();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}); */\r\n\r\n\t\ttrace.log(\"🎯 [CellSelection] Initialized (New Structure Compatible)\");\r\n\t}\r\n\r\n\t#getMatrixRow(tr) {\r\n\t\tif (!tr) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10);\r\n\t\tif (isNaN(dataRow)) return { dataRow: -1, subRowIndex: -1, matrixRow: -1 };\r\n\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tconst trs = Array.from(tbody.querySelectorAll('tr:not(.nodata)'));\r\n\r\n\t\tconst sameGroupTrs = trs.filter(t => parseInt(t.dataset.row, 10) === dataRow);\r\n\t\tconst subRowIndex = sameGroupTrs.indexOf(tr);\r\n\t\tconst templateLength = sameGroupTrs.length > 0 ? sameGroupTrs.length : 1;\r\n\r\n\t\tconst matrixRow = (dataRow * templateLength) + (subRowIndex >= 0 ? subRowIndex : (tr.sectionRowIndex % templateLength));\r\n\r\n\t\treturn { dataRow, subRowIndex, matrixRow };\r\n\t}\r\n\r\n\tsetFocus(matrixRow, col) {\r\n\t\t// 1. 기존 포커스 클래스 제거\r\n\t\tthis.#sheet.querySelectorAll(`tr.selected-start`).forEach($tr => {$tr.classList.remove(\"selected-start\");\r\n\t\t\t$tr.querySelectorAll(`td.selected-start`).forEach($td => {$td.classList.remove(\"selected-start\");\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 [신규 구조 대응] data-matrix-row 탐색 경로 수정 (.ng-sheet-body-content 기준)\r\n\t\tconst $td = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`);\r\n\t\tif (!$td) return;\r\n\r\n\t\t$td.classList.add(\"selected-start\");\r\n\t\t$td.closest('tr')?.classList.add(\"selected-start\");\r\n\t}\r\n\r\n\tsetRange(startRow, startCol, endRow, endCol) {\r\n\t\tlet r1 = Math.min(startRow, endRow);\r\n\t\tlet r2 = Math.max(startRow, endRow);\r\n\t\tlet c1 = Math.min(startCol, endCol);\r\n\t\tlet c2 = Math.max(startCol, endCol);\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\tlet expanded = true;\r\n\t\tlet loopCount = 0;\r\n\r\n\t\twhile (expanded && loopCount < 5) {\r\n\t\t\texpanded = false;\r\n\t\t\tloopCount++;\r\n\r\n\t\t\tcontainers.forEach(container => {\r\n\t\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\t\tif (tr.classList.contains('nodata')) return;\r\n\t\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\r\n\t\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\t\tconst isIntersecting = cellEndRow >= r1 && matrixRow <= r2 && cellEndCol >= c1 && col <= c2;\r\n\r\n\t\t\t\t\t\tif (isIntersecting) {\r\n\t\t\t\t\t\t\tconst nsR = Math.min(r1, matrixRow);\r\n\t\t\t\t\t\t\tconst neR = Math.max(r2, cellEndRow);\r\n\t\t\t\t\t\t\tconst nsC = Math.min(c1, col);\r\n\t\t\t\t\t\t\tconst neC = Math.max(c2, cellEndCol);\r\n\r\n\t\t\t\t\t\t\tif (nsR !== r1 || neR !== r2 || nsC !== c1 || neC !== c2) {\r\n\t\t\t\t\t\t\t\tr1 = nsR; r2 = neR; c1 = nsC; c2 = neC;\r\n\t\t\t\t\t\t\t\texpanded = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#range = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trefresh = () => {\r\n\t\tthis.render();\r\n\t}\r\n\r\n\trender = () => {\r\n\t\tconst { startRow, startCol, endRow, endCol } = this.#range;\r\n\r\n\t\t// 🎯 [신규 구조 대응] 컨테이너 셀렉터 경로 수정\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body-content .ng-container-left, .ng-sheet-body-content .ng-container-body, .ng-sheet-body-content .ng-container-right'\r\n\t\t);\r\n\r\n\t\t// 1. 기존 선택 클래스 초기화\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('.selected, .selected-top, .selected-bottom, .selected-left, .selected-right, .selected-start').forEach(el => {\r\n\t\t\t\tel.classList.remove('selected', 'selected-top', 'selected-bottom', 'selected-left', 'selected-right', 'selected-start');\r\n\t\t\t});\r\n\t\t\tcontainer.querySelectorAll('tr.selected-start').forEach(tr => {\r\n\t\t\t\ttr.classList.remove('selected-start');\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tif (startRow < 0 || startCol < 0) return;\r\n\r\n\t\t// 2. 범위 렌더링\r\n\t\tcontainers.forEach((container) => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => {\r\n\t\t\t\tconst { matrixRow } = this.#getMatrixRow(tr);\r\n\t\t\t\tif (matrixRow < 0) return;\r\n\r\n\t\t\t\ttr.querySelectorAll('td, th').forEach(cell => {\r\n\t\t\t\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (isNaN(col)) return;\r\n\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tconst colSpan = parseInt(cell.colSpan || 1, 10);\r\n\r\n\t\t\t\t\tconst cellEndRow = matrixRow + rowSpan - 1;\r\n\t\t\t\t\tconst cellEndCol = col + colSpan - 1;\r\n\r\n\t\t\t\t\tconst isSelected = cellEndRow >= startRow && matrixRow <= endRow && cellEndCol >= startCol && col <= endCol;\r\n\t\t\t\t\tif (!isSelected) return;\r\n\r\n\t\t\t\t\tcell.classList.add('selected');\r\n\r\n\t\t\t\t\tif (matrixRow <= startRow) cell.classList.add('selected-top');\r\n\t\t\t\t\tif (cellEndRow >= endRow) cell.classList.add('selected-bottom');\r\n\t\t\t\t\tif (col <= startCol) cell.classList.add('selected-left');\r\n\t\t\t\t\tif (cellEndCol >= endCol) cell.classList.add('selected-right');\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 3. 포커스 셀 복구\r\n\t\tconst $focusTd = this.#sheet.querySelector(`.ng-sheet-body-content tr[data-matrix-row=\"${startRow}\"] td[data-col=\"${startCol}\"]`);\r\n\t\tif ($focusTd) {$focusTd.classList.add(\"selected-start\");\r\n\t\t\t$focusTd.closest('tr')?.classList.add(\"selected-start\");\r\n\t\t}\r\n\t}\r\n\r\n\t#initEvents() {\r\n\t\tconst mainZone = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tif (!mainZone) {\r\n\t\t\ttrace.log(\"❌ [CellSelection] .ng-sheet-body not found!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmainZone.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tif (cell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\tthis.#sheet.style.userSelect = 'none';\r\n\t\t\tthis.#sheet.style.webkitUserSelect = 'none';\r\n\r\n\t\t\tconst tr = cell.closest('tr');\r\n\t\t\tconst { matrixRow: startRow } = this.#getMatrixRow(tr);\r\n\t\t\tconst startCol = parseInt(cell.dataset.col, 10);\r\n\r\n\t\t\tif (startRow < 0) {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tthis.setFocus(startRow, startCol);\r\n\t\t\tthis.setRange(startRow, startCol, startRow, startCol);\r\n\r\n\t\t\tlet lastMatrixRow = startRow;\r\n\t\t\tlet lastCol = startCol;\r\n\r\n\t\t\tconst onMouseMove = (moveEvent) => {\r\n\t\t\t\tconst targetEl = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);\r\n\t\t\t\tlet targetCell = targetEl?.closest('td, th');\r\n\r\n\t\t\t\tif (!targetCell || !this.#sheet.contains(targetCell)) {\r\n\t\t\t\t\tconst allCells = this.#sheet.querySelectorAll('.ng-sheet-body-content tbody tr:not(.nodata) td, .ng-sheet-body-content tbody tr:not(.nodata) th');\r\n\t\t\t\t\tfor (const c of allCells) {\r\n\t\t\t\t\t\tconst rect = c.getBoundingClientRect();\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tmoveEvent.clientX >= rect.left &&\r\n\t\t\t\t\t\t\tmoveEvent.clientX <= rect.right &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY >= rect.top &&\r\n\t\t\t\t\t\t\tmoveEvent.clientY <= rect.bottom\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\ttargetCell = c;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!targetCell) return;\r\n\t\t\t\tif (targetCell.dataset.row === undefined || targetCell.dataset.col === undefined) return;\r\n\t\t\t\tif (targetCell.closest('tr').classList.contains('nodata')) return;\r\n\r\n\t\t\t\tconst targetTr = targetCell.closest('tr');\r\n\t\t\t\tconst { matrixRow: endRow } = this.#getMatrixRow(targetTr);\r\n\t\t\t\tconst endCol = parseInt(targetCell.dataset.col, 10);\r\n\r\n\t\t\t\tif (endRow < 0) return;\r\n\t\t\t\tif (lastMatrixRow === endRow && lastCol === endCol) return;\r\n\r\n\t\t\t\tlastMatrixRow = endRow;\r\n\t\t\t\tlastCol = endCol;\r\n\r\n\t\t\t\tthis.setRange(startRow, startCol, endRow, endCol);\r\n\t\t\t};\r\n\r\n\t\t\tconst onMouseUp = () => {\r\n\t\t\t\tthis.#sheet.style.userSelect = '';\r\n\t\t\t\tthis.#sheet.style.webkitUserSelect = '';\r\n\r\n\t\t\t\tdocument.removeEventListener('mousemove', onMouseMove);\r\n\t\t\t\tdocument.removeEventListener('mouseup', onMouseUp);\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener('mousemove', onMouseMove);\r\n\t\t\tdocument.addEventListener('mouseup', onMouseUp);\r\n\t\t});\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\n\r\nexport class CellNavigation {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#currentCell = null;\r\n\t#currentTr = null;\r\n\t#currentRow = -1;\r\n\t#currentCol = -1;\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.#initEvents();\r\n\t\ttrace.log(\"🎯 [CellNavigation] Initialized (Diagnostic Logging Restored)\");\r\n\t}\r\n\r\n\tget currentCell() {\r\n\t\treturn this.#currentCell;\r\n\t}\r\n\r\n\tset currentCell(cell) {\r\n\t\tif (!cell) return;\r\n\r\n\t\tthis.#currentCell = cell;\r\n\t\tcell.focus({ preventScroll: true });\r\n\r\n\t\tthis.#currentTr = cell.closest(\"tr\");\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\ttrace.log(`📌 [setCurCell] Active set -> dataRow: ${cell.dataset.row}, subrow: ${cell.closest('tr')?.dataset.subrow}, matrixRow: ${matrixRow}, col: ${cell.dataset.col}`);\r\n\t\tthis.#sheet.selection.setFocus(matrixRow, this.#currentCell.dataset.col);\r\n\t}\r\n\r\n\t#getMatrixRowFromTr(tr) {\r\n\t\tif (!tr) return 0;\r\n\t\tconst dataRow = parseInt(tr.dataset.row, 10) || 0;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\t// 1. tr에 data-matrix-row가 박혀있다면 최우선 사용\r\n\t\tconst mRowAttr = parseInt(tr.dataset.matrixRow, 10);\r\n\t\tif (!isNaN(mRowAttr)) return mRowAttr;\r\n\r\n\t\t// 2. tbody 내에서 동일 data-row를 가진 그룹 중 몇 번째 서브 행인지 정확히 산출\r\n\t\tconst tbody = tr.closest('tbody');\r\n\t\tif (tbody) {\r\n\t\t\tconst groupTrs = Array.from(tbody.querySelectorAll(`tr[data-row=\"${dataRow}\"]`));\r\n\t\t\tconst subIdx = groupTrs.indexOf(tr);\r\n\t\t\tif (subIdx >= 0) {\r\n\t\t\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\t\t\treturn (dataRow * templateLength) + subIdx;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst subRowIndex = parseInt(tr.dataset.subrow, 10) || 0;\r\n\t\t// 🎯 [수정] 깨진 연산자 복구 (* 연산)\r\n\t\treturn (dataRow * templateLength) + subRowIndex;\r\n\t}\r\n\r\n\tmoveCell(e) {\r\n\r\n\t\t//trace.log(e.target.tagName);\r\n\t\tif (![\"TH\",\"TD\"].includes(e.target.tagName)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!this.#currentCell || !this.#currentTr) {\r\n\t\t\ttrace.log(\"⚠️ [moveCell] currentCell or currentTr is missing!\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst cell = this.#currentCell;\r\n\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\tconst col = parseInt(cell.dataset.col, 10);\r\n\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\t\tconst matrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\r\n\t\tlet nextMatrixRow = matrixRow;\r\n\t\tlet nextCol = col;\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tnextMatrixRow = matrixRow + (cell.rowSpan || 1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\t\tnextMatrixRow = Math.max(0, matrixRow - (cell.rowSpan || 1));\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tnextCol = this.#getPreviousCol(matrixRow, col);\r\n\t\t\t\t\tif (nextCol < 0 && matrixRow > 0) {\r\n\t\t\t\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow - 1;\r\n\t\t\t\t\t\tconst prevTrs = this.#findTargetTrsByMatrix(nextMatrixRow);\r\n\t\t\t\t\t\tconst maxColCell = this.#getMaxColCell(prevTrs);\r\n\t\t\t\t\t\tnextCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) : 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tnextCol = this.#getNextCol(matrixRow, col);\r\n\t\t\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\t\t\tconst maxColCell = this.#getMaxColCell(targetTrs);\r\n\t\t\t\t\tconst maxCol = maxColCell ? parseInt(maxColCell.dataset.col, 10) + parseInt(maxColCell.colSpan || 1, 10) : 0;\r\n\r\n\t\t\t\t\tif (nextCol >= maxCol) {\r\n\t\t\t\t\t\tnextMatrixRow = matrixRow + 1;\r\n\t\t\t\t\t\tnextCol = 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\r\n\t\tswitch (e.code) {\r\n\t\t\tcase \"ArrowDown\":\r\n\t\t\t\tconst maxDataRow = this.#host.data.length;\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst maxMatrixRowLimit = (maxDataRow * templateLength) - 1;\r\n\t\t\t\tif (matrixRow + (cell.rowSpan || 1) > maxMatrixRowLimit) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowUp\":\r\n\t\t\t\tif (matrixRow <= 0) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowRight\":\r\n\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"ArrowLeft\":\r\n\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"Tab\":\r\n\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\tif (col === nextCol || nextCol < this.#getMinCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (col === nextCol || nextCol > this.#getMaxCol(dataRow, col)) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\ttrace.log(\"========\")\r\n\r\n\t\t// 🎯 전체 데이터 갯수 한계 체크 (오버플로우 방지)\r\n\t\tconst totalCount = this.#sheet.view.getArray()?.length || 0;\r\n\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\tconst maxMatrixRow = (totalCount * templateLength) - 1;\r\n\t\tnextMatrixRow = Math.max(0, Math.min(nextMatrixRow, maxMatrixRow));\r\n\r\n\t\ttrace.log(`⌨️ [Key: ${e.code}] Current matrixRow: ${matrixRow} -> Target nextMatrixRow: ${nextMatrixRow}, nextCol: ${nextCol}`);\r\n\r\n\t\tconst nextDataRow = Math.floor(nextMatrixRow / templateLength);\r\n\t\tconst nextSubRowIndex = nextMatrixRow % templateLength;\r\n\r\n\t\tconst attemptFindAndMove = (retries = 0) => {\r\n\t\t\tlet targetCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\r\n\t\t\tif (targetCell) {\r\n\t\t\t\ttrace.log(`✅ [Found Cell] Attempt ${retries} -> dataRow: ${targetCell.dataset.row}, col: ${targetCell.dataset.col}`);\r\n\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(this.#currentTr);\r\n\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, targetCell.dataset.col, actualMatrixRow, targetCell.dataset.col);\r\n\r\n\t\t\t\tthis.#ensureCellVisible(targetCell);\r\n\t\t\t} else {\r\n\t\t\t\ttrace.log(`📜 [Scroll Trigger] Cell not found in DOM, invoking rowManager.scrollToDataRow(${nextDataRow})`);\r\n\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(nextDataRow, \"bottom\", () => {\r\n\t\t\t\t\ttrace.log(\"nextDataRow\", nextDataRow);\r\n\r\n\t\t\t\t\tconst retryLoop = () => {\r\n\t\t\t\t\t\tlet retryCell = this.#getNearElement(nextDataRow, nextSubRowIndex, nextCol, nextMatrixRow);\r\n\t\t\t\t\t\tif (retryCell) {\r\n\t\t\t\t\t\t\ttrace.log(`✅ [Found After Scroll] RetryLoop success -> dataRow: ${retryCell.dataset.row}`);\r\n\t\t\t\t\t\t\tthis.currentCell = retryCell;\r\n\t\t\t\t\t\t\tconst tr = retryCell.closest(\"tr\");\r\n\t\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, retryCell.dataset.col, actualMatrixRow, retryCell.dataset.col);\r\n\t\t\t\t\t\t\tthis.#ensureCellVisible(retryCell);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t};\r\n\t\t\t\t\tretryLoop();\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tattemptFindAndMove();\r\n\t}\r\n\r\n\t#ensureCellVisible(cell) {\r\n\t\tconst bodyViewport = this.#sheet.querySelector('.ng-sheet-body');\r\n\t\tconst bodyContainer = this.#sheet.querySelector('.ng-sheet-body .ng-container-body');\r\n\t\tconst headerBody = this.#sheet.querySelector('.ng-sheet-header .ng-container-body');\r\n\r\n\t\tif (!bodyViewport || !bodyContainer) return;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst viewportRect = bodyViewport.getBoundingClientRect();\r\n\t\tconst containerRect = bodyContainer.getBoundingClientRect();\r\n\t\tconst headerRect = headerBody ? headerBody.getBoundingClientRect() : null;\r\n\r\n\t\ttrace.log(`📐 [DIAGNOSTIC VISIBILITY] \r\n- cell.dataset.col: ${cell.dataset.col}\r\n- cellRect (left: ${cellRect.left}, right: ${cellRect.right})\r\n- containerRect (left: ${containerRect.left}, right: ${containerRect.right}, width: ${containerRect.width}, scrollLeft: ${bodyContainer.scrollLeft}, scrollWidth: ${bodyContainer.scrollWidth}, clientWidth: ${bodyContainer.clientWidth})\r\n- viewportRect (width: ${viewportRect.width})\r\n- headerBody (scrollLeft: ${headerBody?.scrollLeft}, width: ${headerRect?.width})\r\n `);\r\n\r\n\t\tconst isAbove = cellRect.top < viewportRect.top;\r\n\t\tconst isBelow = cellRect.bottom > viewportRect.bottom;\r\n\r\n\t\tif (isAbove || isBelow) {\r\n\t\t\tconst dataRow = parseInt(cell.dataset.row, 10);\r\n\t\t\tconst col = cell.dataset.col;\r\n\t\t\tconst $tr = cell.closest(\"tr\");\r\n\t\t\tconst subrow = $tr?.dataset.subrow || 0;\r\n\r\n\t\t\tif (!isNaN(dataRow) && this.#sheet.rowManager) {\r\n\t\t\t\ttrace.log(\"11111111111\");\r\n\t\t\t\tthis.#sheet.rowManager.scrollToDataRow(dataRow, \"top\", () => {\r\n\t\t\t\t\tconst targetCell = this.#sheet.querySelector(`.ng-sheet-body tr[data-row=\"${dataRow}\"][data-subrow=\"${subrow}\"] td[data-col=\"${col}\"]`);\r\n\t\t\t\t\tif (targetCell) {\r\n\t\t\t\t\t\tthis.currentCell = targetCell;\r\n\t\t\t\t\t\tconst tr = targetCell.closest(\"tr\");\r\n\t\t\t\t\t\tconst actualMatrixRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\t\t\tthis.#sheet.selection.setRange(actualMatrixRow, col, actualMatrixRow, col);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (cellRect.left < containerRect.left) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Left] cell out of left bound`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft -= (containerRect.left - cellRect.left + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t} else if (cellRect.right > containerRect.right) {\r\n\t\t\ttrace.log(`↔️ [Scroll X Right] cell out of right bound. cellRect.right: ${cellRect.right} > containerRect.right: ${containerRect.right}`);\r\n\t\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 연산)\r\n\t\t\tbodyContainer.scrollLeft += (cellRect.right - containerRect.right + 10);\r\n\t\t\tthis.#sheet.scrollToX(bodyContainer.scrollLeft);\r\n\t\t}\r\n\t}\r\n\r\n\t#getMinCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet minCol = Infinity;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tminCol = Math.min(minCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn minCol === Infinity ? 0 : minCol;\r\n\t};\r\n\r\n\t#getMaxCol = (dataRow) => {\r\n\t\tconst cells = this.#sheet.querySelectorAll(`.ng-sheet-body td[data-row=\"${dataRow}\"]`);\r\n\t\tif (!cells || cells.length === 0) return 0;\r\n\t\tlet maxCol = 0;\r\n\t\tcells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tmaxCol = Math.max(maxCol, c);\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn maxCol;\r\n\t};\r\n\r\n\t#getMaxColCell = (targetTrs) => {\r\n\t\tconst allCells = [];\r\n\t\ttargetTrs.forEach(tr => allCells.push(...Array.from(tr.querySelectorAll('td'))));\r\n\t\tif (allCells.length === 0) return null;\r\n\t\tallCells.sort((a, b) => parseInt(a.dataset.col, 10) - parseInt(b.dataset.col, 10));\r\n\t\t// 🎯 [수정] 깨진 마이너스 연산자 복구 (- 1)\r\n\t\treturn allCells[allCells.length - 1];\r\n\t};\r\n\r\n\t#getNextCol = (matrixRow, col) => {\r\n\t\tconst td = this.#sheet.querySelector(`.ng-sheet-body tr[data-matrix-row=\"${matrixRow}\"] td[data-col=\"${col}\"]`) ||\r\n\t\t\tthis.#sheet.querySelector(`.ng-sheet-body td[data-col=\"${col}\"]`);\r\n\r\n\t\tconst colSpan = td?.colSpan || 1;\r\n\t\tconst next = col + colSpan;\r\n\t\ttrace.log(`🔍 [#getNextCol] current col: ${col}, found td colSpan: ${colSpan}, calculated next col: ${next}`);\r\n\t\treturn next;\r\n\t}\r\n\r\n\t#getPreviousCol = (matrixRow, currentCol) => {\r\n\t\tif (currentCol <= 0) return 0;\r\n\t\tconst currentTrCells = this.#currentTr ? Array.from(this.#currentTr.querySelectorAll('td, th')) : [];\r\n\t\tconst cols = new Set();\r\n\r\n\t\tcurrentTrCells.forEach(cell => {\r\n\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\tcols.add(c);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (cols.size === 0) {\r\n\t\t\tconst targetTrs = this.#findTargetTrsByMatrix(matrixRow);\r\n\t\t\ttargetTrs.forEach(tr => {\r\n\t\t\t\tArray.from(tr.querySelectorAll('td, th')).forEach(cell => {\r\n\t\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\t\tif (!isNaN(c) && window.getComputedStyle(cell).display !== 'none') {\r\n\t\t\t\t\t\tcols.add(c);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst smallerCols = Array.from(cols).filter(c => c < currentCol);\r\n\t\treturn smallerCols.length === 0 ? Math.max(0, currentCol - 1) : Math.max(...smallerCols);\r\n\t};\r\n\r\n\t#findTargetTrsByMatrix = (matrixRow) => {\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body .ng-container-left, .ng-sheet-body .ng-container-body, .ng-sheet-body .ng-container-right'\r\n\t\t);\r\n\t\tconst matchedTrs = [];\r\n\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tconst trs = Array.from(container.querySelectorAll('tbody tr'));\r\n\t\t\tfor (const tr of trs) {\r\n\t\t\t\tconst mRow = this.#getMatrixRowFromTr(tr);\r\n\t\t\t\tif (mRow === matrixRow) {\r\n\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst cells = Array.from(tr.querySelectorAll('td'));\r\n\t\t\t\tlet foundInSpan = false;\r\n\t\t\t\tfor (const cell of cells) {\r\n\t\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\t\t\t\t\tif (rowSpan > 1 && matrixRow >= mRow && matrixRow < mRow + rowSpan) {\r\n\t\t\t\t\t\tmatchedTrs.push(tr);\r\n\t\t\t\t\t\tfoundInSpan = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (foundInSpan) break;\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn matchedTrs;\r\n\t};\r\n\r\n\t#getNearElement = (dataRow, subRowIndex, col, matrixRow) => {\r\n\t\tconst targetMatrixRow = matrixRow !== undefined ? matrixRow : (dataRow * (this.#sheet.templateLength || 1)) + subRowIndex;\r\n\t\tconst templateLength = this.#sheet.templateLength || 1;\r\n\r\n\t\tconst targetDataRow = Math.floor(targetMatrixRow / templateLength);\r\n\t\tconst targetSubRow = targetMatrixRow % templateLength;\r\n\r\n\t\tconst containers = this.#sheet.querySelectorAll(\r\n\t\t\t'.ng-sheet-body, .ng-container-left, .ng-container-body, .ng-container-right, .ng-part-body'\r\n\t\t);\r\n\r\n\t\tconst searchedTrs = new Set();\r\n\t\tcontainers.forEach(container => {\r\n\t\t\tcontainer.querySelectorAll('tbody tr').forEach(tr => searchedTrs.add(tr));\r\n\t\t});\r\n\r\n\t\tfor (const tr of Array.from(searchedTrs)) {\r\n\t\t\tconst trDataRow = parseInt(tr.dataset.row, 10);\r\n\t\t\tif (isNaN(trDataRow)) continue;\r\n\r\n\t\t\tconst tbody = tr.closest('tbody');\r\n\t\t\tconst groupTrs = tbody ? Array.from(tbody.querySelectorAll(`tr[data-row=\"${trDataRow}\"]`)) : [tr];\r\n\t\t\tconst trSubIdx = groupTrs.indexOf(tr);\r\n\r\n\t\t\tfor (const cell of Array.from(tr.querySelectorAll('td'))) {\r\n\t\t\t\tconst c = parseInt(cell.dataset.col, 10);\r\n\t\t\t\tconst span = parseInt(cell.colSpan || 1, 10);\r\n\t\t\t\tconst rowSpan = parseInt(cell.rowSpan || 1, 10);\r\n\r\n\t\t\t\tif (isNaN(c) || window.getComputedStyle(cell).display === 'none') continue;\r\n\r\n\t\t\t\tconst cellDataRowStart = trDataRow;\r\n\t\t\t\tconst cellSubRowStart = trSubIdx;\r\n\r\n\t\t\t\t// 🎯 [수정] 깨진 곱하기/마이너스 연산자 복구 (* , - 1)\r\n\t\t\t\tconst cellStartMatrix = (cellDataRowStart * templateLength) + cellSubRowStart;\r\n\t\t\t\tconst cellEndMatrix = cellStartMatrix + rowSpan - 1;\r\n\r\n\t\t\t\tif (targetMatrixRow >= cellStartMatrix && targetMatrixRow <= cellEndMatrix) {\r\n\t\t\t\t\tif (col >= c && col < c + span) {\r\n\t\t\t\t\t\treturn cell;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn null;\r\n\t};\r\n\r\n\t#initEvents() {\r\n\t\tthis.#sheet.addEventListener('mousedown', (e) => {\r\n\t\t\tif (e.button !== 0) return;\r\n\t\t\tconst cell = e.target.closest('td, th');\r\n\t\t\tif (!cell) return;\r\n\t\t\tif (cell.dataset.row === undefined || cell.dataset.col === undefined) return;\r\n\t\t\tthis.currentCell = cell;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.addEventListener('keydown', (e) => {\r\n\t\t\tif ([\"Tab\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\r\n\t\t\t\tthis.moveCell(e);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}","// ui/col/ColResizer.js\nimport { trace } from \"@nopeer\";\nimport { COLLAPSED_WIDTH, TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nconst RESIZE_OFFSET = 2; // 🎯 리사이즈 감지 영역 오프셋을 상단으로 추출\n\nexport class ColResizer {\n #sheet;\n #host;\n #panel;\n #tooltip;\n\n #targetColIndex = null;\n #nextColIndex = null;\n #targetContainerType = null;\n #targetCell = null;\n #startX = 0;\n #startColWidth = 0;\n #nextColStartWidth = 0;\n #startCellWidth = 0;\n #startLeft = 0;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#host = sheet.getRootNode().host;\n this.#panel = this.#sheet.querySelector('.ng-col-resizer-panel');\n this.#tooltip = this.#panel?.querySelector('.resizer-overlay');\n this.bindEvents();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointermove', this.#onPointerMove);\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n this.#sheet.removeEventListener('dblclick', this.#onDblClick);\n }\n\n refreshLayout(containerType = 'body') {\n const containers = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType}`));\n if (containers.length === 0) return;\n\n const isFixedContainer = containerType === 'left' || containerType === 'right';\n const isAutoFit = !isFixedContainer && (\n this.#sheet.isAutoFitCol ||\n containers[0].querySelector('table')?.getAttribute('auto-fit-col') === 'true'\n );\n\n if (!isAutoFit) {\n\n const firstColgroup = containers[0].querySelector('table colgroup');\n if (!firstColgroup) return;\n\n let totalWidth = 0;\n const colWidths = {};\n\n Array.from(firstColgroup.querySelectorAll('col')).forEach(col => {\n const colIdx = col.getAttribute('data-col');\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) {\n colWidths[colIdx] = w;\n totalWidth += w;\n }\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n\n trace.log(\"====================\", containers, containerType);\n\n if (containerType === 'body') {\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n //tbl.style.minWidth = `${totalWidth}px`;\n });\n } else {\n container.style.flex = `0 0 ${totalWidth}px`;\n container.style.width = `${totalWidth}px`;\n container.style.minWidth = `${totalWidth}px`;\n container.style.maxWidth = `${totalWidth}px`;\n\n tables.forEach(tbl => {\n tbl.style.width = `${totalWidth}px`;\n tbl.style.minWidth = `${totalWidth}px`;\n tbl.style.maxWidth = `${totalWidth}px`;\n\n Object.entries(colWidths).forEach(([colIdx, w]) => {\n tbl.querySelectorAll(`th[data-col=\"${colIdx}\"], td[data-col=\"${colIdx}\"]`).forEach(cell => {\n cell.style.width = `${w}px`;\n cell.style.minWidth = `${w}px`;\n cell.style.maxWidth = `${w}px`;\n });\n });\n });\n }\n });\n } else {\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n tables.forEach(tbl => {\n //tbl.style.width = '100%';\n //tbl.style.minWidth = '100%';\n //tbl.style.maxWidth = '';\n });\n });\n }\n\n this.#sheet.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n setColumnWidth(globalColIndex, width, containerType = null) {\n\n trace.log(\"setColumnWidth\");\n\n\n let targetCols = [];\n\n //if (containerType) {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`.ng-container-${containerType} table colgroup col[data-col=\"${globalColIndex}\"]`));\n //} else {\n // targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n //}\n targetCols = Array.from(this.#sheet.querySelectorAll(`table colgroup col[data-col=\"${globalColIndex}\"]`));\n\n if (targetCols.length === 0) return;\n\n const firstContainer = targetCols[0].closest('.ng-container-left, .ng-container-body, .ng-container-right');\n const resolvedContainerType = containerType || (\n firstContainer?.classList.contains('ng-container-left') ? 'left' :\n firstContainer?.classList.contains('ng-container-right') ? 'right' : 'body'\n );\n\n targetCols.forEach(col => {\n col.setAttribute('width', width);\n col.style.width = `${width}px`;\n\n trace.log(col, width);\n });\n\n const sourceCol = this.#sheet.sourceTable?.querySelector(`colgroup col[data-col=\"${globalColIndex}\"]`);\n if (sourceCol) {\n sourceCol.setAttribute('width', width);\n sourceCol.style.width = `${width}px`;\n }\n\n\n\n this.refreshLayout(resolvedContainerType);\n\n // 🎯 [핵심] autoFit을 여기서 또 호출하면 루프가 돌거나 레이아웃 계산이 꼬입니다.\n // 바디 영역 리사이즈 시에는 body만 refreshLayout 해주면 됩니다!\n if (resolvedContainerType === 'left' || resolvedContainerType === 'right') {\n this.refreshLayout('body');\n }\n\n this.#sheet.rowManager?.refresh();\n }\n\n #checkIsAutoFit(targetCell) {\n if (this.#sheet.isAutoFitCol) return true;\n const table = targetCell?.closest('table');\n if (table && table.getAttribute('auto-fit-col') === 'true') return true;\n return false;\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointermove', this.#onPointerMove);\n //this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n //this.#sheet.addEventListener('dblclick', this.#onDblClick);\n\n this.#sheet.addDebounseEventListener('dblclick', this.#onDblClick, 'pointerdown', this.#onPointerDown);\n }\n\n #getContainerType(cell) {\n const container = cell.closest('.ng-container-left, .ng-container-body, .ng-container-right');\n if (!container) return null;\n if (container.classList.contains('ng-container-left')) return 'left';\n if (container.classList.contains('ng-container-right')) return 'right';\n return 'body';\n }\n\n #onPointerMove = (e) => {\n\n\n const headerPart = e.target.closest('thead');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n\n headerPart.querySelectorAll('.resizable-edge').forEach(el => {\n if (el !== cell) el.classList.remove('resizable-edge');\n });\n\n if (!cell || cell.dataset.col === undefined) return;\n if (cell.getAttribute('collapsed') === 'true') return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n const isLeftEdge = offsetX <= RESIZE_OFFSET;\n const isRightEdge = (rect.width - offsetX) <= RESIZE_OFFSET;\n\n if (isLeftEdge) {\n const prevCell = cell.previousElementSibling;\n if (!prevCell || prevCell.getAttribute('collapsed') === 'true') {\n cell.classList.remove('resizable-edge');\n return;\n }\n }\n\n if (isLeftEdge || isRightEdge) {\n cell.classList.add('resizable-edge');\n } else {\n cell.classList.remove('resizable-edge');\n }\n };\n\n #onPointerDown = (e) => {\n\n //const path = e.composedPath();\n //const cell1 = path.find(el => el?.nodeType === Node.ELEMENT_NODE && (el.tagName === 'TH' || el.tagName === 'TD'));\n\n //trace.log(e);\n //trace.log( path, cell1);\n\n //const actualTarget = document.elementFromPoint(e.clientX, e.clientY);\n //if (!actualTarget) return;\n\n trace.log(e.actualTarget, e.target);\n\n const headerPart = e.actualTarget.closest('thead');\n if (!headerPart) return;\n\n const cell = e.actualTarget.closest('th, td');\n trace.log(cell, e.actualTarget);\n\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n\n\n e.preventDefault();\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n let targetCell = cell;\n\n if (offsetX <= RESIZE_OFFSET) {\n const prevCell = cell.previousElementSibling;\n if (prevCell && prevCell.dataset.col !== undefined && prevCell.getAttribute('collapsed') !== 'true') {\n targetCell = prevCell;\n } else if (!cell.previousElementSibling) {\n return;\n }\n }\n\n this.#targetCell = targetCell;\n this.#targetContainerType = this.#getContainerType(targetCell);\n\n const container = this.#sheet.querySelector(`.ng-container-${this.#targetContainerType}`);\n if (!container) return;\n\n const baseColIndex = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n this.#targetColIndex = baseColIndex + colSpan - 1;\n\n const isAutoFit = this.#checkIsAutoFit(targetCell);\n if (isAutoFit) {\n this.#nextColIndex = this.#targetColIndex + 1;\n const nextColEl = container.querySelector(`col[data-col=\"${this.#nextColIndex}\"]`);\n if (nextColEl) {\n this.#nextColStartWidth = parseInt(nextColEl.getAttribute('width'), 10) || 100;\n } else {\n this.#nextColIndex = null;\n }\n } else {\n this.#nextColIndex = null;\n }\n\n const targetRect = targetCell.getBoundingClientRect();\n const sheetRect = this.#sheet.getBoundingClientRect();\n\n this.#startCellWidth = targetRect.width;\n this.#startLeft = targetRect.left - sheetRect.left;\n\n const targetColEl = container.querySelector(`col[data-col=\"${this.#targetColIndex}\"]`);\n const attrW = targetColEl?.getAttribute('width');\n this.#startColWidth = (attrW && !isNaN(parseInt(attrW, 10))) ? parseInt(attrW, 10) : targetRect.width / colSpan;\n\n this.#startX = e.clientX;\n\n if (this.#panel) {\n this.#panel.classList.add('active');\n this.#updatePositions(e.clientX);\n }\n\n window.addEventListener('pointermove', this.#onDragMove);\n window.addEventListener('pointerup', this.#onDragEnd, { once: true });\n };\n\n #updatePositions(clientX) {\n let diff = clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxDiff = this.#nextColStartWidth - COLLAPSED_WIDTH;\n const minDiff = -(this.#startColWidth - COLLAPSED_WIDTH);\n diff = Math.max(minDiff, Math.min(diff, maxDiff));\n }\n\n const currentColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n\n const targetRect = this.#targetCell.getBoundingClientRect();\n let realCellWidth = clientX - targetRect.left;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n const maxCellWidth = this.#startCellWidth + (this.#nextColStartWidth - COLLAPSED_WIDTH);\n realCellWidth = Math.min(realCellWidth, maxCellWidth);\n }\n\n const currentCellWidth = Math.max(COLLAPSED_WIDTH, realCellWidth);\n\n if (this.#panel) {\n this.#panel.style.setProperty('--tooltip-left', `${this.#startLeft}px`);\n this.#panel.style.setProperty('--tooltip-width', `${currentCellWidth}px`);\n }\n\n const sizeBadge = this.#tooltip?.querySelector('.size-badge');\n if (sizeBadge) {\n sizeBadge.textContent = `${Math.round(currentColWidth)}px`;\n }\n }\n\n #onDragMove = (e) => {\n trace.log(e);\n this.#updatePositions(e.clientX);\n };\n\n #onDragEnd = (e) => {\n window.removeEventListener('pointermove', this.#onDragMove);\n\n const diff = e.clientX - this.#startX;\n const isAutoFit = this.#checkIsAutoFit(this.#targetCell);\n let finalWidth = 0;\n\n if (isAutoFit && this.#nextColIndex !== null) {\n let newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n let newNextWidth = this.#startColWidth + this.#nextColStartWidth - newColWidth;\n\n if (newNextWidth < COLLAPSED_WIDTH) {\n newNextWidth = COLLAPSED_WIDTH;\n newColWidth = this.#startColWidth + this.#nextColStartWidth - COLLAPSED_WIDTH;\n }\n\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n this.setColumnWidth(this.#nextColIndex, newNextWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n } else {\n const newColWidth = Math.max(COLLAPSED_WIDTH, this.#startColWidth + diff);\n if (this.#targetColIndex !== null && this.#targetContainerType) {\n this.setColumnWidth(this.#targetColIndex, newColWidth, this.#targetContainerType);\n finalWidth = newColWidth;\n }\n }\n\n if (this.#targetCell) {\n const targetCell = this.#targetCell;\n if (targetCell.getAttribute('collapsed') !== 'true' && finalWidth > 20) {\n targetCell.dataset.expandWidth = String(finalWidth);\n }\n }\n\n if (this.#panel) {\n this.#tooltip?.classList.add('fade-out');\n setTimeout(() => {\n this.#panel.classList.remove('active');\n this.#tooltip?.classList.remove('fade-out');\n }, 150);\n }\n\n this.#targetColIndex = null;\n this.#nextColIndex = null;\n this.#targetContainerType = null;\n this.#targetCell = null;\n };\n\n #onDblClick = (e) => {\n\n const targetEl = e.target;\n let cell = targetEl.closest('th, td');\n if (!cell || !cell.classList.contains('resizable-edge')) return;\n\n const rect = cell.getBoundingClientRect();\n const offsetX = e.clientX - rect.left;\n\n if (offsetX <= RESIZE_OFFSET) {\n cell = cell.previousElementSibling;\n }\n\n const baseColIndex = parseInt(cell.dataset.col, 10);\n const tbodyCell = this.#sheet.querySelector(`tbody.body [data-col=\"${baseColIndex}\"]`);\n if (!tbodyCell || !tbodyCell.dataset.bind || tbodyCell.classList.contains(\"CELL-RADIO\")) return;\n\n let extraPadding = 0;\n Array.from(tbodyCell.firstElementChild.children).forEach(($el) => {\n switch ($el.tagName) {\n case 'SPAN': extraPadding += 8; break;\n case 'DIV': extraPadding += 8; break;\n case 'BUTTON': extraPadding += 32; break;\n case 'SELECT': extraPadding += 32; break;\n case 'INPUT':\n switch (($el.type || 'text').toLowerCase()) {\n // 1. 체크박스 / 라디오 (비교적 좁은 영역)\n case 'checkbox':\n case 'radio':\n extraPadding += 12;\n break;\n\n // 2. 버튼 계열 input\n case 'button':\n case 'submit':\n case 'reset':\n case 'image':\n extraPadding += 16;\n break;\n\n // 3. 특수 위젯 (컬러, 파일, 슬라이더)\n case 'color':\n case 'file':\n case 'range':\n extraPadding += 24;\n break;\n\n // 4. 화면에 안 보이는 hidden 필드\n case 'hidden':\n extraPadding += 0;\n break;\n\n // 5. 텍스트 및 숫자, 날짜 등 일반 입력 필드 (기본값)\n case 'text':\n case 'search':\n case 'tel':\n case 'url':\n case 'email':\n case 'password':\n case 'number':\n case 'date':\n case 'time':\n case 'datetime-local':\n case 'month':\n case 'week':\n default:\n extraPadding += 16;\n break;\n }\n break;\n }\n });\n\n trace.log(extraPadding);\n\n\n const fieldIdx = this.#host.fields.get().indexOf(tbodyCell.dataset.bind);\n\n const computedStyle = window.getComputedStyle(tbodyCell);\n const font = computedStyle.font || '12px sans-serif';\n\n // 헤더 텍스트 길이 측정\n const headerText = cell.innerText || \"\";\n const headerSize = nine.measureTextSize(headerText, font);\n let maxTextWidth = (headerSize.width || 0) + 16;\n\n this.#host.execute(() => {\n\n this.#sheet.view.getArray().forEach((record, idx) => {\n const val = String(tbodyCell.dataset.expr ? this.#host.exprEngine.evaluate(tbodyCell.dataset.expr, record, idx) : record.v[fieldIdx] ?? \"\").trim();\n const size = nine.measureTextSize(val, font);\n if (size.width && size.width > maxTextWidth) {\n maxTextWidth = size.width;\n }\n });\n\n // 글자 수 당 대략적인 픽셀 계산 (기본 패딩 여백 포함, 최소 32px ~ 최대 400px 제한)\n const calculatedWidth = Math.max(32, Math.min(400, Math.ceil(maxTextWidth) + extraPadding));\n\n // 자동 계산된 너비 적용\n this.setColumnWidth(tbodyCell.dataset.col, calculatedWidth, this.#getContainerType(cell));\n })\n };\n}\n\n","// ui/col/ColMover.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColMover {\n #sheet;\n #grip;\n #indi;\n\n #isDragging = false;\n #sourceCell = null;\n #sourceColIndex = null;\n #targetColIndex = null;\n #shiftX = 0;\n #timer = null;\n\n constructor(sheet) {\n this.#sheet = sheet;\n this.#grip = this.#sheet.querySelector('.ng-col-mover-grip');\n this.#indi = this.#sheet.querySelector('.ng-col-mover-indi');\n this.bindEvents();\n }\n\n bindEvents() {\n this.#sheet.addEventListener('pointerdown', this.#onPointerDown);\n }\n\n #checkIsMovable() {\n const host = this.#sheet.getRootNode()?.host;\n return this.#sheet.getAttribute('col-movable') === 'true' || host?.getAttribute('col-movable') === 'true';\n }\n\n #getDeepElementFromPoint(x, y) {\n const root = this.#sheet.getRootNode();\n let el = root.elementFromPoint ? root.elementFromPoint(x, y) : document.elementFromPoint(x, y);\n\n while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) {\n const nested = el.shadowRoot.elementFromPoint(x, y);\n if (!nested || nested === el) break;\n el = nested;\n }\n\n return el;\n }\n\n #getColGroupRange(cell) {\n if (!cell || cell.dataset.col === undefined) return null;\n\n const startCol = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const endCol = startCol + colSpan - 1;\n const rowIndex = cell.closest('tr')?.sectionRowIndex ?? 0;\n\n const table = cell.closest('table');\n if (!table) return { startCol, colSpan, endCol, rowIndex, isGroup: false, parentGroupRange: null, isValidGroup: true };\n\n const headerCells = table.querySelectorAll('thead th, thead td');\n let hasStrictChildren = false;\n let isValidGroup = true;\n let parentGroupRange = null;\n\n for (const subCell of headerCells) {\n if (subCell === cell || subCell.dataset.col === undefined) continue;\n\n const subStart = parseInt(subCell.dataset.col, 10);\n const subSpan = subCell.colSpan || 1;\n const subEnd = subStart + subSpan - 1;\n const subRowIndex = subCell.closest('tr')?.sectionRowIndex ?? 0;\n\n if (subRowIndex < rowIndex && subStart <= startCol && subEnd >= endCol && subSpan > colSpan) {\n if (!parentGroupRange) {\n parentGroupRange = { startCol: subStart, endCol: subEnd };\n } else {\n parentGroupRange.startCol = Math.max(parentGroupRange.startCol, subStart);\n parentGroupRange.endCol = Math.min(parentGroupRange.endCol, subEnd);\n }\n }\n\n const isOverlap = !(subEnd < startCol || subStart > endCol);\n if (isOverlap) {\n const isFullyContained = (subStart >= startCol && subEnd <= endCol);\n\n if (isFullyContained) {\n if (subSpan < colSpan) {\n hasStrictChildren = true;\n }\n } else if (subStart < startCol || subEnd > endCol) {\n if (!(subStart <= startCol && subEnd >= endCol)) {\n isValidGroup = false;\n }\n }\n }\n }\n\n const isRealGroup = hasStrictChildren && isValidGroup;\n\n return {\n startCol,\n colSpan: isRealGroup ? colSpan : 1,\n endCol: isRealGroup ? endCol : startCol,\n rowIndex,\n isGroup: isRealGroup,\n parentGroupRange,\n isValidGroup\n };\n }\n\n #createGroupHeaderPreview(cell) {\n const groupRange = this.#getColGroupRange(cell);\n if (!groupRange) return null;\n\n const { startCol, endCol, isGroup } = groupRange;\n\n // 핵심: 테이블이 여러 개인 구조이므로 cell이 속한 바로 그 테이블을 직접 가져옵니다.\n const origTable = cell.closest('table');\n if (!origTable) return null;\n\n let minLeft = Infinity, maxRight = -Infinity, minTop = Infinity, maxBottom = -Infinity;\n const targetCells = [];\n\n origTable.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n const isTarget = isGroup\n ? (cCol >= startCol && cEnd <= endCol)\n : (c === cell);\n\n if (isTarget) {\n const rect = c.getBoundingClientRect();\n minLeft = Math.min(minLeft, rect.left);\n maxRight = Math.max(maxRight, rect.right);\n minTop = Math.min(minTop, rect.top);\n maxBottom = Math.max(maxBottom, rect.bottom);\n\n const computedStyle = window.getComputedStyle(c);\n targetCells.push({ el: c, rect, style: computedStyle });\n }\n });\n\n if (targetCells.length === 0) return null;\n\n const groupWidth = maxRight - minLeft;\n const groupHeight = maxBottom - minTop;\n\n const headerContent = document.createElement('div');\n headerContent.className = 'grip-header-content';\n headerContent.style.position = 'relative';\n headerContent.style.width = `${groupWidth}px`;\n headerContent.style.height = `${groupHeight}px`;\n\n targetCells.forEach(({ el, rect, style }) => {\n const clonedCell = el.cloneNode(true);\n\n clonedCell.style.position = 'absolute';\n clonedCell.style.left = `${rect.left - minLeft}px`;\n clonedCell.style.top = `${rect.top - minTop}px`;\n\n clonedCell.style.width = `${rect.width}px`;\n clonedCell.style.minWidth = `${rect.width}px`;\n clonedCell.style.maxWidth = 'none';\n\n clonedCell.style.height = `${rect.height}px`;\n clonedCell.style.boxSizing = 'border-box';\n clonedCell.style.margin = '0';\n\n clonedCell.style.backgroundColor = style.backgroundColor !== 'transparent' && style.backgroundColor !== 'rgba(0, 0, 0, 0)'\n ? style.backgroundColor\n : '#f9fafb';\n clonedCell.style.color = style.color;\n clonedCell.style.font = style.font;\n clonedCell.style.fontWeight = style.fontWeight;\n clonedCell.style.fontSize = style.fontSize;\n clonedCell.style.textAlign = style.textAlign;\n clonedCell.style.padding = style.padding;\n clonedCell.style.border = style.border;\n clonedCell.style.borderRight = style.borderRight;\n clonedCell.style.borderBottom = style.borderBottom;\n clonedCell.style.display = 'flex';\n clonedCell.style.alignItems = 'center';\n clonedCell.style.justifyContent = style.textAlign === 'center' ? 'center' : (style.textAlign === 'right' ? 'flex-end' : 'flex-start');\n\n headerContent.appendChild(clonedCell);\n });\n\n return {\n element: headerContent,\n bounds: {\n left: minLeft,\n right: maxRight,\n top: minTop,\n bottom: maxBottom,\n width: groupWidth,\n height: groupHeight\n }\n };\n }\n\n #onPointerDown = (e) => {\n if (!this.#checkIsMovable()) return;\n\n const headerPart = e.target.closest('.ng-sheet-header');\n if (!headerPart) return;\n\n const cell = e.target.closest('th, td');\n if (!cell || cell.classList.contains('resizable-edge') || ['INPUT', 'BUTTON'].includes(e.target.tagName)) return;\n if (cell.dataset.col === undefined) return;\n\n e.preventDefault();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cancelTimer = () => {\n if (this.#timer) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n window.removeEventListener('pointermove', onPointerMovePending);\n window.removeEventListener('pointerup', cancelTimer);\n window.removeEventListener('pointercancel', cancelTimer);\n };\n\n const onPointerMovePending = (moveEvent) => {\n const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);\n if (dist > 5) {\n cancelTimer();\n }\n };\n\n this.#timer = setTimeout(() => {\n cancelTimer();\n this.#startDrag(e, cell);\n }, 500);\n\n window.addEventListener('pointermove', onPointerMovePending);\n window.addEventListener('pointerup', cancelTimer, { once: true });\n window.addEventListener('pointercancel', cancelTimer, { once: true });\n };\n\n #startDrag(e, cell) {\n if (this.#isDragging) return;\n\n const preview = this.#createGroupHeaderPreview(cell);\n if (!preview) return;\n\n this.#isDragging = true;\n this.#sourceCell = cell;\n this.#sourceColIndex = parseInt(cell.dataset.col, 10);\n\n const sheetRect = this.#sheet.getBoundingClientRect();\n const { bounds, element } = preview;\n\n this.#shiftX = e.clientX - bounds.left;\n\n if (this.#grip) {\n this.#grip.replaceChildren(element);\n\n const relativeTop = bounds.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#grip.style.width = `${bounds.width}px`;\n this.#grip.style.height = `${fullHeight}px`;\n this.#grip.style.top = `${relativeTop}px`;\n this.#grip.style.display = 'block';\n\n this.#updateGripPosition(e.clientX);\n }\n\n document.body.style.cursor = 'move';\n\n window.addEventListener('pointermove', this.#onPointerMove);\n window.addEventListener('pointerup', this.#onPointerUp, { once: true });\n }\n\n #onPointerMove = (e) => {\n if (!this.#isDragging) return;\n\n this.#updateGripPosition(e.clientX);\n\n if (this.#grip) this.#grip.style.pointerEvents = 'none';\n if (this.#indi) this.#indi.style.pointerEvents = 'none';\n\n const targetElement = this.#getDeepElementFromPoint(e.clientX, e.clientY);\n const targetCell = targetElement?.closest('.ng-sheet-header th, .ng-sheet-header td');\n\n if (targetCell && targetCell.dataset.col !== undefined) {\n const targetColIndex = parseInt(targetCell.dataset.col, 10);\n const sheetRect = this.#sheet.getBoundingClientRect();\n const table = targetCell.closest('table');\n\n let colMinLeft = Infinity;\n let colMaxRight = -Infinity;\n\n if (table) {\n table.querySelectorAll('thead th, thead td').forEach(c => {\n if (c.dataset.col === undefined) return;\n const cCol = parseInt(c.dataset.col, 10);\n const cSpan = c.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n\n if (cCol <= targetColIndex && cEnd >= targetColIndex) {\n const cRect = c.getBoundingClientRect();\n colMinLeft = Math.min(colMinLeft, cRect.left);\n colMaxRight = Math.max(colMaxRight, cRect.right);\n }\n });\n }\n\n if (colMinLeft === Infinity) {\n const rect = targetCell.getBoundingClientRect();\n colMinLeft = rect.left;\n colMaxRight = rect.right;\n }\n\n const midX = colMinLeft + ((colMaxRight - colMinLeft) / 2);\n let calculatedTargetCol = 0;\n let indicatorLeft = 0;\n\n if (e.clientX < midX) {\n calculatedTargetCol = targetColIndex;\n indicatorLeft = colMinLeft - sheetRect.left;\n } else {\n const colSpan = targetCell.colSpan || 1;\n calculatedTargetCol = targetColIndex + colSpan;\n indicatorLeft = colMaxRight - sheetRect.left;\n }\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n const movingSpan = sourceGroup.colSpan;\n\n const sourceRowStart = sourceGroup.rowIndex;\n const sourceRowSpan = this.#sourceCell.rowSpan || 1;\n const sourceRowEnd = sourceRowStart + sourceRowSpan - 1;\n\n const targetRowStart = targetCell.closest('tr')?.sectionRowIndex ?? 0;\n const targetRowSpan = targetCell.rowSpan || 1;\n const targetRowEnd = targetRowStart + targetRowSpan - 1;\n\n const isRowSpanCompatible = !(sourceRowEnd < targetRowStart || sourceRowStart > targetRowEnd);\n\n let isOutOfBoundsOfParent = false;\n if (sourceGroup.parentGroupRange) {\n const { startCol: pStart, endCol: pEnd } = sourceGroup.parentGroupRange;\n if (calculatedTargetCol < pStart || (calculatedTargetCol + movingSpan - 1) > pEnd) {\n isOutOfBoundsOfParent = true;\n }\n }\n\n let isDroppingInsideOtherGroup = false;\n if (table) {\n const spannedCells = table.querySelectorAll('thead th[colspan], thead td[colspan]');\n\n for (const sCell of spannedCells) {\n if (sCell === this.#sourceCell) continue;\n\n const sRowStart = sCell.closest('tr')?.sectionRowIndex ?? 0;\n const sRowSpan = sCell.rowSpan || 1;\n const sRowEnd = sRowStart + sRowSpan - 1;\n\n const isVerticalOverlap = !(sourceRowEnd < sRowStart || sourceRowStart > sRowEnd);\n if (!isVerticalOverlap) continue;\n\n const sStart = parseInt(sCell.dataset.col, 10);\n const sSpan = sCell.colSpan || 1;\n const sEnd = sStart + sSpan - 1;\n\n if (calculatedTargetCol > sStart && calculatedTargetCol < sEnd + 1) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n\n const moveEndCol = calculatedTargetCol + movingSpan - 1;\n const isCrossIntersecting = (\n (calculatedTargetCol > sStart && calculatedTargetCol <= sEnd && moveEndCol > sEnd) ||\n (calculatedTargetCol < sStart && moveEndCol >= sStart && moveEndCol < sEnd)\n );\n\n if (isCrossIntersecting) {\n isDroppingInsideOtherGroup = true;\n break;\n }\n }\n }\n\n const isSelfGroup = (\n calculatedTargetCol >= sourceGroup.startCol &&\n calculatedTargetCol <= sourceGroup.endCol + 1\n );\n\n const isInvalidMove = !isRowSpanCompatible || isSelfGroup || isOutOfBoundsOfParent || isDroppingInsideOtherGroup || !sourceGroup.isValidGroup;\n\n if (isInvalidMove) {\n this.#targetColIndex = null;\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n } else {\n this.#targetColIndex = calculatedTargetCol;\n if (this.#grip) this.#grip.classList.remove('invalid');\n\n if (this.#indi) {\n const headerPart = targetCell.closest('.ng-sheet-header');\n const headerRect = headerPart.getBoundingClientRect();\n const relativeTop = headerRect.top - sheetRect.top;\n const fullHeight = sheetRect.height - relativeTop;\n\n this.#indi.style.top = `${relativeTop}px`;\n this.#indi.style.height = `${fullHeight}px`;\n this.#indi.style.left = `${indicatorLeft - 1}px`;\n this.#indi.style.display = 'block';\n }\n }\n } else {\n if (this.#indi) this.#indi.style.display = 'none';\n if (this.#grip) this.#grip.classList.add('invalid');\n this.#targetColIndex = null;\n }\n };\n\n #updateGripPosition(clientX) {\n if (!this.#grip) return;\n const sheetRect = this.#sheet.getBoundingClientRect();\n const left = clientX - sheetRect.left - this.#shiftX;\n this.#grip.style.left = `${left}px`;\n }\n\n #onPointerUp = (e) => {\n if (!this.#isDragging) return;\n\n window.removeEventListener('pointermove', this.#onPointerMove);\n document.body.style.cursor = '';\n\n if (this.#grip) {\n this.#grip.style.display = 'none';\n this.#grip.replaceChildren();\n }\n if (this.#indi) this.#indi.style.display = 'none';\n\n if (\n this.#targetColIndex !== null &&\n this.#sourceColIndex !== null &&\n this.#targetColIndex !== this.#sourceColIndex &&\n this.#targetColIndex !== this.#sourceColIndex + 1\n ) {\n this.moveColumn(this.#sourceColIndex, this.#targetColIndex);\n }\n\n this.#isDragging = false;\n this.#sourceCell = null;\n this.#sourceColIndex = null;\n this.#targetColIndex = null;\n };\n\n moveColumn(fromColIndex, toColIndex) {\n\n trace.log(this.#sheet.sourceTable.cloneNode(true));\n\n const colgroup = this.#sheet.sourceTable.querySelector('colgroup');\n const targetCol = colgroup.querySelector(`col[data-col=\"${toColIndex}\"]`);\n\n const sourceGroup = this.#getColGroupRange(this.#sourceCell);\n if (!sourceGroup || !sourceGroup.isValidGroup) return;\n\n const spanCount = sourceGroup.colSpan;\n const isInRange = (idx) => idx >= fromColIndex && idx < fromColIndex + spanCount;\n\n // 1. colgroup 내 <col> 이동 및 fixed 설정\n const targetViewportCol = this.#sheet.querySelector(`.ng-sheet-body-content col[data-col=\"${toColIndex}\"]`);\n const fixedType = targetViewportCol?.closest('.ng-container-left') ? 'left' : targetViewportCol?.closest('.ng-container-right') ? 'right' : null;\n\n colgroup.querySelectorAll('col').forEach(col => {\n if (isInRange(parseInt(col.getAttribute('data-col'), 10))) {\n fixedType ? col.setAttribute('fixed', fixedType) : col.removeAttribute('fixed');\n colgroup.insertBefore(col, targetCol);\n }\n });\n\n // 2. 테이블 행(tr) 내부의 셀(th, td) 순서 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n this.#sheet.sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n const cells = Array.from(tr.children);\n const targetRowCell = cells.find(c => parseInt(c.dataset.col, 10) >= toColIndex);\n\n cells.forEach(cell => {\n if (isInRange(parseInt(cell.dataset.col, 10))) {\n tr.insertBefore(cell, targetRowCell || null);\n }\n });\n });\n });\n\n this.#sheet.recompileAndRefresh();\n }\n\n destroy() {\n this.#sheet.removeEventListener('pointerdown', this.#onPointerDown);\n }\n}","// ui/col/ColFixManager.js\nimport { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColFixManager {\n #sheet;\n\n constructor(sheet) {\n this.#sheet = sheet;\n }\n\n /**\n * 🎯 현재 클릭된 셀의 고정 구역('left', 'right', 'none') 탐색\n */\n getFixState(targetCell, table) {\n if (!targetCell || !table) return 'none';\n\n // 🎯 [보정] 3분할 레이어 구조 내부의 컨테이너를 안전하게 탐색\n const container = targetCell.closest('.ng-container-left, .ng-container-right, .ng-container-body');\n if (container?.classList.contains('ng-container-left')) return 'left';\n if (container?.classList.contains('ng-container-right')) return 'right';\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n if (!isNaN(baseCol)) {\n const colEl = table.querySelector(`colgroup col[data-col=\"${baseCol}\"]`);\n const fixedAttr = colEl?.getAttribute('fixed');\n if (fixedAttr) return fixedAttr;\n }\n\n return 'none';\n }\n\n /**\n * 🎯 상하 멀티 헤더 경계선 일치 여부 검사 (Fix Column 가부 판별)\n */\n canFixColumn(targetCell, table) {\n if (!targetCell || targetCell.tagName !== 'TH' || !table) return false;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n if (isNaN(baseCol)) return false;\n\n const targetBoundaryCol = baseCol + colSpan - 1;\n const theadTrs = Array.from(table.querySelectorAll('thead tr'));\n\n if (theadTrs.length <= 1) return true;\n\n for (const tr of theadTrs) {\n const cells = Array.from(tr.querySelectorAll('th, td'));\n let cellBoundaryFound = false;\n\n for (const cell of cells) {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEndCol = cCol + cSpan - 1;\n\n // 목표 경계선이 특정 셀의 중간을 관통하는 경우 (Fix 불가능)\n if (cCol <= targetBoundaryCol && targetBoundaryCol < cEndCol) {\n return false;\n }\n\n if (cEndCol === targetBoundaryCol) {\n cellBoundaryFound = true;\n break;\n }\n }\n\n if (!cellBoundaryFound) return false;\n }\n\n return true;\n }\n\n /**\n * 🎯 [인스턴스 메서드] 배치 범위 고정 및 해제 처리\n * - 원본(`sourceTable`)의 구조(fixed 속성)를 직접 조작하므로 decompile은 절대 호출하지 않음!\n */\n executeFixToggle(action, targetCell, fixType = 'left') {\n if (!this.#sheet || !targetCell) return;\n\n const sourceTable = this.#sheet.sourceTable;\n if (!sourceTable) return;\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n const colSpan = targetCell.colSpan || 1;\n const targetColIndex = baseCol + colSpan - 1;\n\n if (isNaN(targetColIndex)) return;\n\n const colgroup = sourceTable.querySelector('colgroup');\n if (!colgroup) return;\n\n const cols = Array.from(colgroup.querySelectorAll('col'));\n\n if (action === 'fix-column') {\n // 🎯 Batch Fix: 0번부터 targetColIndex까지의 모든 <col>과 셀에 fixed 속성 일괄 부여\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx <= targetColIndex) {\n col.setAttribute('fixed', fixType);\n }\n });\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (!isNaN(cIdx) && cIdx <= targetColIndex) {\n cell.setAttribute('fixed', fixType);\n }\n });\n });\n });\n\n } else if (action === 'unfix-column') {\n let minBaseCol = baseCol;\n let maxEndCol = baseCol + colSpan - 1;\n\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach((tr, rIdx) => {\n Array.from(tr.children).forEach(cell => {\n const cCol = parseInt(cell.dataset.col, 10);\n const cSpan = cell.colSpan || 1;\n const cEnd = cCol + cSpan - 1;\n const rSpan = cell.rowSpan || 1;\n const trIndex = tr.sectionRowIndex ?? rIdx;\n\n // 현재 클릭된 셀의 수직 범위와 겹치는 머지 셀이 있는지 검사\n const isVerticalOverlap = !(trIndex + rSpan - 1 < cell.closest('tr').sectionRowIndex || trIndex > (cell.closest('tr').sectionRowIndex + rSpan - 1));\n\n // 만약 기존에 고정(fixed)되어 있으면서 현재 클릭한 타겟 라인과 걸쳐있는 머지 셀이라면 범위를 확장합니다.\n const isHorizontalOverlap = !(cEnd < baseCol || cCol > targetColIndex);\n\n if (isHorizontalOverlap) {\n minBaseCol = Math.min(minBaseCol, cCol);\n maxEndCol = Math.max(maxEndCol, cEnd);\n }\n });\n });\n });\n\n // 🎯 2단계: 계산된 실제 머지 블록의 시작점(minBaseCol) 이상인 모든 <col> 속성 해제\n cols.forEach(col => {\n const idx = parseInt(col.getAttribute('data-col'), 10);\n if (idx >= minBaseCol) {\n col.removeAttribute('fixed');\n }\n });\n\n // 🎯 3단계: left 구역의 고정 연속성(체인) 검증\n let isBroken = false;\n cols.forEach(col => {\n if (isBroken) {\n col.removeAttribute('fixed');\n } else if (!col.getAttribute('fixed')) {\n isBroken = true;\n }\n });\n\n // 🎯 4단계: <col>들의 최종 fixed 상태를 기준으로 모든 thead, tbody, tfoot 셀(th, td)의 fixed 속성 완벽 동기화\n ['thead', 'tbody', 'tfoot'].forEach(group => {\n sourceTable.querySelectorAll(`${group} tr`).forEach(tr => {\n Array.from(tr.children).forEach(cell => {\n const cIdx = parseInt(cell.dataset.col, 10);\n if (isNaN(cIdx)) return;\n\n const correspondingCol = cols.find(c => parseInt(c.getAttribute('data-col'), 10) === cIdx);\n const isColFixed = correspondingCol?.getAttribute('fixed');\n\n if (isColFixed) {\n cell.setAttribute('fixed', isColFixed);\n } else {\n cell.removeAttribute('fixed');\n }\n });\n });\n });\n }\n\n trace.log(this.#sheet.sourceTable);\n\n // 🎯 recompileAndRefresh 단 1회 호출로 원본 정렬 및 뷰포트 재생성 완결\n this.#sheet.recompileAndRefresh?.();\n }\n}","import { NINE_TABLE } from '@/core/constants.js';\r\nimport { trace } from \"@nopeer\";\r\n\r\n/**\r\n * 🎯 [필터 패널 커스텀 엘리먼트 Light DOM 버전]\r\n */\r\nexport class NineTableFilterPanel extends HTMLElement {\r\n\t#sheet;\r\n\t#host;\r\n\t#nineTable;\r\n\t#view;\r\n\t#button;\r\n\tcurrentCol = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#init();\r\n\t\tdocument.addEventListener(\"mousedown\", this.#closeHandler);\r\n\t}\r\n\r\n\t#init = () => {\r\n\t\t//setTimeout(() => {\r\n\t\t\tthis.#renderer();\r\n\r\n\t\t\tthis.#sheet = this.closest(\"nine-table-sheet\");\r\n\t\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\t\tthis.#nineTable = this.querySelector(\"nine-table-simple\");\r\n\t\t\ttrace.log(\"1***********************\", this.#nineTable);\r\n\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tthis.#view = this.#nineTable.shadowRoot.querySelector(\"nine-table-sheet\");\r\n\t\t\t\ttrace.log(\"2***********************\", this.#view);\r\n\t\t\t})\r\n\r\n\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"focusin\", (e) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t});\r\n\t\t\tthis.querySelector(\".search-box\").addEventListener(\"input\", this.#onInput);\r\n\t\t\tthis.querySelector(\"#chkSelectAll\").addEventListener(\"change\", this.#onSelectAll);\r\n\t\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\r\n\t\t//});\r\n\t}\r\n\r\n\t#renderer = () => {\r\n\t\tthis.innerHTML = `\r\n <style>\r\n nine-table-filter-panel nine-table-simple {\r\n width: 100%;\r\n flex: 1;\r\n border: none;\r\n }\r\n nine-table-filter-panel.active {\r\n display: flex;\r\n }\r\n nine-table-filter-panel .search-box {\r\n width: 100%;\r\n height: 28px;\r\n box-sizing: border-box;\r\n padding: 0px 8px;\r\n border: none;\r\n border-bottom: 1px solid #e5e7eb;\r\n border-radius: 0px;\r\n outline: none;\r\n font-size: 12px;\r\n background: #fafafa;\r\n color: #333;\r\n }\r\n nine-table-filter-panel .search-box:focus {\r\n background: #ffffff;\r\n }\r\n nine-table-filter-panel .footer-section {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 4px 6px;\r\n gap: 8px;\r\n border-top: 1px solid #e5e7eb;\r\n background: #f9fafb;\r\n flex-shrink: 0;\r\n }\r\n nine-table-filter-panel .footer-btns {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 6px;\r\n }\r\n nine-table-filter-panel .footer-btns label {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n nine-table-filter-panel .btn-group {\r\n display: flex;\r\n gap: 4px;\r\n }\r\n nine-table-filter-panel button {\r\n padding: 4px 14px;\r\n border-radius: 4px;\r\n border: 1px solid #d1d5db;\r\n background: #ffffff;\r\n cursor: pointer;\r\n font-size: 11px;\r\n }\r\n nine-table-filter-panel button:hover {\r\n background: #f3f4f6;\r\n }\r\n nine-table-filter-panel button#btnOk {\r\n background: #2563eb;\r\n color: white;\r\n border: none;\r\n }\r\n </style>\r\n\r\n <input type=\"text\" class=\"search-box\" placeholder=\"Search...\">\r\n \r\n <nine-table-simple class=\"filter-list\" theme=\"simple\">\r\n <table auto-fit-col=\"true\">\r\n <colgroup>\r\n <col width=\"32\" fixed=\"left\" />\r\n <col width=\"180\" />\r\n <col width=\"0\" fixed=\"right\"/>\r\n </colgroup>\r\n <tbody>\r\n <tr>\r\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\r\n <td data-bind=\"DATA2\" html=\"true\"></td>\r\n <td data-bind=\"DATA\"></td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </nine-table-simple>\r\n\r\n <div class=\"footer-section\">\r\n <div class=\"footer-btns\">\r\n <label><input type=\"checkbox\" id=\"chkSelectAll\" checked> Select All</label>\r\n <div class=\"btn-group\">\r\n <button id=\"btnOk\">Apply</button>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n\t}\r\n\r\n\topen(filterBtn) {\r\n\t\tthis.#button = filterBtn;\r\n\r\n\t\tconst cell = filterBtn.closest(\"th, td\");\r\n\t\tthis.currentCol = cell?.dataset.col;\r\n\r\n\t\tconst cellRect = cell.getBoundingClientRect();\r\n\t\tconst sheetRect = this.#sheet.getBoundingClientRect();\r\n\r\n\t\tconst panelWidth = this.offsetWidth || 240;\r\n\t\tlet left = (cellRect.right - sheetRect.left) - panelWidth;\r\n\t\tlet top = cellRect.bottom - sheetRect.top;\r\n\r\n\t\tif (left < 0) {\r\n\t\t\tleft = Math.max(0, cellRect.left - sheetRect.left);\r\n\t\t}\r\n\r\n\t\tthis.style.left = `${left}px`;\r\n\t\tthis.style.top = `${top}px`;\r\n\r\n\t\tconst searchBox = this.querySelector(\".search-box\");\r\n\t\tsearchBox.value = \"\";\r\n\r\n\t\tthis.classList.add(\"active\");\r\n\t\tthis.classList.add(\"loading\");\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tthis.#loadVirtualFilterItems();\r\n\t\t\t\tthis.#view.rowManager.scrollToDataRow(0);\r\n\t\t\t} finally {\r\n\t\t\t\tthis.classList.remove(\"loading\");\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t#closeHandler = (e) => {\r\n\t\tconst path = e.composedPath ? e.composedPath() : [];\r\n\t\tif (path.includes(this) || (this.#button && path.includes(this.#button))) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tthis.close();\r\n\t};\r\n\r\n\tclose() {\r\n\t\tthis.currentCol = null;\r\n\t\tthis.classList.remove(\"active\");\r\n\t\tthis.#button = null;\r\n\t}\r\n\r\n\t#loadVirtualFilterItems() {\r\n\t\tconst filteredRecords = this.#host.data.getArray();\r\n\t\tconst targetCols = this.#button?.columns || []; // [{ bind, expr }] 형태 배열\r\n\t\tconst fields = this.#host.fields.get() || [];\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst ds = targetCols.flatMap((colInfo) => {\r\n\t\t\tconst bindKey = colInfo.bind;\r\n\t\t\tconst exprKey = colInfo.expr;\r\n\r\n\t\t\tconst filterKey = bindKey || exprKey; // 실제 필터 파라미터 키로 사용\r\n\t\t\tconst fieldIdx = bindKey ? fields.indexOf(bindKey) : -1;\r\n\t\t\tconst activeSelectedVals = activeFilters[filterKey] || [];\r\n\r\n\t\t\t// 1. Map을 이용한 O(N) 고속 유니크 추출 (DATA는 bind/원시값, DATA2는 expr 연산 결과)\r\n\t\t\tconst uniqueMap = new Map();\r\n\t\t\tfor (let i = 0; i < filteredRecords.length; i++) {\r\n\t\t\t\tconst record = filteredRecords[i];\r\n\t\t\t\tif (!record) continue;\r\n\r\n\t\t\t\t// DATA 기준이 될 원시 값 (bind가 있으면 필드 인덱스에서, 없으면 expr 결과)\r\n\t\t\t\tlet rawVal = undefined;\r\n\t\t\t\tif (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\trawVal = record.v[fieldIdx];\r\n\t\t\t\t} else if (bindKey && bindKey.includes(\"data.\")) {\r\n\t\t\t\t\trawVal = exprEngine ? exprEngine.evaluate(bindKey, record, i) : undefined;\r\n\t\t\t\t} else if (exprKey && exprEngine) {\r\n\t\t\t\t\trawVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// DATA2에 출력될 화면 표시 값 (expr 수식 연산 결과, 없으면 rawVal)\r\n\t\t\t\tlet displayVal = rawVal;\r\n\t\t\t\tif (exprKey && exprEngine) {\r\n\t\t\t\t\tdisplayVal = exprEngine.evaluate(exprKey, record, i);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (displayVal !== undefined && displayVal !== null && !uniqueMap.has(displayVal)) {\r\n\t\t\t\t\tuniqueMap.set(displayVal, {\r\n\t\t\t\t\t\tv: rawVal, // 💡 필터링 비교 기준 (DATA)\r\n\t\t\t\t\t\tv2: displayVal // 💡 화면 출력 기준 (DATA2)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tconst uniqueList = [...uniqueMap.values()];\r\n\r\n\t\t\t// 2. 출력값(v2) 기준 정렬\r\n\t\t\tuniqueList.sort((a, b) => String(a.v2 || \"\").localeCompare(String(b.v2 || \"\")));\r\n\t\t\tactiveSelectedVals.sort((a, b) => { return a > b ? 1 : -1; });\r\n\r\n\t\t\treturn uniqueList.map(o => ({\r\n\t\t\t\tLVL: 2,\r\n\t\t\t\tDATA: o.v, // 필터링 비교용 값\r\n\t\t\t\tDATA2: (o.v2 === \"\" || o.v2 === null || o.v2 === undefined) ? '<span class=\"empty-value\">(empty)</span>' : o.v2, // 화면 출력용 값\r\n\t\t\t\tCOLNM: filterKey,\r\n\t\t\t\tCHK: activeSelectedVals.length === 0 || activeSelectedVals.nineBinarySearch(o.v || \"\") >= 0 ? \"Y\" : \"N\"\r\n\t\t\t}));\r\n\t\t});\r\n\r\n\t\tthis.#nineTable.data.set(ds);\r\n\r\n\t\tconst selectAllChk = this.querySelector(\"#chkSelectAll\");\r\n\t\tif (selectAllChk) {\r\n\t\t\tselectAllChk.checked = ds.length > 0 && ds.every(item => item.CHK === \"Y\");\r\n\t\t}\r\n\t}\r\n\r\n\t#onOk = () => {\r\n\t\tthis.#host.loading = true;\r\n\r\n\t\tconst filterRecords = this.#view.view.getArray();\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\r\n\t\tconst checkedRecords = filterRecords.filter(record => {\r\n\t\t\tconst chk = record.v[fields.indexOf(\"CHK\")];\r\n\t\t\treturn (chk === \"Y\" || chk === true);\r\n\t\t});\r\n\r\n\t\tconst filterParams = { ...(this.#sheet.filtering?.filters || {}) };\r\n\r\n\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\tconst fieldIdx = colInfo.expr ? fields.indexOf(\"DATA2\") : fields.indexOf(\"DATA\");\r\n\t\t\tconst selectedVals = checkedRecords.map(r => r.v[fieldIdx]);\r\n\r\n\t\t\tif (selectedVals.length > 0) {\r\n\t\t\t\tfilterParams[filterKey] = selectedVals;\r\n\t\t\t} else {\r\n\t\t\t\tdelete filterParams[filterKey];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tconst totalCount = this.#nineTable.data.count();\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\ttry {\r\n\t\t\t\tif (totalCount === checkedRecords.length) {\r\n\t\t\t\t\tthis.#button.columns.forEach(colInfo => {\r\n\t\t\t\t\t\tconst filterKey = colInfo.expr || colInfo.bind;\r\n\t\t\t\t\t\tif (filterKey) this.#sheet.filtering.clear(filterKey);\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#sheet.filtering.set(filterParams);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\t\t\tbtn.updateFilteredState();\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.#sheet.invalidate();\r\n\t\t\t\tthis.close();\r\n\t\t\t} finally {\r\n\t\t\t\tthis.#host.loading = false;\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\t#onInput = (e) => {\r\n\r\n\t\tconst query = e.target.value.toLowerCase().trim();\r\n\r\n\t\tif (!query) {\r\n\t\t\tthis.#view.filtering.clear();\r\n\t\t} else {\r\n\t\t\tconst rawRecords = this.#nineTable.data.getArray();\r\n\t\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\t\tconst data2Idx = fields.indexOf(\"DATA2\");\r\n\r\n\t\t\tconst matchedValues = [];\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tconst val = data2Idx >= 0 && record.v ? record.v[data2Idx] : \"\";\r\n\t\t\t\tconst textVal = String(val).replace(/<[^>]*>?/gm, '').toLowerCase();\r\n\r\n\t\t\t\t// 💡 expr 연산 결과가 담긴 DATA2 텍스트와 검색어 비교\r\n\t\t\t\tif (textVal.includes(query)) {\r\n\t\t\t\t\tmatchedValues.push(val);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\ttrace.log(matchedValues);\r\n\r\n\t\t\tthis.#view.filtering.set({\r\n\t\t\t\tDATA2: [...new Set(matchedValues)]\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\r\n\t#onSelectAll = (e) => {\r\n\t\tconst isChecked = e.target.checked;\r\n\t\tconst rawRecords = this.#nineTable?.data?.getArray() || [];\r\n\t\tconst fields = this.#nineTable.data.getHostFields();\r\n\t\tconst chkIdx = fields.indexOf(\"CHK\");\r\n\r\n\t\tif (chkIdx >= 0) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\trecord.v[chkIdx] = isChecked ? \"Y\" : \"N\";\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#nineTable.refresh();\r\n\t};\r\n\r\n\t#onCancel = () => {\r\n\t\tthis.close();\r\n\t};\r\n}\r\n\r\nexport class NineTableFilterButton extends HTMLElement {\r\n\t#sheet;\r\n\t#columns = null;\r\n\r\n\tconnectedCallback() {\r\n\t\tthis.#sheet = this.closest(\"nine-table-sheet\") || this.getRootNode().host;\r\n\t\tthis.removeEventListener(\"click\", this.#onClick);\r\n\t\tthis.addEventListener(\"click\", this.#onClick);\r\n\t}\r\n\r\n\tget columns() {\r\n\t\tif (this.#columns) return this.#columns;\r\n\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst colIndex = cell?.dataset.col;\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\r\n\t\tconst cols = [];\r\n\t\tconst seen = new Set();\r\n\r\n\t\tif (sourceTable && colIndex !== undefined) {\r\n\t\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\t\tconst bindKey = $td.dataset.bind;\r\n\t\t\t\tconst exprKey = $td.dataset.expr;\r\n\r\n\t\t\t\tif (bindKey || exprKey) {\r\n\t\t\t\t\tconst uniqueKey = `${bindKey || ''}_${exprKey || ''}`;\r\n\t\t\t\t\tif (!seen.has(uniqueKey)) {\r\n\t\t\t\t\t\tseen.add(uniqueKey);\r\n\t\t\t\t\t\tcols.push({\r\n\t\t\t\t\t\t\tbind: bindKey,\r\n\t\t\t\t\t\t\texpr: exprKey,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tthis.#columns = cols;\r\n\t\treturn this.#columns;\r\n\t}\r\n\r\n\tupdateFilteredState = () => {\r\n\t\tconst activeFilters = this.#sheet.filtering?.filters || {};\r\n\t\tconst isFiltered = this.columns.some(colInfo => {\r\n\t\t\tconst key = colInfo.expr || colInfo.bind;\r\n\t\t\treturn key && activeFilters[key] && activeFilters[key].length > 0;\r\n\t\t});\r\n\t\tthis.classList.toggle('filtered', isFiltered);\r\n\t};\r\n\r\n\t#onClick = (e) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tconst panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tconst cell = this.closest(\"th, td\");\r\n\t\tconst col = cell?.dataset.col;\r\n\r\n\t\tif (panel && panel.currentCol === col && panel.classList.contains('active')) {\r\n\t\t\tpanel.close();\r\n\t\t} else if (panel) {\r\n\t\t\tpanel.open(this);\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class Filtering {\r\n\t#sheet;\r\n\t#host;\r\n\t#isFiltering = false;\r\n\t#filterPanel = null;\r\n\t#filters = {};\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = this.#sheet.getRootNode().host;\r\n\t\tthis.#init();\r\n\t}\r\n\r\n\tget filters() {\r\n\t\treturn this.#filters;\r\n\t};\r\n\r\n\t#init = () => {\r\n\t\tthis.#initFilterPanel();\r\n\t}\r\n\r\n\t#initFilterPanel = () => {\r\n\t\tif (this.#host.tagName.toLowerCase() === \"nine-table-simple\") {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet panel = this.#sheet.querySelector(\"nine-table-filter-panel\");\r\n\t\tif (!panel) {\r\n\t\t\tpanel = document.createElement(\"nine-table-filter-panel\");\r\n\t\t\tthis.#sheet.appendChild(panel);\r\n\t\t}\r\n\t\tthis.#filterPanel = panel;\r\n\t}\r\n\r\n\tisFiltering() {\r\n\t\treturn this.#isFiltering;\r\n\t}\r\n\r\n\tclear = (colnm) => {\r\n\t\tif (colnm) {\r\n\t\t\tdelete this.#filters[colnm];\r\n\t\t} else {\r\n\t\t\tthis.#filters = {};\r\n\t\t}\r\n\r\n\t\tthis.#isFiltering = Object.keys(this.#filters).length > 0;\r\n\t\tthis.#applyFiltering();\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"nine-table-filter-button\").forEach(btn => {\r\n\t\t\tbtn.updateFilteredState();\r\n\t\t});\r\n\r\n\t\ttrace.log(`🔄 [NineTableFiltering] Filter cleared for ${colnm || 'all'}`);\r\n\t}\r\n\r\n\tset = (oFilter) => {\r\n\r\n\t\ttrace.log(oFilter);\r\n\r\n\t\tlet jsonFilter = Array.isArray(oFilter)\r\n\t\t\t? Object.fromEntries(Object.keys(oFilter[0]).map(k => [k, [...new Set(oFilter.map(item => item[k]))]]))\r\n\t\t\t: oFilter;\r\n\r\n\t\tthis.#filters = jsonFilter;\r\n\t\tthis.#isFiltering = Object.keys(jsonFilter).length > 0;\r\n\t\tthis.#sheet.toggleAttribute(\"filtering\", this.#isFiltering);\r\n\r\n\t\tthis.#applyFiltering();\r\n\t}\r\n\r\n\t#applyFiltering() {\r\n\t\tconst hostData = this.#host.data;\r\n\t\tconst rawRecords = hostData.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields();\r\n\t\tconst sheetIndex = this.#sheet.index;\r\n\t\tconst exprEngine = this.#host.exprEngine;\r\n\r\n\t\tconst hasFilters = Object.keys(this.#filters).length > 0;\r\n\r\n\t\tif (!hasFilters) {\r\n\t\t\trawRecords.forEach(record => {\r\n\t\t\t\tif (record?.m?._?.[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\tthis.#sheet.invalidate();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 💡 필터 규칙 빌드 (targetKey가 bind인지 expr 수식인지 판별)\r\n\t\tconst filterRules = Object.entries(this.#filters).map(([targetKey, allowedValues]) => {\r\n\t\t\tconst isExpr = targetKey.includes(\"data.\") || targetKey.includes(\"host.\") || targetKey.includes(\"rowItem.v\");\r\n\t\t\treturn {\r\n\t\t\t\ttargetKey,\r\n\t\t\t\tisExpr,\r\n\t\t\t\tfieldIdx: !isExpr ? fields.indexOf(targetKey) : -1,\r\n\t\t\t\tallowedSet: new Set(allowedValues)\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\trawRecords.forEach((record, recordIdx) => {\r\n\t\t\tif (!record) return;\r\n\r\n\t\t\tif (!record.m._[NINE_TABLE.META.INDEX.FILTER]) {\r\n\t\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER] = [];\r\n\t\t\t}\r\n\r\n\t\t\tlet isPass = true;\r\n\r\n\t\t\tfor (let i = 0; i < filterRules.length; i++) {\r\n\t\t\t\tconst { targetKey, isExpr, fieldIdx, allowedSet } = filterRules[i];\r\n\t\t\t\tlet val = undefined;\r\n\r\n\t\t\t\tif (isExpr && exprEngine) {\r\n\t\t\t\t\tval = exprEngine.evaluate(targetKey, record, recordIdx);\r\n\t\t\t\t} else if (fieldIdx >= 0 && record.v) {\r\n\t\t\t\t\tval = record.v[fieldIdx];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!allowedSet.has(val)) {\r\n\t\t\t\t\tisPass = false;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\trecord.m._[NINE_TABLE.META.INDEX.FILTER][sheetIndex] = isPass;\r\n\t\t});\r\n\r\n\t\tthis.#sheet.invalidate();\r\n\t}\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-panel')) {\r\n\tcustomElements.define(\"nine-table-filter-panel\", NineTableFilterPanel);\r\n}\r\n\r\nif (!customElements.get('nine-table-filter-button')) {\r\n\tcustomElements.define(\"nine-table-filter-button\", NineTableFilterButton);\r\n}","// ui/data/Sorting.js (또는 정렬 관련 소스)\r\nimport { trace } from \"@nopeer\";\r\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\r\n\r\nexport class Sorting {\r\n\t#sheet;\r\n\t#host;\r\n\r\n\t#columns = [];\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tsetTimeout(() => {\r\n\t\t\tthis.#initEvents();\r\n\t\t}, 300);\r\n\t}\r\n\r\n\t#initEvents() {\r\n\r\n\t\tthis.#sheet.querySelectorAll(\"thead\").forEach($el => {\r\n\r\n\t\t\t$el.addEventListener('dblclick', (e) => {\r\n\r\n\t\t\t\tconst cell = e.target.closest('th, td');\r\n\t\t\t\tif (!cell || cell.classList.contains('resizable-edge')) return;\r\n\r\n\t\t\t\tif ([\"INPUT\",\"CELL-CHECKBOX\"].includes(e.target.tagName)) return;\r\n\r\n\t\t\t\t// 🎯 [수정] 줄바꿈으로 깨져있던 마이너스 연산자를 한 줄로 정상 복구\r\n\t\t\t\tif (e.offsetX <= 2 || e.offsetX >= cell.offsetWidth - 2) return;\r\n\r\n\t\t\t\tconst host = this.#sheet.getRootNode().host;\r\n\r\n\t\t\t\thost.loading = true;\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\ttry {\r\n\t\t\t\t\t\tthis.#handleSort(e, cell);\r\n\t\t\t\t\t} finally {\r\n\t\t\t\t\t\t// 🎯 3. 작업이 끝나면 무조건 로딩바 끄기\r\n\t\t\t\t\t\thost.loading = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}); // 또는 requestAnimationF\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\ttrace.log(\"🎯 [NineTableSorting] Initialized\");\r\n\t}\r\n\r\n\t#handleSort(e, cell) {\r\n\t\tconst colIndex = cell.dataset.col;\r\n\t\tconst tr = cell.closest('tr');\r\n\t\tconst subRowIndex = tr ? tr.dataset.subrow || String(tr.sectionRowIndex) : '0';\r\n\r\n\t\tif (colIndex === undefined) return;\r\n\r\n\t\tconst sourceTable = this.#sheet.sourceTable;\r\n\t\tif (!sourceTable) return;\r\n\r\n\t\tlet colName = null;\r\n\t\tlet exprVal = null; // 💡 expr 속성 수집용 변수\r\n\r\n\t\t// 1. 🎯 데이터 바인딩 키(colName) 및 expr 탐지\r\n\t\tsourceTable.querySelectorAll(`tbody [data-col=\"${colIndex}\"]`).forEach($td => {\r\n\t\t\tif ($td.dataset.bind) {\r\n\t\t\t\tcolName = $td.dataset.bind;\r\n\t\t\t}\r\n\t\t\t// 💡 셀에 선언된 expr 식 추출\r\n\t\t\tif ($td.dataset.expr) {\r\n\t\t\t\texprVal = $td.dataset.expr;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!colName && !exprVal) return;\r\n\r\n\t\tconst isAsc = cell.classList.contains('asc');\r\n\t\tconst isDesc = cell.classList.contains('desc');\r\n\r\n\t\tif (!e.ctrlKey && !e.shiftKey) {\r\n\t\t\tthis.#columns = [];\r\n\t\t}\r\n\r\n\t\tconst existingColIndex = this.#columns.findIndex(\r\n\t\t\tm => (m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName\r\n\t\t);\r\n\r\n\t\t// 정렬 규칙 추가 시 expr 속성(`expr`) 함께 저장\r\n\t\tconst ruleData = {\r\n\t\t\tcolIndex,\r\n\t\t\tsubRowIndex,\r\n\t\t\tcolname: colName || exprVal,\r\n\t\t\tcolName: colName || exprVal,\r\n\t\t\texpr: exprVal, // 💡 expr 규칙 보관\r\n\t\t\tasc: true,\r\n\t\t\t\"expr-func\": exprVal ? (record, idx) => this.#host.exprEngine(exprVal, record, idx) : null\r\n\t\t};\r\n\r\n\t\tif (!isAsc && !isDesc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = true;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: true });\r\n\t\t\t}\r\n\t\t} else if (isAsc) {\r\n\t\t\tif (existingColIndex >= 0) {\r\n\t\t\t\tthis.#columns[existingColIndex].asc = false;\r\n\t\t\t} else {\r\n\t\t\t\tthis.#columns.push({ ...ruleData, asc: false });\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tthis.#columns = this.#columns.filter(\r\n\t\t\t\tm => !((m.colIndex === colIndex && m.subRowIndex === subRowIndex) || m.colName === colName)\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tthis.#applySorting();\r\n\t}\r\n\r\n\t#applySorting() {\r\n\t\tif (!this.#sheet.view) {\r\n\t\t\tconsole.warn(\"⚠️ [NineTableSorting] Sheet view (SheetView) is not initialized.\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tthis.#sheet.view.setSorting(this.#columns);\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.invalidate();\r\n\t\t//this.#sheet.rowManager?.refresh(true);\r\n\r\n\t\ttrace.log(\"🔄 [NineTableSorting] Sorting applied via RowManager.refresh(true)\");\r\n\t}\r\n\r\n\t#syncHeaderUI() {\r\n\t\t// 기존 UI 클래스 초기화\r\n\t\tthis.#sheet.querySelectorAll('thead th, thead td').forEach(el => {\r\n\t\t\tel.classList.remove('asc', 'desc');\r\n\t\t});\r\n\r\n\t\tif (this.#columns.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 🎯 [핵심] tr[data-subrow] + [data-col] 조합으로 정밀 타겟팅\r\n\t\tthis.#columns.forEach(colRule => {\r\n\t\t\tconst { colIndex, subRowIndex, asc } = colRule;\r\n\r\n\t\t\tif (colIndex !== undefined) {\r\n\t\t\t\tlet selector = `thead [data-col=\"${colIndex}\"]`;\r\n\t\t\t\tif (subRowIndex !== undefined) {\r\n\t\t\t\t\tselector = `thead tr[data-subrow=\"${subRowIndex}\"] [data-col=\"${colIndex}\"]`;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst targetHeaderCells = this.#sheet.querySelectorAll(selector);\r\n\t\t\t\ttargetHeaderCells.forEach(cell => {\r\n\t\t\t\t\tcell.classList.add(asc ? 'asc' : 'desc');\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t//TableCompiler.decompile(this.#sheet);\r\n\t}\r\n\r\n\trestore() {\r\n\t\tthis.#columns = [];\r\n\t\tif (this.#sheet.view) {\r\n\t\t\tthis.#sheet.view.resetSorting();\r\n\t\t}\r\n\r\n\t\tthis.#syncHeaderUI();\r\n\t\tthis.#sheet.rowManager?.refresh(true);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { NINE_TABLE } from \"@/core/constants.js\";\r\nimport {Grouping} from \"@/data/Grouping.js\";\r\n\r\nexport class SheetView {\r\n\t#sheet;\r\n\t#host;\r\n\t#sortingColumns = []; // 정렬 규칙 [{ colname, asc, expr-func }]\r\n\t#filterRules = []; // 필터 규칙\r\n\t#viewIndexes = []; // 필터링 및 소팅이 반영된 유효 데이터 인덱스 버퍼\r\n\r\n\t#cachedVisibleRecords = null; // 💡 [추가] 캐싱된 유효 레코드 배열\r\n\r\n\tconstructor(sheet) {\r\n\t\tthis.#sheet = sheet;\r\n\t\tthis.#host = sheet.getRootNode().host;\r\n\r\n\t\tthis.refresh();\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [시트 뷰 전용 배열 조회] - 캐시 적용으로 성능 대폭 개선\r\n\t */\r\n\tgetArray = (at, colnm) => {\r\n\t\t// 💡 캐시가 없거나 비어있을 때만 가져옴 (보통 refresh에서 갱신됨)\r\n\t\tif (!this.#cachedVisibleRecords) {\r\n\t\t\tconst records = this.#host.data.getArray();\r\n\t\t\tthis.#cachedVisibleRecords = this.#viewIndexes.map(idx => records[idx]);\r\n\t\t}\r\n\r\n\t\tconst visibleRecords = this.#cachedVisibleRecords;\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords;\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (colnm != null) {\r\n\t\t\tconst fields = this.#host.data.getHostFields();\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn targetRecord;\r\n\t};\r\n\r\n\tget = (at, colnm) => {\r\n\t\tconst visibleRecords = this.getArray();\r\n\t\tconst fields = this.#host.data.getHostFields?.() || [];\r\n\r\n\t\tif (at === undefined || at === null) {\r\n\t\t\treturn visibleRecords.map(record => this.#convSingle(record, fields));\r\n\t\t}\r\n\r\n\t\tif (at < 0 || at >= visibleRecords.length) return null;\r\n\r\n\t\tconst targetRecord = visibleRecords[at];\r\n\t\tif (!targetRecord) return null;\r\n\r\n\t\tif (colnm != null) {\r\n\t\t\tconst idx = fields.indexOf(colnm);\r\n\t\t\treturn (idx >= 0 && targetRecord.v) ? targetRecord.v[idx] : null;\r\n\t\t}\r\n\r\n\t\treturn this.#convSingle(targetRecord, fields);\r\n\t};\r\n\r\n\t#convSingle = (o, fields) => {\r\n\t\tif (!o) return null;\r\n\t\tconst t = {};\r\n\t\tfields.forEach((colnm, i) => {\r\n\t\t\tt[colnm] = o.v ? o.v[i] : o[colnm];\r\n\t\t});\r\n\t\tif (o.m) t.m = o.m;\r\n\t\tif (o._) t._ = o._;\r\n\t\treturn t;\r\n\t};\r\n\r\n\t/**\r\n\t * 🎯 유효 데이터 또는 정렬/필터 변경 시에만 실행되는 뷰 버퍼 재계산\r\n\t */\r\n\t\t// SheetView.refresh() 내부 예시\r\n\trefresh = () => {\r\n\r\n\t\tthis.#cachedVisibleRecords = null;\r\n\r\n\t\t// 1. 필터 적용\r\n\t\tconst rawRecords = this.#host.data.getArray();\r\n\t\tlet indices = [];\r\n\t\trawRecords.forEach((record, i) => {\r\n\t\t\tif (!record) return;\r\n\t\t\tconst filterSlot = record.m?._?.[NINE_TABLE.META.INDEX.FILTER];\r\n\t\t\tif (filterSlot && filterSlot[this.#sheet.index] === false) return;\r\n\t\t\tindices.push(i);\r\n\t\t});\r\n\r\n\t\ttrace.log(indices);\r\n\r\n\t\t// 2. 정렬 적용\r\n\t\tif (this.#sortingColumns.length > 0) {\r\n\t\t\tindices = this.#applySorting(indices, rawRecords);\r\n\t\t}\r\n\r\n\t\tthis.#viewIndexes = indices;\r\n\t\tconst validRecords = indices.map(idx => rawRecords[idx]);\r\n\r\n\t\t//trace.log(this.#sheet.sourceTable);\r\n\t\t//const isGrouped = this.#sheet.sourceTable?.querySelector(\"tbody tr[grouping='true']\") ? true : false;\r\n\t\t//trace.log(\"#######\", isGrouped, this.#sheet.grouping?.columns);\r\n\t\tconst groupColumns = this.#sheet.grouping?.columns || [];\r\n\t\tif (groupColumns.length > 0) {\r\n\t\t\t//this.#sheet.grouping.apply();\r\n\t\t\tconst groupResult = Grouping.apply(validRecords, groupColumns, this.#host.data.getHostFields());\r\n\t\t\t//const groupResult = Grouping.apply(validRecords);\r\n\t\t\tthis.#cachedVisibleRecords = groupResult.renderItems; // 최종 렌더링 아이템\r\n\r\n\t\t\t//trace.log(\"2.============================\", groupColumns, this.#cachedVisibleRecords);\r\n\r\n\t\t\tthis.#sheet.grouping.setGroupMap(groupResult.groupMap); // 자식 매핑 공유\r\n\t\t} else {\r\n\t\t\tthis.#cachedVisibleRecords = validRecords;\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n\tsetSorting = (columns) => {\r\n\t\tthis.#sortingColumns = columns || [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\tgetSorting = () => {\r\n\t\treturn this.#sortingColumns;\r\n\t};\r\n\r\n\tresetSorting = () => {\r\n\t\tthis.#sortingColumns = [];\r\n\t\tthis.refresh();\r\n\t};\r\n\r\n\r\n\t#applySorting = (indices, validRecords) => {\r\n\t\ttrace.log(new Date());\r\n\r\n\t\tconst fields = typeof this.#host.data.getHostFields === 'function' ? this.#host.data.getHostFields() : [];\r\n\r\n\t\tconst rulesWithIdx = this.#sortingColumns.map(rule => ({\r\n\t\t\t...rule,\r\n\t\t\tcolIndex: fields.indexOf(rule.colname || rule.colName)\r\n\t\t}));\r\n\r\n\t\treturn indices.sort((idxA, idxB) => {\r\n\t\t\tconst a = validRecords[idxA];\r\n\t\t\tconst b = validRecords[idxB];\r\n\r\n\t\t\tfor (const rule of rulesWithIdx) {\r\n\t\t\t\tconst isAsc = rule.asc;\r\n\t\t\t\tconst expr = rule.expr; // 💡 등록된 expr 수식\r\n\t\t\t\tlet valA, valB;\r\n\r\n\t\t\t\t// 💡 1. expr 수식이 존재하면 ExprEngine으로 연산된 결과값을 가져옴\r\n\t\t\t\tif (expr) {\r\n\t\t\t\t\tvalA = this.#host.exprEngine.evaluate(expr, a, idxA);\r\n\t\t\t\t\tvalB = this.#host.exprEngine.evaluate(expr, b, idxB);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 2. 일반 바인딩 필드인 경우 원시 배열에서 추출\r\n\t\t\t\t\tif (rule.colIndex >= 0 && a.v && b.v) {\r\n\t\t\t\t\t\tvalA = a.v[rule.colIndex];\r\n\t\t\t\t\t\tvalB = b.v[rule.colIndex];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst isEmptyA = (valA === null || valA === undefined || valA === '');\r\n\t\t\t\tconst isEmptyB = (valB === null || valB === undefined || valB === '');\r\n\r\n\t\t\t\tif (isEmptyA && isEmptyB) continue;\r\n\t\t\t\tif (isEmptyA) return 1;\r\n\t\t\t\tif (isEmptyB) return -1;\r\n\r\n\t\t\t\tif (valA !== valB) {\r\n\t\t\t\t\tlet diff = 0;\r\n\r\n\t\t\t\t\tif (typeof valA === 'number' && typeof valB === 'number') {\r\n\t\t\t\t\t\tdiff = valA - valB;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tconst strA = String(valA);\r\n\t\t\t\t\t\tconst strB = String(valB);\r\n\t\t\t\t\t\tdiff = strA > strB ? 1 : (strA < strB ? -1 : 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (diff !== 0) {\r\n\t\t\t\t\t\treturn isAsc ? diff : -diff;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn idxA - idxB;\r\n\t\t});\r\n\r\n\t\ttrace.log(new Date());\r\n\t};\r\n}","import { trace } from \"@nopeer\";\nimport { TableCompiler } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport const COLLAPSED_WIDTH = 16;\n\nexport class PreCompiler {\n\n static initializeTable(host, tbl) {\n if (!host || !tbl) return null;\n\n // 1. 기본 구조 보장 (colgroup, thead)\n PreCompiler.#ensureColgroup(tbl);\n PreCompiler.#ensureThead(tbl);\n PreCompiler.#ensureSectionTbodys(tbl);\n\n PreCompiler.#ensureRowIndicator(tbl);\n\n PreCompiler.#normalizeColAttributes(tbl);\n\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('thead tr'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr[grouping=\"true\"]'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tbody.body tr:not([grouping=\"true\"])'));\n TableCompiler.resetColIndex(tbl, tbl.querySelectorAll('tfoot tr'));\n\n PreCompiler.#createColIndicator(tbl);\n\n // 2. 속성 정규화 (collapsed=\"true\" -> collapsible=\"true\" 보정)\n PreCompiler.#normalizeCollapsibleAttributes(tbl);\n\n // 3. 셀 커스텀 엘리먼트 생성\n PreCompiler.#generateCell(host, tbl);\n\n // 5. 초기 접힘/펼치기(expand) 버튼 및 너비 세팅\n PreCompiler.#initColExpanders(tbl);\n\n // 6. 필터 버튼 생성\n PreCompiler.#initFilterButtons(host, tbl);\n\n PreCompiler.#applyInitialCellWidths(tbl);\n //tbl.classList.add('nine-table-element');\n\n //trace.log(\"**************\", tbl.cloneNode(true));\n return tbl;\n }\n\n static #createColIndicator(tbl) {\n const thead = tbl.querySelector('thead');\n if (!thead || thead.querySelector('.col-indicator-rowgroup')) return;\n\n const tdTmpl = `<th data-col=\"@col\" class=\"col-indicator\" scope=\"col\"></th>`;\n\n // 맨 위에 인덱스용 row(tr) 삽입\n const tr = thead.insertRow(0);\n tr.setAttribute('role', 'row');\n tr.classList.add('col-indicator-rowgroup');\n tr.classList.add('collapse');\n\n const firstRow = tbl.querySelector('tbody tr');\n if (!firstRow) return;\n\n let cnt = 0;\n firstRow.querySelectorAll('th, td').forEach(td => {\n if (!td.classList.contains('dummy')) {\n const colSpan = td.colSpan || 1;\n for (let i = 0; i < colSpan; i++) {\n const html = tdTmpl.replace('@col', cnt).replace('@text', PreCompiler.#numToExcelCol(cnt++));\n tr.insertAdjacentHTML('beforeend', html);\n }\n }\n });\n\n // 🎯 colgroup의 모든 스타일 및 속성 동기화\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n tr.querySelectorAll('.col-indicator').forEach((el, i) => {\n const background = cols[i].getAttribute('background');\n if (background) {\n el.style.background = background;\n }\n });\n }\n\n // 엑셀 스타일 알파벳 변환 유틸 (A, B, C ... Z, AA, AB ...)\n static #numToExcelCol(num) {\n let text = '';\n for (let n = num; n >= 0; n = Math.floor(n / 26) - 1) {\n text = String.fromCharCode(65 + (n % 26)) + text;\n }\n return text;\n }\n\n static #ensureSectionTbodys(tbl) {\n let tbody = tbl.querySelector('tbody:not(.head):not(.foot)');\n\n if (!tbody) return;\n\n tbody.classList.add('body');\n\n // 🎯 이미 존재하지 않을 때만 생성\n if (!tbl.querySelector('tbody.head')) {\n const headTbody = document.createElement('tbody');\n headTbody.classList.add('head');\n tbody.before(headTbody);\n }\n\n if (!tbl.querySelector('tbody.foot')) {\n const footTbody = document.createElement('tbody');\n footTbody.classList.add('foot');\n tbody.after(footTbody);\n }\n }\n\n static #ensureColgroup(tbl) {\n let colgroup = tbl.querySelector('colgroup');\n if (!colgroup) {\n colgroup = document.createElement('colgroup');\n tbl.prepend(colgroup);\n }\n\n // 🎯 <col> 엘리먼트 자체가 없다면 행 기준으로 생성\n if (colgroup.querySelectorAll('col').length === 0) {\n const firstRow = tbl.querySelector('tbody tr');\n let colCount = 1;\n if (firstRow) {\n colCount = Array.from(firstRow.querySelectorAll('th, td')).reduce((sum, cell) => {\n return sum + (parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1);\n }, 0);\n }\n colCount = Math.max(colCount, 1);\n\n for (let i = 0; i < colCount; i++) {\n const col = document.createElement('col');\n colgroup.appendChild(col);\n }\n }\n\n // 🎯 col 속성 및 너비 정리는 별도 함수로 분리\n //PreCompiler.#normalizeColAttributes(tbl);\n }\n\n // 🎯 <col>들의 data-col, width, style.width 속성 정리를 전담하는 메서드\n static #normalizeColAttributes(tbl) {\n const cols = Array.from(tbl.querySelectorAll('colgroup col'));\n if (cols.length === 0) return;\n\n const containerWidth = tbl.clientWidth || 0;\n const defaultWidth = Math.max(Math.floor(containerWidth / cols.length), 100);\n\n cols.forEach((col, i) => {\n // 1. data-col 인덱스 보장\n if (!col.hasAttribute('data-col')) {\n col.setAttribute('data-col', i);\n }\n\n // 2. width 속성 및 style.width 정규화\n const width = col.getAttribute('width') || parseInt(col.style.width, 10) || defaultWidth;\n col.setAttribute('width', width);\n\n const widthVal = String(width).includes('px') ? width : `${width}px`;\n col.style.width = widthVal;\n });\n }\n\n static #ensureThead(tbl) {\n if (tbl.querySelector('thead')) return;\n\n const thead = document.createElement('thead');\n const colgroup = tbl.querySelector('colgroup');\n\n if (colgroup) {\n colgroup.after(thead);\n } else {\n tbl.prepend(thead);\n }\n }\n\n static #normalizeCollapsibleAttributes(tbl) {\n const headers = tbl.querySelectorAll('thead th, thead td');\n headers.forEach(cell => {\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n if (isCollapsed && cell.getAttribute('collapsible') !== 'true') {\n cell.setAttribute('collapsible', 'true');\n }\n });\n }\n\n static #generateCell(host, $tbl) {\n\n const targetAttributes = ['data-bind', 'data-expr', 'type'];\n let autoIdCounter = 0;\n\n $tbl.querySelectorAll('tbody th, tbody td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type') || \"renderer\";\n const tagName = `cell-${cellType}`;\n\n const $datalist = $cell.querySelector(\"datalist\");\n\n if ($datalist) {\n let l = [];\n $datalist.querySelectorAll('option').forEach($option => {\n l.push({\n k: $option.getAttribute(\"k\"),\n v: $option.getAttribute(\"v\"),\n });\n });\n\n // 🎯 1. 절대 겹치지 않는 유니크한 가상 함수 이름 생성\n const uniqueFuncName = `__ds_${Date.now()}_${++autoIdCounter}`;\n\n // 🎯 2. 호스트(NineTable)에 해당 데이터를 반환하는 클로저 함수 등록\n if (host) {\n host[uniqueFuncName] = () => l;\n }\n\n // 🎯 3. 셀에 data-source 자동 장착 (정규식/세터 스캔기가 알아서 캐치함)\n $cell.setAttribute(\"data-source\", `host.${uniqueFuncName}()`);\n\n // 🎯 4. 사용이 끝난 정적 datalist 엘리먼트는 DOM에서 제거\n $datalist.remove();\n }\n\n const expr = $cell.dataset.expr;\n if (expr) {\n $cell.setAttribute('data-expr', host.exprEngine.precompile(expr));\n }\n\n // 💡 2. 기타 속성들 중 표현식이 포함된 경우 프리컴파일\n Array.from($cell.attributes).forEach(attr => {\n if (['data-bind', 'data-expr', 'cell-type'].includes(attr.name)) return;\n if (attr.value.includes(\"data.\") || attr.value.includes(\"host.\")) {\n $cell.setAttribute(attr.name, host.exprEngine.precompile(attr.value));\n }\n });\n\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')}></${tagName}>`;\n $cell.setAttribute('tabindex', '0');\n });\n\n $tbl.querySelectorAll('thead th, thead td, tfoot th, tfoot td').forEach($cell => {\n const cellType = $cell.getAttribute('cell-type');\n if (cellType) {\n const originalContent = $cell.innerHTML;\n const tagName = `cell-${cellType}`;\n const innerAttrs = targetAttributes\n .filter(attr => $cell.hasAttribute(attr))\n .map(attr => `${attr}=\"${$cell.getAttribute(attr)}\"`);\n\n $cell.innerHTML = `<${tagName} ${innerAttrs.join(' ')} content=\"${originalContent}\"></${tagName}>`;\n }\n });\n }\n\n static #initFilterButtons(host, tbl) {\n const hostFilter = host.getAttribute('filtering') === 'true';\n const tableFilter = tbl.getAttribute('filtering') === 'true';\n\n // 🎯 인덱스 행을 제외한 실제 헤더 셀들만 타겟팅\n tbl.querySelectorAll('thead tr:not(.col-indicator-rowgroup) th, thead tr:not(.col-indicator-rowgroup) td').forEach(cell => {\n const finalFiltering = cell.getAttribute('filtering') === 'true' || tableFilter || hostFilter;\n\n cell.setAttribute('filtering', finalFiltering ? 'true' : 'false');\n\n if (finalFiltering) {\n cell.appendChild(document.createElement('nine-table-filter-button'));\n }\n });\n }\n\n static #initColExpanders(tbl) {\n /** 작동하나? */\n tbl.querySelectorAll('thead th, thead td').forEach(cell => {\n const isCollapsible = cell.getAttribute('collapsible') === 'true' || cell.getAttribute('expandable') === 'true';\n if (!isCollapsible) return;\n\n trace.log(\"11.*******************************\", cell.dataset.col);\n\n const colIndex = parseInt(cell.dataset.col, 10);\n const colSpan = cell.colSpan || 1;\n const col = tbl.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n\n trace.log(\"11.*******************************\", col);\n\n const currentWidth = col ? (parseInt(col.getAttribute('width'), 10) || 100) : 100;\n\n if (!cell.dataset.expandWidth || parseInt(cell.dataset.expandWidth, 10) <= COLLAPSED_WIDTH) {\n cell.dataset.expandWidth = String(currentWidth > COLLAPSED_WIDTH ? currentWidth : 100);\n }\n\n let expandBtn = cell.querySelector('nine-table-col-expand');\n if (!expandBtn) {\n expandBtn = document.createElement('nine-table-col-expand');\n cell.insertBefore(expandBtn, cell.firstChild);\n }\n\n const isCollapsed = cell.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n expandBtn.classList.add('collapsed');\n expandBtn.classList.remove('expand');\n expandBtn.setAttribute('collapsed', 'true');\n cell.style.color = 'transparent';\n\n const targetWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n if (!isNaN(colIndex)) {\n for (let i = 0; i < colSpan; i++) {\n const targetCol = tbl.querySelector(`colgroup col[data-col=\"${colIndex + i}\"]`);\n if (targetCol) {\n targetCol.setAttribute('width', targetWidth);\n targetCol.style.width = `${targetWidth}px`;\n }\n }\n }\n } else {\n expandBtn.classList.remove('collapsed');\n expandBtn.classList.add('expand');\n expandBtn.setAttribute('collapsed', 'false');\n cell.style.color = '';\n }\n });\n }\n\n static #ensureRowIndicator(tbl, host) {\n // 1. colgroup에 인디케이터용 <col> 추가\n const w = tbl.getAttribute(\"row-indicator\") === 'true' ? 48 : 0;\n\n const colgroup = tbl.querySelector('colgroup');\n\n //if (colgroup && !colgroup.querySelector('col.row-indicator-col')) {\n const col = document.createElement('col');\n //col.className = 'row-indicator-col';\n col.setAttribute('fixed', 'left');\n col.setAttribute('width', w);\n col.style.width = `${w}px`;\n colgroup.prepend(col);\n //}\n\n // 2. thead, tbody, tfoot 각 섹션별로 첫 번째 tr에 인디케이터 생성 및 rowSpan 부여\n //const sections = tbl.querySelectorAll('thead, tbody, tfoot');\n\n tbl.querySelectorAll('thead, tbody, tfoot').forEach(section => {\n const rows = Array.from(section.querySelectorAll('tr'));\n if (rows.length === 0) return;\n\n const firstTr = rows[0];\n\n const indicatorCell = document.createElement('th');\n indicatorCell.className = 'row-indicator';\n indicatorCell.setAttribute('cell-type', 'row-indicator');\n //indicatorCell.setAttribute('filtering', 'false');\n\n // 💡 섹션 내 행이 여러 개면(멀티 라인 템플릿 등) 전체를 아우르도록 rowSpan 설정\n if (rows.length > 1) {\n indicatorCell.rowSpan = rows.length;\n }\n\n firstTr.insertBefore(indicatorCell, firstTr.firstElementChild);\n });\n }\n\n static #applyInitialCellWidths(tbl) {\n // 🎯 컬럼 기준이 아닌 셀(th, td) 기준으로 순회하여 colspan 반영\n tbl.querySelectorAll('th[data-col], td[data-col]').forEach(cell => {\n\n trace.log(cell);\n\n const startColIdx = parseInt(cell.getAttribute('data-col'), 10);\n if (isNaN(startColIdx)) return;\n\n // 셀의 실제 colspan 값 추출 (기본값 1)\n const colSpan = parseInt(cell.getAttribute('colspan') || cell.colSpan, 10) || 1;\n let totalWidth = 0;\n\n // colspan 만큼 다음 컬럼들의 너비를 누적 합산\n for (let i = 0; i < colSpan; i++) {\n const targetIdx = startColIdx + i;\n const col = tbl.querySelector(`colgroup col[data-col=\"${targetIdx}\"]`);\n if (col) {\n totalWidth += parseInt(col.getAttribute('width'), 10) || 100;\n }\n }\n\n if (totalWidth > 0) {\n const widthVal = `${totalWidth}px`;\n cell.style.width = widthVal;\n cell.style.minWidth = widthVal;\n cell.style.maxWidth = widthVal;\n }\n });\n }\n}","// NineTableSheet.js (필터 버튼 레이아웃 및 패딩 스타일 완벽 통합본)\n\nimport { trace } from \"@nopeer\";\nimport './nine-table-hscrollbar.js';\nimport './nine-table-vscrollbar.js';\nimport { RowManager } from './core/RowManager.js';\nimport { TableCompiler } from \"./core/TableCompiler.js\";\nimport { CellSelection } from \"@/ui/cell-manager/CellSelection.js\";\nimport { CellNavigation } from \"@/ui/cell-manager/CellNavigation.js\";\n\nimport { ColResizer } from \"@/ui/col/ColResizer.js\";\nimport { ColMover } from \"@/ui/col/ColMover.js\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nimport { Filtering } from \"@/data/Filtering.js\";\nimport {Grouping, GroupingManager} from \"@/data/Grouping.js\";\nimport { Sorting } from \"@/data/Sorting.js\";\nimport { SheetView } from \"@/data/SheetView.js\";\n\nimport { PreCompiler } from \"@/ui/layout/core/PreCompiler.js\";\n\nexport class NineTableSheet extends HTMLElement {\n #index;\n #host;\n #rowManager;\n #cellSelection;\n #cellNavigation;\n #colResizer;\n #colMover;\n #colFix;\n #sorting;\n #filtering;\n #grouping;\n\n #view;\n\n #source = {\n table: null,\n };\n\n #elements;\n\n static SCROLLBAR_SIZE = 16;\n\n constructor() {\n super();\n trace.log(\"11111\")\n this.#rowManager = new RowManager(this);\n trace.log(\"222\")\n this.#host = this.getRootNode().host;\n trace.log(\"333\")\n }\n\n connectedCallback() {\n this.#init();\n }\n\n get index() { return this.#index; }\n get colResizer() { return this.#colResizer; }\n get filtering() { return this.#filtering; }\n get grouping() { return this.#grouping; }\n get colMover() { return this.#colMover; }\n get colFix() { return this.#colFix; }\n get rowManager() { return this.#rowManager; }\n get selection() { return this.#cellSelection; }\n get navigation() { return this.#cellNavigation; }\n get templateLength() { return this.#source.tbody.tr.length || 0; }\n\n get elements() { return this.#elements; }\n\n get isAutoFitCol() {\n const attrTrue = this.getAttribute('auto-fit-col') === 'true' || this.#host?.getAttribute('auto-fit-col') === 'true';\n const sourceTableTrue = this.#source.table?.getAttribute('auto-fit-col') === 'true';\n return attrTrue || sourceTableTrue;\n }\n\n get sourceTable() {\n return this.#source.table;\n }\n\n get source() {\n return this.#source;\n }\n\n get #isSimple() {\n return this.#host.hasAttribute('simple') || this.#host.getAttribute('theme') === 'simple';\n }\n\n recompileAndRefresh() {\n if (!this.#source.table) return;\n\n TableCompiler.recompile(this.#source.table);\n\n ['left', 'right', 'body'].forEach(type => {\n ['header', 'body', 'footer'].forEach(section => {\n const container = this.querySelector(`.ng-sheet-${section} .ng-container-${type}`);\n if (!container) return;\n container.querySelectorAll('table').forEach(tbl => tbl.remove());\n });\n });\n\n this.#renderSplitContainers();\n\n this.#updateContainerWidths();\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n requestAnimationFrame(() => {\n this.#updateContainerWidths();\n this.#rowManager?.refresh();\n });\n }\n\n refreshLayout() {\n if (!this.classList.contains('active') || !this.#source.table) return;\n\n requestAnimationFrame(() => {\n\n this.#updateContainerWidths();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n this.#adjustOverlay();\n\n this.#colResizer?.refreshLayout();\n\n this.#rowManager?.refresh();\n });\n }\n\n #adjustOverlay = () => {\n // 3분할된 영역 중 중앙(body) 또는 좌측 영역의 thead를 타겟팅하여 높이 측정\n const $thead = this.querySelector('.ng-container-body thead');\n const $overlay = this.querySelector('.ng-nodata-overlay');\n $overlay.style.top = `${$thead.offsetHeight}px`;\n }\n\n get view() {\n if (!this.#view && this.#host?.data) {\n this.#view = new SheetView(this);\n }\n return this.#view;\n }\n\n invalidate = () => {\n\n this.view.refresh();\n\n this.#rowManager.refresh(true);\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n }\n };\n\n autoFit = (enable = true) => {\n requestAnimationFrame(() => {\n this.#autoFit?.(enable);\n });\n };\n\n #autoFit = (enable = true) => {\n trace.log(\"autoFit\", this);\n\n const container = this.querySelector('.ng-sheet-body .ng-container-body');\n if (!container) return;\n\n const tables = container.querySelectorAll('table');\n const firstColgroup = this.querySelector('.ng-sheet-header .ng-container-body table colgroup');\n if (!firstColgroup) return;\n\n if (enable) {\n this.setAttribute('auto-fit-col', 'true');\n const containerWidth = container.clientWidth;\n if (containerWidth <= 0) return;\n\n let totalOriginalWidth = 0;\n const colList = [];\n\n // 1단계: 접힌 컬럼(16px 고정)과 일반 컬럼을 분리해서 수집\n firstColgroup.querySelectorAll('col').forEach(col => {\n const globalColIndex = col.getAttribute('data-col');\n const headerCell = this.querySelector(`.ng-sheet-header th[data-col=\"${globalColIndex}\"]`);\n const isCollapsed = headerCell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n colList.unshift({ globalColIndex, width: 16, isCollapsed: true });\n trace.log(`[AutoFit Col] Index ${globalColIndex}: COLLAPSED (forced 16px)`);\n } else {\n const w = parseInt(col.getAttribute('width'), 10) || 100;\n colList.push({ globalColIndex, width: w, isCollapsed: false });\n totalOriginalWidth += w;\n trace.log(`[AutoFit Col] Index ${globalColIndex}: NORMAL (original width: ${w}px)`);\n }\n });\n\n trace.log(`[AutoFit] Total Original Width of Normal Cols: ${totalOriginalWidth}px`);\n\n // 접힌 컬럼들이 차지하는 총 너비 계산\n const collapsedTotalWidth = colList\n .filter(c => c.isCollapsed)\n .reduce((sum, c) => sum + c.width, 0);\n\n // 남은 컨테이너 너비를 펼쳐진 컬럼들에게만 배분 (오류 수정)\n const availableWidth = Math.max(0, containerWidth - collapsedTotalWidth);\n trace.log(`[AutoFit] Collapsed Total Width: ${collapsedTotalWidth}px | Available Width for Normal Cols: ${availableWidth}px`);\n\n if (totalOriginalWidth > 0 && colList.length > 0) {\n let allocatedTotal = 0;\n\n const calculatedCols = colList.map(item => {\n if (item.isCollapsed) {\n return { globalColIndex: item.globalColIndex, remainder: 0, width: 16 };\n }\n\n // 연산자 오류 수정 (* 와 - 추가)\n const exactWidth = (item.width * availableWidth) / totalOriginalWidth;\n const baseWidth = Math.max(30, Math.floor(exactWidth));\n allocatedTotal += baseWidth;\n return {\n globalColIndex: item.globalColIndex,\n remainder: exactWidth - Math.floor(exactWidth),\n width: baseWidth\n };\n });\n\n // 잔여 픽셀 보정 (오류 수정)\n let remainderPixels = availableWidth - allocatedTotal;\n trace.log(`[AutoFit] Initial Allocated Total: ${allocatedTotal}px | Remainder Pixels to distribute: ${remainderPixels}`);\n\n const uncollapsedCols = calculatedCols.filter(c => !colList.find(item => item.globalColIndex === c.globalColIndex)?.isCollapsed);\n\n if (remainderPixels > 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => b.remainder - a.remainder);\n for (let i = 0; i < remainderPixels; i++) {\n uncollapsedCols[i % uncollapsedCols.length].width += 1;\n }\n } else if (remainderPixels < 0 && uncollapsedCols.length > 0) {\n uncollapsedCols.sort((a, b) => a.remainder - b.remainder);\n for (let i = 0; i < Math.abs(remainderPixels); i++) {\n const target = uncollapsedCols[i % uncollapsedCols.length];\n if (target.width > 30) target.width -= 1;\n }\n }\n\n const finalSumWidth = calculatedCols.reduce((sum, c) => sum + c.width, 0);\n trace.log(`[AutoFit Verification] Target Container Width: ${containerWidth}px | Sum of All Calculated Cols: ${finalSumWidth}px`);\n\n if (containerWidth !== finalSumWidth) {\n trace.log(`⚠️ [AutoFit Mismatch Warning!] 오차 발생: ${containerWidth - finalSumWidth}px 차이가 납니다.`);\n } else {\n trace.log(`✅ [AutoFit Success] 완벽하게 일치합니다!`);\n }\n\n // 최종 적용\n calculatedCols.forEach(({ globalColIndex, width }) => {\n trace.log(`[AutoFit Apply] Col Index ${globalColIndex} -> ${width}px`);\n this.#colResizer?.setColumnWidth(globalColIndex, width, 'body');\n });\n }\n } else {\n this.removeAttribute('auto-fit-col');\n }\n\n this.querySelector('nine-table-hscrollbar')?.refresh();\n }\n\n generate = ($table, index) => {\n\n this.#index = index;\n\n PreCompiler.initializeTable(this.#host, $table);\n\n trace.log(\"=======\", $table);\n\n this.#source = {\n table: TableCompiler.compile($table),\n tbody: {\n tr: $table.querySelectorAll(\"tbody tr\"),\n }\n };\n\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n this.#renderSplitContainers();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#updateContainerWidths();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n\n this.#syncHeaderAndFooterHeights();\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //\n this.#initRowHoverEvent();\n\n ['left', 'body', 'right'].forEach(type => {\n const prefix = `.ng-container-${type}`;\n this.#elements[type] = {\n thead: this.querySelector(`${prefix} thead`),\n tbody: {\n head: this.querySelector(`${prefix} tbody.head`),\n body: this.querySelector(`${prefix} tbody.body`),\n foot: this.querySelector(`${prefix} tbody.foot`),\n },\n tfoot: this.querySelector(`${prefix} tfoot`),\n };\n });\n\n //trace.log(\"---------\", this, this.sourceTable.cloneNode(true));\n //trace.log(\"********1\", this.#source.table)\n\n this.#rowManager.initialize();\n\n if (this.isAutoFitCol) {\n this.autoFit(true);\n } else {\n this.querySelector('nine-table-hscrollbar').refresh();\n }\n\n //this.#grouping = new GroupingManager(this);\n this.#grouping.initialize();\n\n this.loaded = true;\n };\n\n\n #updateContainerWidths = () => {\n const isAutoFit = this.isAutoFitCol;\n\n ['left', 'right', 'body'].forEach(type => {\n const containers = this.querySelectorAll(`.ng-container-${type}`);\n if (containers.length === 0) return;\n\n const firstTable = containers[0].querySelector('table');\n if (!firstTable) return;\n\n let width = 0;\n firstTable.querySelectorAll('col').forEach(col => {\n const w = parseInt(col.getAttribute('width'), 10);\n if (!isNaN(w)) width += w;\n });\n\n containers.forEach(container => {\n const tables = container.querySelectorAll('table');\n if (type === 'body') {\n container.style.flex = `1`;\n tables.forEach(tbl => {\n //tbl.style.width = isAutoFit ? `100%` : `${width}px`;\n //tbl.style.minWidth = isAutoFit ? `100%` : `${width}px`;\n });\n } else {\n container.style.flex = `0 0 ${width}px`;\n container.style.width = `${width}px`;\n container.style.minWidth = `${width}px`;\n container.style.maxWidth = `${width}px`;\n tables.forEach(tbl => {\n //tbl.style.width = `${width}px`;\n //tbl.style.minWidth = `${width}px`;\n });\n }\n });\n });\n };\n\n #renderSplitContainers = () => {\n const colTypes = [\n { selector: '.ng-container-left', type: 'left' },\n { selector: '.ng-container-body', type: null },\n { selector: '.ng-container-right', type: 'right' }\n ];\n\n colTypes.forEach(({ selector, type }) => {\n this.querySelector(`.ng-sheet-body ${selector}`).appendChild(this.#createSplitTable(type));\n });\n };\n\n #createSplitTable = (targetFixedType) => {\n\n const $tbl = this.#source.table.cloneNode(true);\n\n if (targetFixedType === 'left') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"left\") $el.remove();\n });\n } else if (targetFixedType === 'right') {\n $tbl.querySelectorAll(\"col, th, td\").forEach($el => {\n if ($el.getAttribute(\"fixed\") !== \"right\") $el.remove();\n });\n } else {\n $tbl.querySelectorAll(\"[fixed=left], [fixed=right]\").forEach($el => {\n $el.remove();\n });\n }\n\n return $tbl;\n };\n\n getRowHeight = () => {\n return this.#rowManager.getRowHeight();\n };\n\n scrollToX = (scrollLeft) => {\n const bodyContainer = this.querySelector('.ng-sheet-body .ng-container-body');\n if (bodyContainer) bodyContainer.scrollLeft = scrollLeft;\n };\n\n scrollToY = (scrollTop) => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (bodyViewport) bodyViewport.scrollTop = scrollTop;\n };\n\n #init = () => {\n trace.log(\"11111*****************\");\n\n this.#render();\n\n this.#cellSelection = new CellSelection(this);\n this.#cellNavigation = new CellNavigation(this);\n this.#colResizer = new ColResizer(this);\n this.#colMover = new ColMover(this);\n this.#colFix = new ColFixManager(this);\n\n this.#view = new SheetView(this);\n this.#filtering = new Filtering(this);\n this.#grouping = new GroupingManager(this);\n\n //trace.log(\"----------------------\")\n //trace.log(\"Is GroupingManager instance?\", this.#grouping instanceof GroupingManager); // true가 나와야 정상\n //trace.log(\"Grouping keys:\", Object.keys(this.#grouping)); // 또는 내부 속성 확인\n\n if (!this.#isSimple) {\n this.#sorting = new Sorting(this);\n }\n\n this.#elements.mainBody.addEventListener('scroll', () => {\n this.querySelector(\"nine-table-hscrollbar\").refresh();\n });\n };\n\n\n\n #render = () => {\n trace.log(\"11111*****************\");\n const sbSize = NineTableSheet.SCROLLBAR_SIZE;\n trace.log(\"2222*****************\");\n this.innerHTML = `\n <div class=\"ng-sheet-body\">\n <div class=\"ng-sheet-body-content\">\n <div class=\"ng-container-left\"></div>\n <div class=\"ng-container-body\"></div>\n <div class=\"ng-container-right\"></div>\n </div>\n <div class=\"ng-virtual-height-holder\"></div>\n </div>\n\n <div class=\"ng-nodata-overlay\">Data Not Found</div>\n\n <!-- [Grid Row 1, Col 2] 세로 스크롤바 -->\n <nine-table-vscrollbar></nine-table-vscrollbar>\n\n <!-- [Grid Row 2, Col 1] 가로 스크롤바 -->\n <nine-table-hscrollbar></nine-table-hscrollbar>\n\n <!-- [Grid Row 2, Col 2] 우하단 엣지 -->\n <div class=\"ng-scroll-edge\"></div>\n \n <!-- 리사이저 및 드래그 패널들 -->\n <div class=\"ng-col-resizer-panel\">\n <div class=\"resizer-overlay\">\n <span class=\"size-badge\">0px</span>\n </div>\n </div>\n \n <div class=\"ng-col-mover-grip\"></div>\n <div class=\"ng-col-mover-indi\"></div>\n `;\n\n //let fixedHeight = this.#sheet.querySelector('.ng-container-body thead').offsetHeight + this.#sheet.querySelector('.ng-container-body tfoot').offsetHeight;\n trace.log(\"3333*****************\");\n this.#elements = {\n mainBody: this.querySelector('.ng-sheet-body .ng-container-body'),\n hscrollbar: this.querySelector('nine-table-hscrollbar'),\n vscrollbar: this.querySelector('nine-table-vscrollbar'),\n content: this.querySelector('.ng-sheet-body .ng-sheet-body-content'),\n scrollHolder: this.querySelector('.ng-sheet-body .ng-virtual-height-holder'),\n }\n trace.log(\"444*****************\");\n };\n\n #syncHeaderAndFooterHeights = () => {\n trace.log(\"**********************\", \"#syncHeaderAndFooterHeights\");\n\n const leftTable = this.querySelector('.ng-container-left table');\n const bodyTable = this.querySelector('.ng-container-body table');\n const rightTable = this.querySelector('.ng-container-right table');\n\n // 1. 헤더(thead) 행 높이 싱크 (인덱스 행 제외)\n const leftHeaderRows = Array.from(leftTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const bodyHeaderRows = Array.from(bodyTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n const rightHeaderRows = Array.from(rightTable.querySelectorAll('thead tr:not(.col-indicator-rowgroup)'));\n\n this.#applyMaxHeights(leftHeaderRows, bodyHeaderRows, rightHeaderRows);\n\n // 2. 푸터(tfoot) 행 높이 싱크\n const leftFooterRows = Array.from(leftTable.querySelectorAll('tfoot tr'));\n const bodyFooterRows = Array.from(bodyTable.querySelectorAll('tfoot tr'));\n const rightFooterRows = Array.from(rightTable.querySelectorAll('tfoot tr'));\n\n this.#applyMaxHeights(leftFooterRows, bodyFooterRows, rightFooterRows);\n };\n\n// 공통 최대 높이 적용 헬퍼 메서드\n #applyMaxHeights = (leftRows, bodyRows, rightRows) => {\n const maxRows = Math.max(leftRows.length, bodyRows.length, rightRows.length);\n\n for (let i = 0; i < maxRows; i++) {\n const heights = [\n leftRows[i]?.getBoundingClientRect().height || 0,\n bodyRows[i]?.getBoundingClientRect().height || 0,\n rightRows[i]?.getBoundingClientRect().height || 0\n ];\n const maxHeight = Math.max(...heights);\n\n if (maxHeight > 0) {\n if (leftRows[i]) leftRows[i].style.height = `${maxHeight}px`;\n if (bodyRows[i]) bodyRows[i].style.height = `${maxHeight}px`;\n if (rightRows[i]) rightRows[i].style.height = `${maxHeight}px`;\n }\n }\n };\n\n #initRowHoverEvent = () => {\n const bodyViewport = this.querySelector('.ng-sheet-body');\n if (!bodyViewport) return;\n\n let activeRowIndex = null;\n\n // 마우스 진입 (모든 컨테이너 탐색)\n bodyViewport.addEventListener('mouseover', (e) => {\n const tr = e.target.closest('tr');\n if (!tr || !tr.dataset.row && tr.dataset.row !== '0') return;\n\n const rowIndex = tr.dataset.row;\n if (activeRowIndex === rowIndex) return;\n activeRowIndex = rowIndex;\n\n // 좌측, 본문, 우측 컨테이너에서 동일한 data-row를 가진 tr들을 모두 찾아 .hover 부여\n bodyViewport.querySelectorAll(`tr[data-row=\"${rowIndex}\"]`).forEach($tr => {\n $tr.classList.add('hover');\n });\n });\n\n // 마우스 이탈\n bodyViewport.addEventListener('mouseout', (e) => {\n const tr = e.target.closest('tr');\n if (!tr) return;\n\n // 현재 영역을 완전히 벗어났을 때만 전체 hover 제거\n const relatedTarget = e.relatedTarget;\n if (tr.contains(relatedTarget)) return;\n\n bodyViewport.querySelectorAll('tr.hover').forEach($tr => {\n $tr.classList.remove('hover');\n });\n activeRowIndex = null;\n });\n }\n\n disconnectedCallback() {\n this.#colResizer?.destroy();\n this.#colMover?.destroy();\n this.innerHTML = '';\n }\n}\n\nif (!customElements.get('nine-table-sheet')) {\n customElements.define('nine-table-sheet', NineTableSheet);\n}","import { trace } from \"@nopeer\";\nimport '@/ui/layout/nine-table-sheets.js';\nimport '@/ui/layout/nine-table-sheets-footer.js';\nimport '@/ui/layout/nine-table-toolbar.js';\nimport { NineTableSheet } from \"@/ui/layout/nine-table-sheet.js\";\n\nexport class LayoutManager {\n #host;\n\n constructor(owner) {\n this.#host = owner;\n this.#init();\n }\n\n #init = () => {\n this.#render();\n\n new ResizeObserver((entries) => {\n for (let entry of entries) {\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n }\n }).observe(this.#host);\n }\n\n set loading(val) {\n if (!!val) {\n this.#host.classList.add(\"loading\");\n } else {\n this.#host.classList.remove(\"loading\");\n }\n }\n\n #applyAutoHeight = () => {\n const activeSheets = Array.from(this.#host.shadowRoot.querySelectorAll('nine-table-sheet.active'));\n if (activeSheets.length === 0) return;\n\n const maxDisplayRows = parseInt(this.#host.getAttribute('max-display-row'), 10) || 10;\n const maxRowHeight = Math.max(...activeSheets.map(sheet => sheet.getRowHeight()));\n\n const toolbarEl = this.#host.shadowRoot.querySelector('nine-table-toolbar');\n const footerEl = this.#host.shadowRoot.querySelector('nine-table-sheets-footer');\n\n const toolbarHeight = toolbarEl ? toolbarEl.getBoundingClientRect().height : 0;\n const footerHeight = footerEl ? footerEl.getBoundingClientRect().height : 0;\n const extraPadding = NineTableSheet.SCROLLBAR_SIZE;\n\n const calculatedHeight = (maxDisplayRows * maxRowHeight) + toolbarHeight + footerHeight + extraPadding;\n\n this.#host.style.height = `${calculatedHeight}px`;\n };\n\n #render = () => {\n\n const rawElements = Array.from(this.#host.children);\n const rawTables = rawElements.filter(el => (el.tagName.toUpperCase() === 'TABLE') );\n const isAutoHeight = this.#host.getAttribute('auto-height') === 'true';\n const sheetCount = rawTables.length;\n\n const sheetsHtml = rawTables.map((tbl, idx) => {\n const className = idx === 0 ? 'active' : '';\n const sheetId = tbl.id || `sheet${idx + 1}`;\n\n const sheetTag = `<nine-table-sheet class=\"${className}\" data-index=\"${idx}\" data-sheet-id=\"${sheetId}\" id=\"${sheetId}\"></nine-table-sheet>`;\n const splitterTag = idx < sheetCount - 1 ? `<nine-splitter class=\"h\" data-split-index=\"${idx}\"></nine-splitter>` : '';\n return sheetTag + splitterTag;\n }).join('');\n\n // 1. 공통 파일명 배열 정의\n const cssFiles = ['layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table'];\n // 2. npm 패키지 CSS 배열 생성\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}.css\";`\n );\n\n // 3. 커스텀 CSS 배열 생성\n const customCssImports = [];\n if (nine.cssPath) {\n cssFiles.forEach(file => {\n customCssImports.push(`@import \"${nine.cssPath}/${file}.css\";`);\n });\n }\n\n this.#host.shadowRoot.innerHTML = `\n <style>\n ${[...npmCssImports, ...customCssImports].join('\\n')}\n </style>\n \n <nine-table-toolbar></nine-table-toolbar>\n\n <nine-table-body>\n <nine-table-summary></nine-table-summary>\n <div class=\"ng-loading-bar\"></div>\n <nine-table-sheets>\n <nine-table-sheets-body>\n ${sheetsHtml}\n </nine-table-sheets-body>\n <nine-table-sheets-footer></nine-table-sheets-footer>\n </nine-table-sheets>\n <nine-table-analysis></nine-table-analysis>\n </nine-table-body>\n <nine-table-footer></nine-table-footer>\n `;\n\n /**\n * <div class=\"nine-tab-bar\">${tabsHtml}</div>\n * <div class=\"sheets-counter\">Total : <span id=\"row-count\">0</span></div>\n */\n this.#host.shadowRoot.querySelectorAll('nine-table-sheet').forEach(($el, idx) => {\n\n if (rawTables[idx]) {\n setTimeout(() => {\n $el.generate(rawTables[idx], idx);\n if (isAutoHeight) {\n this.#applyAutoHeight();\n }\n });\n }\n });\n };\n}","import { trace } from \"@nopeer\";\n\nexport class ExprEngine {\n #host;\n #fields;\n #exprCache = new Map(); // 💡 통합된 단일 캐시로 모든 컴파일된 함수 관리\n\n constructor(host) {\n this.#host = host;\n this.#fields = host.fields.get();\n }\n\n /**\n * 🎯 표현식 내의 data.fieldName을 원시 배열 인덱스 접근(rowItem.v[idx])으로 변환\n */\n rewriteExpr(expr) {\n\n if (!expr || !this.#fields.length) return expr;\n\n return expr.replace(/data\\.([a-zA-Z_$][\\w$]*)/g, (match, fieldName) => {\n const idx = this.#fields.indexOf(fieldName);\n return idx >= 0 ? `rowItem.v[${idx}]` : match;\n });\n }\n\n /**\n * 🎯 셀 또는 컬럼 정의에 선언된 expr 프리컴파일\n */\n precompile(expr) {\n if (!expr) return expr;\n return this.rewriteExpr(expr);\n }\n\n /**\n * 🎯 표현식 평가 및 실행 (통합 캐싱)\n */\n evaluate(expr, rowItem, row = 0) {\n if (expr === undefined || expr === null) return \"\";\n\n //trace.log(expr, rowItem, this.#exprCache);\n\n try {\n const trimmedExpr = String(expr).trim();\n const compiledExpr = this.rewriteExpr(trimmedExpr);\n\n // 💡 함수 호출, 데이터 참조, 연산식이 포함된 경우 통합 평가 및 캐싱\n if (compiledExpr.includes(\"data.\") || compiledExpr.includes(\"rowItem.v\") || compiledExpr.includes(\"host.\") || compiledExpr.includes(\"(\")) {\n let evalFn = this.#exprCache.get(compiledExpr);\n\n if (!evalFn) {\n evalFn = new Function('rowItem', 'row', 'host', `\n const data = rowItem;\n if (!data && !host) return \"\";\n return ${compiledExpr};\n `);\n this.#exprCache.set(compiledExpr, evalFn);\n }\n\n return evalFn(rowItem, row, this.#host);\n }\n\n // 단순 리터럴 문자열인 경우\n return compiledExpr;\n } catch (e) {\n //console.error(\"ExprEngine evaluation error:\", expr, e);\n return expr;\n }\n }\n}","import { trace } from \"@nopeer\";\nimport { ngDataManager } from '@/data/ngDataManager.js';\nimport { fields } from \"@/data/Fields.js\";\nimport { LayoutManager } from '@/ui/layout/core/LayoutManager.js';\nimport { ExprEngine } from \"@/core/ExprEngine.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\n\nexport default class NineTable extends HTMLElement {\n #shadowRoot;\n #dataManager;\n #layoutManager;\n #templateCnt = 0; // 🎯 로딩 상태 플래그\n\n constructor() {\n super();\n\n this.#shadowRoot = this.attachShadow({ mode: 'open' });\n this.#dataManager = new ngDataManager(this);\n }\n\n connectedCallback() {\n setTimeout(() => {\n this.#templateCnt = this.querySelectorAll(\"table\")?.length;\n\n this.fields = new fields(this);\n this.exprEngine = new ExprEngine(this);\n\n this.#bindDynamicSetters();\n\n this.#layoutManager = new LayoutManager(this);\n\n this.#dispatchLoad();\n //this.dispatchEvent(new CustomEvent('load', { bubbles: true, detail: { target: this } }));\n });\n }\n\n disconnectedCallback() {\n trace.log('NineTable disconnected.');\n }\n\n #dispatchLoad = () => {\n // 🎯 2. 변수명 오타 수정 (#sheetCnt -> #templateCnt)\n //trace.log(\"*********************** template count:\", this.#templateCnt);\n\n let checkCount = 0;\n const maxChecks = 50; // 최대 5초 대기 (100ms * 50)\n\n const checkTimer = setInterval(() => {\n checkCount++;\n\n const sheets = this.shadow.querySelectorAll('nine-table-sheet');\n //trace.log(\"Current mounted sheets:\", sheets.length);\n\n if (checkCount >= maxChecks) {\n clearInterval(checkTimer);\n }\n\n if (sheets.length >= this.#templateCnt) {\n let loadSheetCnt = 0;\n sheets.forEach($sheet => {\n if ($sheet.loaded) loadSheetCnt++;\n });\n\n //trace.log('Checking sheet loaded status:', loadSheetCnt, '/', this.#templateCnt);\n\n if (loadSheetCnt >= this.#templateCnt) {\n clearInterval(checkTimer);\n this.loaded = true;\n this.dispatchEvent(new CustomEvent(NINE_TABLE.EVENT.LOAD, { bubbles: true, detail: { target: this } }));\n }\n }\n }, 100);\n }\n\n\n // 🎯 공통 데이터 & API 접근자\n get shadow() { return this.#shadowRoot; }\n get dataManager() { return this.#dataManager; }\n get data() { return this.#dataManager.data; }\n get row() { return this.#dataManager.row; }\n\n setData(records) {\n this.#dataManager.data.set(records);\n this.refresh();\n }\n\n refresh() {\n this.activeSheet?.invalidate();\n }\n\n // 🎯 섀도우 돔 내부에서 로딩바 요소를 안전하게 캐싱\n\n\n set loading(val) {\n this.#layoutManager.loading = val;\n }\n\n /**\n * 랜더링 이후에 생기는 data-source 처리기능\n */\n rerenderer() {\n\n this.activeSheet?.querySelectorAll(\"tbody.body th,tbody.body td\").forEach(($cell) => {\n const customComp = Array.from($cell.children).find($el => {\n return $el.tagName.toLowerCase().startsWith('cell-') && typeof $el.rerenderer === 'function'\n });\n\n customComp?.rerenderer();\n })\n }\n\n // 시트 제어 API\n sheet = (idOrIndex) => {\n if (idOrIndex === null || idOrIndex < 0) return this.activeSheet;\n const sheets = Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n\n if (typeof idOrIndex === 'number') return sheets[idOrIndex] || null;\n if (typeof idOrIndex === 'string') {\n return this.shadow.querySelector(`nine-table-sheet#${idOrIndex}, nine-table-sheet[data-sheet-id=\"${idOrIndex}\"]`) || null;\n }\n return sheets[0] || null;\n }\n\n get sheets() {\n return Array.from(this.shadow.querySelectorAll('nine-table-sheet'));\n }\n\n get activeSheet() {\n return this.shadow.querySelector('nine-table-sheet.active') || null;\n }\n\n #bindDynamicSetters() {\n const extractedMethodNames = new Set();\n\n this.querySelectorAll('[data-source]').forEach(el => {\n const dataSource = el.getAttribute('data-source');\n if (!dataSource) return;\n\n // 💡 [수정] 뒤에 여멀림 괄호 '('가 오는 형태만 매칭하여 'DEPART' 같은 파라미터는 배제!\n const matches = dataSource.matchAll(/(?:host\\.)?([a-zA-Z0-9_$]+)\\s*\\(/g);\n for (const match of matches) {\n const name = match[1];\n if (name && name !== 'host') {\n extractedMethodNames.add(name);\n }\n }\n });\n\n // 추출된 메서드 이름별로 NineTable 인스턴스에 동적 세터 생성\n extractedMethodNames.forEach(methodName => {\n let internalValue = null;\n\n Object.defineProperty(this, methodName, {\n set: (newValue) => {\n internalValue = newValue;\n\n // 값이 대입되는 순간 그리드 자동 갱신\n //this.refresh();\n this.rerenderer();\n },\n get: () => internalValue,\n configurable: true,\n enumerable: true\n });\n });\n }\n\n execute = (fn) => {\n this.loading = true;\n setTimeout(() => {\n try {\n fn.call(this);\n } finally {\n this.loading = false;\n }\n })\n }\n}\n\nif (!customElements.get('nine-table')) {\n customElements.define('nine-table', NineTable);\n}\n\nif (!customElements.get('nine-table-simple')) {\n customElements.define('nine-table-simple', class extends NineTable {\n connectedCallback() {\n // simple 태그로 생성되면 자동으로 mode=\"simple\" 속성 부여\n this.setAttribute('theme', 'simple');\n\n super.connectedCallback();\n }\n });\n}","export class BasicCellElement extends HTMLElement {\r\n\r\n\tstatic _styleCache = new Map();\r\n\tstatic _customStyleCache = new Map(); // 👈 커스텀 스타일용 캐시 추가\r\n\r\n\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tapplyBaseStyle() {\r\n\t\tconst className = this.constructor.name;\r\n\r\n\t\treturn;\r\n\t\t// 1. 기본 스타일 시트 처리 (캐싱 O)\r\n\t\tif (!ngElement._styleCache.has(className)) {\r\n\t\t\tconst baseSheet = new CSSStyleSheet();\r\n\t\t\tngElement._styleCache.set(className, baseSheet);\r\n\r\n\t\t\tconst baseUrl = `https://cdn.jsdelivr.net/npm/@ninebone/grid@${__APP_VERSION__}/dist/css/${className}.css`;\r\n\t\t\tfetch(baseUrl)\r\n\t\t\t\t.then(res => res.text())\r\n\t\t\t\t.then(cssText => baseSheet.replaceSync(cssText))\r\n\t\t\t\t.catch(err => console.error(`Base CSS Load Error:`, err));\r\n\t\t}\r\n\r\n\t\tconst sheets = [ngElement._styleCache.get(className)];\r\n\r\n\t\t// 2. 커스텀 스타일 시트 처리 (자바스크립트 단 캐싱 O)\r\n\t\tif (nine.cssPath) {\r\n\t\t\tif (!ngElement._customStyleCache.has(className)) {\r\n\t\t\t\tconst customSheet = new CSSStyleSheet();\r\n\t\t\t\tngElement._customStyleCache.set(className, customSheet);\r\n\r\n\t\t\t\t// 💡 오타 수정 및 캐시 파라미터 제거\r\n\t\t\t\tconst customUrl = `${nine.cssPath}/ninegrid/${className}.css`;\r\n\r\n\t\t\t\tfetch(customUrl)\r\n\t\t\t\t\t.then(res => res.text())\r\n\t\t\t\t\t.then(cssText => customSheet.replaceSync(cssText))\r\n\t\t\t\t\t.catch(err => console.error(`Custom CSS Load Error:`, err));\r\n\t\t\t}\r\n\r\n\t\t\t// 캐시된 커스텀 시트가 있으면 기본 시트 배열 뒤에 추가\r\n\t\t\tsheets.push(ngElement._customStyleCache.get(className));\r\n\t\t}\r\n\r\n\t\t// 한 번에 섀도우 돔에 적용\r\n\t\tthis.shadowRoot.adoptedStyleSheets = sheets;\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\t// ngElement 레벨에서는 비워두셔도 됩니다.\r\n\t}\r\n}","import { trace } from \"@nopeer\";\r\nimport { BasicCellElement } from './BasicCellElement.js';\r\n\r\nconst exprCache = new Map();\r\nconst hostFuncCache = new Map();\r\n\r\nexport class CellElement extends BasicCellElement {\r\n\t#host;\r\n\t#sheet;\r\n\t#tr;\r\n\t#cell;\r\n\r\n\t#attr;\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tget host() { return this.#host; }\r\n\tget sheet() { return this.#sheet; }\r\n\tget cell() { return this.#cell; }\r\n\tget tr() { return this.#tr; }\r\n\tget attr() { return this.#attr; }\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\tthis.#host = this.getRootNode().host;\r\n\r\n\t\tthis.#cell = this.closest(\"th,td\");\r\n\t\tthis.#tr = this.#cell.closest(\"tr\");\r\n\t\tthis.#sheet = this.#tr.closest(\"nine-table-sheet\");\r\n\r\n\t\tthis.#cell.classList.add(this.tagName);\r\n\r\n\t\tthis.#attr = {};\r\n\t\tfor (let i = 0; i < this.#cell.attributes.length; i++) {\r\n\t\t\tconst name = this.#cell.attributes[i].name;\r\n\t\t\tif (![\"text-align\",\"class\",\"cell-type\",\"data-bind\",\"data-expr\",\"data-col\",\"tabindex\"].includes(name)) {\r\n\t\t\t\tthis.#attr[name] = this.#cell.attributes[i].value;\r\n\t\t\t\t//this.setAttribute(name, this.#cell.attributes[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this.#cell) return;\r\n\r\n\r\n\t\tconst root = this.shadowRoot || this;\r\n\r\n\t\t// 🎯 버튼 이벤트 연결\r\n\t\troot.querySelectorAll(\"button, ng-expand-button\").forEach(button => {\r\n\t\t\tbutton.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onbuttonclick\") || this.getAttribute(\"onButtonClick\") || this.#cell?.getAttribute(\"onbuttonclick\") || this.#cell?.getAttribute(\"onButtonClick\");\r\n\r\n\t\t\t\tconst rowData = this.data; // Proxy Lazy 접근\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t/**\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.BUTTON_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t})); */\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\t// 🎯 링크 이벤트 연결\r\n\t\tconst renderer = root.querySelector(\".renderer\");\r\n\t\tif (renderer && this.getAttribute(\"link\") === \"true\") {\r\n\t\t\trenderer.classList.add(\"link\");\r\n\r\n\t\t\trenderer.addEventListener(\"click\", () => {\r\n\t\t\t\tlet fn = this.getAttribute(\"onlinkclick\") || this.getAttribute(\"onLinkClick\");\r\n\r\n\t\t\t\tconst rowData = this.data;\r\n\t\t\t\tconst curRow = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\t\t\tif (fn && this.#host) {\r\n\t\t\t\t\tfn = fn.replace(\"()\", \"\");\r\n\t\t\t\t\tconst match = fn.match(/^(\\w+)\\s*\\(/);\r\n\t\t\t\t\tconst methodName = match?.[1] || fn;\r\n\r\n\t\t\t\t\tif (typeof this.#host[methodName] === 'function') {\r\n\t\t\t\t\t\tthis.#host[methodName].call(this.#host, rowData, curRow, this.#cell);\r\n\t\t\t\t\t} else if (typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\t\t\tthis.#host.exprFunction(fn).call(this, rowData, curRow);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.#host?.dispatchEvent(new CustomEvent(ninegrid.EVENT.LINK_CLICK, {\r\n\t\t\t\t\tdetail: { target: this.#cell, data: rowData, currow: curRow },\r\n\t\t\t\t\tbubbles: true,\r\n\t\t\t\t\tcomposed: true\r\n\t\t\t\t}));\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [Proxy 최적화] 속성 읽기 시에도 fields.indexOf() 사용\r\n\t */\r\n\tget data() {\r\n\t\tconst rawRecord = this.#tr?.data;\r\n\t\tif (!rawRecord) return null;\r\n\t\tif (!rawRecord.v) return rawRecord;\r\n\r\n\t\tconst host = this.#host;\r\n\r\n\t\treturn new Proxy(rawRecord, {\r\n\t\t\tget(target, prop) {\r\n\t\t\t\tif (prop === '__ng') return target.__ng;\r\n\t\t\t\tif (prop === 'v') return target.v;\r\n\r\n\t\t\t\t// 💡 host.fields.indexOf(prop) 사용\r\n\t\t\t\tconst idx = host?.fields?.indexOf?.(prop) ?? -1;\r\n\t\t\t\treturn idx >= 0 ? target.v[idx] : target[prop];\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [핵심] 변환 없이 원시 v 배열에서 direct 인덱스 검색 (GC zero)\r\n\t */\r\n\tget value() {\r\n\t\tif (!this.#cell || !this.#tr?.data) return \"\";\r\n\r\n\t\tconst bindKey = this.#cell.dataset?.bind;\r\n\t\tif (!bindKey) return \"\";\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\t// 1. 원시 데이터 배열({ v: [...] }) 구조인 경우\r\n\t\tif (rawRecord.v && Array.isArray(rawRecord.v)) {\r\n\t\t\t// 💡 fields.indexOf(bindKey)로 바로 찾기!\r\n\t\t\tconst colIdx = this.#host.fields.get().indexOf(bindKey) ?? -1;\r\n\t\t\treturn colIdx >= 0 ? (rawRecord.v[colIdx] ?? \"\") : \"\";\r\n\t\t}\r\n\r\n\t\t// 2. 일반 JSON 객체인 경우 (하위 호환)\r\n\t\treturn rawRecord[bindKey] ?? \"\";\r\n\t}\r\n\r\n\tset value(v) {\r\n\t\tif (!this.#cell || !this.#host?.data) return;\r\n\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tif (isNaN(row) || !bindKey) return;\r\n\r\n\t\tconst updateRowState = this.getAttribute('update-row-state') !== \"false\";\r\n\t\tthis.#host.data.setValue(row, bindKey, v, updateRowState);\r\n\t}\r\n\r\n\tget row() {\r\n\t\treturn parseInt(this.#cell?.dataset?.row, 10);\r\n\t}\r\n\tget index() {\r\n\t\treturn parseInt(this.#cell?.dataset?.index, 10);\r\n\t}\r\n\r\n\tgetDisplayText = (defaultValue = \"\") => {\r\n\r\n\t\ttrace.log(\"=================================\");\r\n\t\tif (!this.#cell || !this.#cell.closest(\"tbody\")) return defaultValue;\r\n\r\n\t\tconst rawRecord = this.#tr.data;\r\n\r\n\t\ttrace.log(\"==============================\", rawRecord);\r\n\r\n\t\tif (!rawRecord) return defaultValue;\r\n\r\n\t\tconst expr = this.#cell.dataset.expr;\r\n\t\tconst bindKey = this.#cell.dataset.bind;\r\n\t\tconst row = parseInt(this.#cell.dataset.row, 10);\r\n\r\n\t\tif (expr) {\r\n\t\t\ttry {\r\n\t\t\t\tif (this.#tr.getAttribute(\"grouping\") === \"true\") {\r\n\t\t\t\t\t// 💡 상수가 정의되어 있다면 GROUP_IDX.ID 로 고유 ID 추출 (아니면 배열 인덱스 직접 참조)\r\n\t\t\t\t\t// 배열 구조체인 경우: rawRecord[0]이 groupId임\r\n\t\t\t\t\t//const groupId = Array.isArray(rawRecord) ? rawRecord[0] : (rawRecord.__ng?.id || rawRecord.m?.id);\r\n\r\n\t\t\t\t\t// 💡 매니저를 통해 해당 그룹의 자식 레코드 목록을 O(1)로 획득\r\n\t\t\t\t\t//const childRecords = this.#sheet.grouping.getChildrenRecords(\"g_0\");\r\n\t\t\t\t\t//trace.log(\"--========\", childRecords);\r\n\t\t\t\t\t// 그룹 전용 표현식 계산 메서드 호출\r\n\t\t\t\t\t//return \"\";//this.getGroupExprValue(expr, childRecords, row, this.#cell);\r\n\r\n\t\t\t\t\t//trace.log(this, this.#cell.dataset.bind);\r\n\t\t\t\t\t//return \"x\";//this.data.length;\r\n\t\t\t\t\treturn this.getGroupExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn this.#host.exprEngine.evaluate(expr, this.#tr.data, row);\r\n\r\n\t\t\t\t\t//return this.getExprValue(expr, this.#tr.data, row, this.#cell);\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\tconsole.trace(e);\r\n\t\t\t\t//console.error(\"Expr evaluation error:\", expr, e);\r\n\t\t\t\treturn defaultValue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\ttrace.log(\"==============================\", bindKey, this.value);\r\n\r\n\t\tif (bindKey) {\r\n\t\t\tconst val = this.value; // 직통 읽기\r\n\t\t\treturn val !== null && val !== undefined ? val : defaultValue;\r\n\t\t}\r\n\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\r\n\r\n\trefresh() {\r\n\r\n\t\tif (!this.#cell || !this.#tr) return;\r\n\r\n\t\tconst val = this.value; // 원시 배열 직통 조회\r\n\r\n\t\t[\"color\",\"background\",\"background-color\",\"class\",\"visible\",\"enable\"].forEach(v => {\r\n\t\t\tconst expr = this.#attr[v];\r\n\t\t\tif (expr) {\r\n\t\t\t\tconst result = this.#host.exprEngine.evaluate(expr, this.#tr.data, parseInt(this.#cell.dataset.row, 10));\r\n\r\n\t\t\t\tif (v === \"visible\") {\r\n\t\t\t\t\tthis.style[\"display\"] = result ? \"\" : \"none\";\r\n\t\t\t\t} else if (v === \"enable\") {\r\n\t\t\t\t\t// 💡 enable이 false면 비활성화(disabled = true), true면 활성화(disabled = false)\r\n\t\t\t\t\t//const isEnabled = !!result;\r\n\r\n\t\t\t\t\tthis.querySelectorAll(\"input, button, textarea, select\").forEach($el => {\r\n\t\t\t\t\t\t$el.disabled = !result;\r\n\t\t\t\t\t});\r\n\r\n\r\n\t\t\t\t\tif (!!result) {\r\n\t\t\t\t\t\tthis.#cell.removeAttribute(\"disabled\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.#cell.setAttribute(\"disabled\", \"true\");\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.#cell.style[v] = result;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn val;\r\n\t}\r\n\r\n\tgetExprValue(expr, data, row) {\r\n\t\t//trace.log(\"********************************************\", expr, data, row);\r\n\r\n\t\treturn this.#host.exprEngine.evaluate(expr, data, row);\r\n\r\n\r\n\t\tif (expr === undefined) return expr;\r\n\t\tconsole.trace(\"********************************************\");\r\ntrace.log(\"********************************************\", expr);\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst trimmedExpr = expr.trim();\r\n\t\t\t//const fields = this.#host?.fields;\r\n\r\n\t\t\t// 🎯 1. 데이터가 원시 배열 구조인 경우 표현식 내부의 필드명을 인덱스로 자동 치환\r\n\t\t\t//const isRawArray = data && typeof data === 'object' && Array.isArray(data.v);\r\n\t\t\t//const compiledExpr = isRawArray ? this.#rewriteExpr(trimmedExpr, fields) : trimmedExpr;\r\n\t\t\t//trace.log(compiledExpr);\r\n\t\t\t// 2. 함수 호출식인 경우 (예: oppositeColor(...))\r\n\t\t\t//const match = trimmedExpr.match(/^([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\tconst match = trimmedExpr.match(/(?:[a-zA-Z_$][\\w$]*\\.)*([a-zA-Z_$][\\w$]*)\\s*\\(/);\r\n\t\t\t//trace.log(trimmedExpr, match);\r\n\t\t\tif (match) {\r\n\t\t\t\tconst fnName = match[1].replace(\"host.\", \"\");\r\n\t\t\t\t//trace.log(fnName);\r\n\t\t\t\tif (this.#host && typeof this.#host[fnName] === 'function') {\r\n\r\n\t\t\t\t\tlet evalFn = hostFuncCache.get(trimmedExpr);\r\n\r\n\t\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\t\tconst openIdx = trimmedExpr.indexOf('(');\r\n\t\t\t\t\t\tconst closeIdx = trimmedExpr.lastIndexOf(')');\r\n\t\t\t\t\t\tconst argsString = (openIdx !== -1 && closeIdx !== -1) ? trimmedExpr.substring(openIdx + 1, closeIdx) : \"\";\r\n\r\n\t\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', 'host', `\r\n\t\t\t\t\t\t try {\r\n\t\t\t\t\t\t const data = rowItem;\r\n\t\t\t\t\t\t //console.log(data);\r\n\t\t\t\t\t\t \r\n\t\t\t\t\t\t //if (!data) return \"\";\r\n\t\t\t\t\t\t return host.${fnName}.call(host, ${argsString});\r\n\t\t\t\t\t\t } catch (err) {\r\n\t\t\t\t\t\t console.error(\"Expr eval error:\", err);\r\n\t\t\t\t\t\t return \"\";\r\n\t\t\t\t\t\t }\r\n\t\t\t\t\t `);\r\n\r\n\t\t\t\t\t\thostFuncCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn evalFn(data, row, cell, this.#host);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//trace.log(trimmedExpr);\r\n\t\t\t// 3. 일반 연산식인 경우 (예: data.v[0] + ' vs ' + data.v[1])\r\n\t\t\tif (trimmedExpr.includes(\"data.\") || trimmedExpr.includes(\"rowItem.v\") || trimmedExpr.includes(\"(\")) {\r\n\t\t\t\t//trace.log(\"=========================\")\r\n\t\t\t\tlet evalFn = exprCache.get(trimmedExpr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('rowItem', 'row', 'cell', `\r\n const data = rowItem;\r\n\r\n if (!data) return \"\";\r\n return ${trimmedExpr};\r\n `);\r\n\t\t\t\t\texprCache.set(trimmedExpr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(data, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\treturn trimmedExpr;\r\n\t\t} catch (e) {\r\n\t\t\treturn [\"NG-COMBO\"].includes(this.tagName) ? \"\" : expr;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * 🎯 [신규] 그룹 행의 자식 데이터 목록(childRecords)을 기반으로 합계/평균/개수 등을 처리하는 메서드\r\n\t */\r\n\tgetGroupExprValue = (expr, groupRecord, row, cell) => {\r\n\t\tif (!expr) return \"\";\r\n\r\n\t\ttry {\r\n\t\t\trow = parseInt(row, 10);\r\n\t\t\tconst cleanExpr = expr.replace(\"()\", \"\").trim();\r\n\r\n\t\t\t// 1. 호스트(컴포넌트)에 정의된 그룹 전용 커스텀 메서드가 있는 경우 우선 위임\r\n\t\t\tif (this.#host && typeof this.#host[cleanExpr] === 'function') {\r\n\t\t\t\treturn this.#host[cleanExpr].call(this, groupRecord, row, cell);\r\n\t\t\t}\r\n\r\n\t\t\t// 2. 기본 내장 집계 함수 파싱 처리 (예: sum(price), count(), avg(score) 등)\r\n\t\t\tconst match = cleanExpr.match(/^(\\w+)\\s*\\(\\s*([\\w\\-]*)\\s*\\)/);\r\n\t\t\tif (match) {\r\n\t\t\t\t// 💡 groupRecord에서 자식 레코드 목록 안전하게 추출 (indices 배열 -> 실제 레코드 매핑)\r\n\t\t\t\tconst indices = groupRecord[GROUP_IDX.CHILDREN];\r\n\t\t\t\tconst allRecords = this.#host?.data?.getArray ? this.#host.data.getArray() : [];\r\n\t\t\t\tconst childRecords = indices ? indices.map(idx => allRecords[idx]).filter(Boolean) : [];\r\n\r\n\t\t\t\tconst [, funcName, field] = match;\r\n\t\t\t\tconst host = this.#host;\r\n\r\n\t\t\t\tswitch (funcName.toLowerCase()) {\r\n\t\t\t\t\tcase 'count':\r\n\t\t\t\t\t\treturn childRecords.length;\r\n\r\n\t\t\t\t\tcase 'sum': {\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\treturn childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tcase 'avg': {\r\n\t\t\t\t\t\tif (childRecords.length === 0) return 0;\r\n\t\t\t\t\t\tconst colIdx = host?.fields?.indexOf?.(field) ?? -1;\r\n\t\t\t\t\t\tconst sum = childRecords.reduce((acc, record) => {\r\n\t\t\t\t\t\t\tconst val = colIdx >= 0 ? record.v?.[colIdx] : record[field];\r\n\t\t\t\t\t\t\treturn acc + (Number(val) || 0);\r\n\t\t\t\t\t\t}, 0);\r\n\t\t\t\t\t\treturn sum / childRecords.length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// 3. 호스트의 exprFunction 활용\r\n\t\t\tif (this.#host && typeof this.#host.exprFunction === 'function') {\r\n\t\t\t\treturn this.#host.exprFunction(expr).call(this, groupRecord, row, this.#host.data);\r\n\t\t\t}\r\n\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (예: \"childRecords.reduce(...)\")\r\n\t\t\t// groupRecord 자체나 내부 자식들을 활용하는 표현식 문자열 처리\r\n\t\t\t// 4. 💡 캐싱을 적용한 그룹 동적 표현식 평가 (안전성 강화 버전)\r\n\t\t\tif (expr.includes(\"data.\") || expr.includes(\"childRecords\") || expr.includes(\"groupRecord\")) {\r\n\t\t\t\tlet evalFn = exprCache.get(\"grp_\" + expr);\r\n\t\t\t\tif (!evalFn) {\r\n\t\t\t\t\tevalFn = new Function('groupRecord', 'row', 'cell', 'host', `\r\n const indices = groupRecord[3]; // GROUP_IDX.CHILDREN = 3\r\n const allRecords = host?.data?.getArray ? host.data.getArray() : [];\r\n \r\n let childRecords = [];\r\n if (Array.isArray(indices)) {\r\n // indices가 숫자 인덱스 배열인지, rowid 문자열 배열인지 판별하여 안전하게 추출\r\n childRecords = indices.map(idx => {\r\n if (typeof idx === 'number') {\r\n return allRecords[idx];\r\n } else {\r\n // rowid 등 문자열 식별자인 경우 전체 배열에서 찾거나 dataManager 활용\r\n return allRecords.find(r => r?.__ng?.rowid === idx || r?.m?._?.[0] === idx);\r\n }\r\n }).filter(Boolean);\r\n }\r\n \r\n // 만약 위에서 못 찾았는데 host.grouping을 쓸 수 있다면 매니저 위임 시도\r\n if (childRecords.length === 0 && host?.grouping?.getChildrenRecords && groupRecord[0]) {\r\n childRecords = host.grouping.getChildrenRecords(groupRecord[0]);\r\n }\r\n\r\n const data = childRecords; // data.length 등을 쓸 수 있도록 호환\r\n return ${expr};\r\n `);\r\n\t\t\t\t\texprCache.set(\"grp_\" + expr, evalFn);\r\n\t\t\t\t}\r\n\t\t\t\treturn evalFn(groupRecord, row, cell, this.#host);\r\n\t\t\t}\r\n\r\n\t\t\treturn expr;\r\n\t\t} catch (e) {\r\n\t\t\tconsole.error(\"Group expr evaluation error:\", expr, e);\r\n\t\t\treturn expr;\r\n\t\t}\r\n\t};\r\n}\r\n\r\nexport class EditableCellElement extends CellElement {\r\n\r\n\tget host() { return super.host; }\r\n\tget sheet() { return super.sheet; }\r\n\tget cell() { return super.cell; }\r\n\tget tr() { return super.tr; }\r\n\tget attr() { return super.attr; }\r\n\r\n\tgetExprValue(expr, data, row, cell) {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n\r\n\tconstructor() {\r\n\t\tsuper();\r\n\t}\r\n\r\n\tconnectedCallback() {\r\n\t\tsuper.connectedCallback();\r\n\r\n\t\t/**\r\n\t\tthis.querySelectorAll(\"input, textarea\").forEach($el => {\r\n\t\t\t$el.addEventListener(\"change\", (event) => {\r\n\t\t\t\tif (!this.closest(\"tbody\")) return;\r\n\r\n\t\t\t\tconst target = event.target;\r\n\t\t\t\tconst inputType = target.getAttribute('type');\r\n\r\n\t\t\t\tif (inputType === \"checkbox\") {\r\n\t\t\t\t\tconst trueVal = super.attr[\"true-value\"] || \"Y\";\r\n\t\t\t\t\tconst falseVal = super.attr[\"false-value\"] || \"N\";\r\n\t\t\t\t\tthis.value = target.checked ? trueVal : falseVal;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlet v = target.value;\r\n\t\t\t\t\tconst maxbyte = super.attr[\"maxbyte\"];\r\n\r\n\t\t\t\t\ttrace.log(maxbyte);\r\n\r\n\t\t\t\t\tif (maxbyte) {\r\n\t\t\t\t\t\tconst byteLen = nine.getByteLength(v);\r\n\t\t\t\t\t\tif (byteLen >= parseInt(maxbyte, 10)) {\r\n\t\t\t\t\t\t\tv = nine.cut(v, parseInt(maxbyte, 10));\r\n\t\t\t\t\t\t\ttarget.value = v;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tthis.value = this.getAttribute(\"type\") === \"number\" ? (isNaN(v) ? \"\" : Number(v)) : v;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsuper.sheet.invalidate();\r\n\t\t\t});\r\n\t\t}); */\r\n\t}\r\n\r\n\trefresh() {\r\n\t\treturn super.refresh();\r\n\t}\r\n\r\n\tgetExprValue = (expr, data, row, cell) => {\r\n\t\treturn super.getExprValue(expr, data, row, cell);\r\n\t}\r\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputText extends EditableCellElement\n{\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\t\n\tconnectedCallback() {\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#renderer();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\n\t\tthis.#initEvent();\n\t};\n\n\trefresh = () => {\n\n\t\tsuper.refresh();\n\n\t\tthis.#target.value = this.value;\n\t};\n\n\t#initEvent = () => {\n\t\tthis.#target.addEventListener(\"input\", e => {\n\t\t\tconst maxbyte = this.cell.getAttribute(\"maxbyte\") || this.cell.getAttribute(\"max-byte\");\n\n\t\t\tif (maxbyte) {\n\t\t\t\tconst maxByteNum = Number(maxbyte);\n\t\t\t\tconst currentBytes = nine.getByteLength(e.target.value);\n\n\t\t\t\tif (currentBytes > maxByteNum) {\n\t\t\t\t\te.target.value = nine.cut(e.target.value, maxByteNum);\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n\t\t\t<style>\n\t\t\t\tcell-input {\n\t\t\t\t\tinput {\n\t\t\t\t\t\tposition: relative;\n\t\t\t\t\t\t-moz-user-select: auto;\n\t\t\t\t\t\t-webkit-user-select: auto;\n\t\t\t\t\t\t-ms-user-select: auto;\n\t\t\t\t\t\tuser-select: auto;\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\theight: 26px;\n\t\t\t\t\t\tborder: 1px solid #eee;\n\t\t\t\t\t\tborder-radius: 3px;\n\t\t\t\t\t\tpadding-left: 4px;\n\t\t\t\t\t\toutline: 0;\n\t\t\t\t\t\tfont: inherit;\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\tbackground-color: white;\n\t\t\t\t\t\tcolor: #333;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tinput:read-only {\n\t\t\t\t\t\tborder-color: #fdfdfd;\n\t\t\t\t\t\tfilter: brightness(97%);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t\n\t\t\t<input type=\"text\" ondragstart=\"return false;\">\n\t\t`;\n\t};\n}\n\nif (!customElements.get('cell-input')) {\n\tcustomElements.define(\"cell-input\", CellInputText);\n}\n","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputNumber extends EditableCellElement\n{\n\t#target;\n\n\tconstructor () {\n\t\tsuper();\n\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\tthis.#target.addEventListener(\"keydown\", this.#onKeyDown);\n\n\t\t// change 대신 input 이벤트를 사용하면 색상을 고르는 즉시 바로 적용됩니다.\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tthis.value = event.target.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 만약 색상 선택 창을 닫을 때(확정할 때) 추가로 처리할 로직이 필요하다면 change에 남겨둘 수 있습니다.\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tthis.value = event.target.value;\n\t\t\t//this.#target.style.backgroundColor = this.value;\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\t/**\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t}); */\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n \t\tcell-input-number {\n\t\t\t\t\tinput[type=text].border-left-none {\n\t\t\t\t\t\t border-left: 0;\n\t\t\t\t\t\t border-top-left-radius: 0;\n\t\t\t\t\t\t border-bottom-left-radius: 0;\n\t\t\t\t\t }\n\t\t\t\t\t input[type=text].border-right-none {\n\t\t\t\t\t\t border-right: 0;\n\t\t\t\t\t\t border-top-right-radius: 0;\n\t\t\t\t\t\t border-bottom-right-radius: 0;\n\t\t\t\t\t }\n\t\t\n\t\t\t\t\t input[type=text] {\n\t\t\t\t\t\t position: relative;\n\t\t\t\t\t\t -moz-user-select: auto;\n\t\t\t\t\t\t -webkit-user-select: auto;\n\t\t\t\t\t\t -ms-user-select: auto;\n\t\t\t\t\t\t user-select: auto;\n\t\t\t\t\t\t width: 100%;\n\t\t\t\t\t\t height: 26px;\n\t\t\t\t\t\t border: 1px solid #eee;\n\t\t\t\t\t\t border-radius: 3px;\n\t\t\t\t\t\t padding-left: 4px;\n\t\t\t\t\t\t outline: 0;\n\t\t\t\t\t\t font: inherit;\n\t\t\t\t\t\t box-sizing: border-box;\n\t\t\t\t\t\t background-color: white;\n\t\t\t\t\t\t color: #333;\n\t\t\t\t\t\t text-align: right; /* 숫자는 기본적으로 우측 정렬이 어울림 */\n\t\t\t\t\t }\n\t\n\t\t\t\t\t input[type=text]:read-only {\n\t\t\t\t\t\t border-color: #fdfdfd;\n\t\t\t\t\t\t filter: brightness(97%);\n\t\t\t\t\t }\n \t\t}\n </style>\n\n <input type=\"text\" ${attr.join(\" \")} ondragstart=\"return false;\">\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tthis.#target.value = v !== undefined && v !== null ? v : \"\";\n\t\t\tthis.#validateInput(this.#target.value);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\n\t\tif (!this.#target) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tconst num = Number(val);\n\t\t\tif (isNaN(num) ||\n\t\t\t\t(super.attr.max !== null && super.attr.max !== undefined && num > Number(super.attr.max)) ||\n\t\t\t\t(super.attr.min !== null && super.attr.min !== undefined && num < Number(super.attr.min))\n\t\t\t) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t\telse if (super.attr.scale !== null && super.attr.scale !== undefined) {\n\t\t\t\tconst strVal = String(val);\n\t\t\t\tconst dotIdx = strVal.indexOf('.');\n\t\t\t\tif (dotIdx >= 0 && strVal.substring(dotIdx + 1).length > Number(super.attr.scale)) {\n\t\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t#onKeyDown = e => {\n\n\t\tif ([\"Escape\", \"Enter\", \"Tab\", \"Home\", \"End\", \"ArrowLeft\", \"ArrowRight\", \"PageUp\", \"PageDown\", \"Backspace\", \"Delete\"].includes(e.code)) return;\n\n\t\tconst target = e.target;\n\t\tconst value = target.value;\n\t\tconst selectionStart = target.selectionStart;\n\t\tconst selectionEnd = target.selectionEnd;\n\t\tconst key = e.key;\n\n\t\tif (key === \"-\") {\n\t\t\t// 이미 마이너스가 존재하거나, 커서가 맨 앞(0)이 아니면 차단 (중간이나 끝에 입력 방지)\n\t\t\tif (value.includes(\"-\") || selectionStart !== 0) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (key === \".\") {\n\t\t\tconst scale = Number(super.attr.scale);\n\t\t\t// scale이 설정되지 않았거나(0 이하), 이미 소수점이 존재하면 차단\n\t\t\tif (isNaN(scale) || scale <= 0 || value.includes(\".\")) {\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// 마이너스만 있는 상태(\"-\")에서 바로 소수점이 찍히는 것(-.)을 막으려면 아래 조건 추가 가능\n\t\t\t// if (value === \"-\" && selectionStart === 1) { e.preventDefault(); return; }\n\t\t}\n\n\t\tlet validKey = [];\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && Number(super.attr.scale) > 0) validKey.push(\".\");\n\t\tif (super.attr.min === null || super.attr.min === undefined || Number(super.attr.min) > 0) validKey.push(\"-\");\n\n\t\t// 숫자 키패드 및 상단 숫자 키 허용 + 소수점/마이너스 허용\n\t\tconst isNumKey = (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105);\n\n\t\tif (!isNumKey && !validKey.includes(e.key)) {\n\t\t\te.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\t// 소수점 자리수(scale) 제한 체크\n\t\tif (super.attr.scale !== null && super.attr.scale !== undefined && isNumKey && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\tconst s = e.target.value;\n\t\t\tconst idx = s.indexOf(\".\");\n\t\t\tif (idx >= 0 && e.target.selectionStart > idx) {\n\t\t\t\tconst decimalPart = s.substr(idx + 1);\n\t\t\t\tif (decimalPart.length >= Number(super.attr.scale)) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (super.attr.maxbyte && nine.getByteLength(e.target.value) >= Number(super.attr.maxbyte) && e.target.selectionStart == e.target.selectionEnd) {\n\t\t\te.preventDefault();\n\t\t}\n\t}\n}\n\nif (!customElements.get('cell-input-number')) {\n\tcustomElements.define(\"cell-input-number\", CellInputNumber);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputColor extends EditableCellElement\n{\n\t#target;\n\t#btn;\n\n\tconstructor () {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"input[type=color]\");\n\t\tthis.#btn = this.querySelector(\"button\");\n\t\tif (!this.#target) return;\n\n\t\t// 버튼 클릭 시 컬러 input을 프로그래밍 방식으로 클릭하여 팝업 오픈\n\t\tif (this.#btn) {\n\t\t\tthis.#btn.addEventListener(\"click\", () => {\n\t\t\t\tthis.#target.click();\n\t\t\t});\n\t\t}\n\n\t\t// 색상 변경 즉시 반영\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\tthis.#target.click();\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\n\t\tvar attr = [];\n\t\tfor (var i = 0; i < this.attributes.length; i++) {\n\t\t\tif ([\"type\", \"maxlength\", \"maxbyte\", \"min\", \"max\", \"step\", \"scale\", \"text-align\"].includes(this.attributes[i].name)) {\n\t\t\t\t//attr.push(`${this.attributes[i].name}=\"${this.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-color {\n --position: relative;\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-color.invalid button {\n padding: 2px;\n }\n cell-input-color.invalid button:after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-input-color input[type=color] {\n width: 100%;\n height: 26px;\n padding: 0px;\n margin-left: unset;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-color: transparent;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color input[type=color]::-webkit-color-swatch {\n border: 0;\n border-top-left-radius: 2px;\n border-bottom-left-radius: 2px;\n }\n cell-input-color input[type=color]::-webkit-color-swatch-wrapper {\n padding: 1px;\n }\n\n cell-input-color button {\n display: inline-flex;\n width: 24px;\n height: 26px;\n margin-right: unset;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n justify-content: center;\n align-items: center;\n cursor: pointer;\n box-sizing: border-box;\n }\n cell-input-color button:after {\n content: \"\";\n border-top: 0.3em solid #333;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n cell-input-color input[type=color]:hover {\n filter: brightness(90%);\n }\n cell-input-color button:hover {\n filter: brightness(95%);\n }\n \n .CELL-INPUT-COLOR {\n \n }\n </style>\n\n <input type=\"color\" ${attr.join(\" \")} ondragstart=\"return false;\">\n <button tabindex=\"-1\" type=\"button\"></button>\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (this.#target) {\n\t\t\tconst val = v !== undefined && v !== null && v !== \"\" ? v : \"#ffffff\";\n\t\t\tthis.#target.value = val;\n\t\t\tthis.#validateInput(val);\n\t\t}\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\t\tthis.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tif (!this.#isValidColor(val)) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tthis.classList.add(\"invalid\");\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidColor = (v) => {\n\t\tif (typeof v !== \"string\" || v.length != 7 || !v.startsWith(\"#\")) return false;\n\n\t\tvar r = parseInt(v.substr(1, 2), 16);\n\t\tvar g = parseInt(v.substr(3, 2), 16);\n\t\tvar b = parseInt(v.substr(5, 2), 16);\n\n\t\tif (isNaN(r) || isNaN(g) || isNaN(b)) return false;\n\t\tif (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) return false;\n\n\t\treturn true;\n\t}\n}\n\nif (!customElements.get('cell-input-color')) {\n\tcustomElements.define(\"cell-input-color\", CellInputColor);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\n\nclass CellInputDate extends EditableCellElement\n{\n\t#target;\n\t#type;\n\n\tconstructor () {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\n\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\t\tthis.#type = super.attr[\"date-type\"] || \"date\";//this.getAttribute(\"date-type\") || \"date\";\n\t\tif (![\"date\",\"datetime-local\",\"time\",\"week\",\"month\"].includes(this.#type)) {\n\t\t\tthrow `invalid type : ${this.#type}`;\n\t\t}\n\n\t\tthis.#target = this.querySelector(\"input\");\n\t\tif (!this.#target) return;\n\n\t\t// 값 변경 시 즉시 반영 및 검증\n\t\tthis.#target.addEventListener(\"input\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#target.classList.toggle(\"has-value\", !!val); // 💡 실시간 반영\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\tthis.#target.addEventListener(\"change\", (event) => {\n\t\t\tconst val = event.target.value;\n\t\t\tthis.value = val;\n\t\t\tthis.#validateInput(val);\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\n\t\t// 키보드 네비게이션 제어\n\t\tthis.#target.addEventListener(\"keydown\", e => {\n\t\t\tif ([\"Enter\"].includes(e.code)) {\n\t\t\t\t// 필요 시 추가 동작\n\t\t\t}\n\t\t\telse if ([\"Escape\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t}\n\t\t\telse if ([\"Tab\", \"PageUp\", \"PageDown\", \"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"].includes(e.code)) {\n\t\t\t\tthis.owner.cell.currentCell = this.cell;\n\t\t\t\tthis.owner.cell.moveCell(e);\n\t\t\t}\n\t\t});\n\t};\n\n\t#renderer = () => {\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst height = parseInt(this.closest(\"tr\")?.style.height || \"26\", 10) - 1;\n\n\t\tlet attr = [];\n\t\tfor (var i = 0; i < cell.attributes.length; i++) {\n\t\t\tif ([\"value\", \"max\", \"min\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t//if ([\"value\", \"step\"].includes(cell.attributes[i].name)) {\n\t\t\t\tattr.push(`${cell.attributes[i].name}=\"${cell.attributes[i].value}\"`);\n\t\t\t}\n\t\t}\n\n\t\tthis.innerHTML = `\n <style>\n cell-input-date {\n height: 100%;\n --width: calc(100% - 8px);\n width: 100%;\n display: flex;\n align-items: center;\n --margin-left: 4px;\n --margin-right: 4px;\n box-sizing: border-box;\n }\n\n cell-input-date input {\n position: relative;\n height: 26px;\n padding: 0;\n margin: 0;\n font: inherit;\n width: 100%;\n padding-left: 4px;\n border: 1px solid #f0f0f0;\n border-radius: 3px;\n outline: 0;\n background-color: transparent;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"black\" viewBox=\"0 0 16 16\"><path d=\"M11 7.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z\"/><path d=\"M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M2 2a1 1 0 0 0-1 1v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1z\"/><path d=\"M2.5 4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5z\"/></svg>');\n background-repeat: no-repeat;\n background-position: right 2px center;\n background-size: 14px auto;\n color: #333;\n box-sizing: border-box;\n }\n\n cell-input-date input:hover {\n filter: brightness(95%);\n }\n \n cell-input-date input::-webkit-calendar-picker-indicator {\n position: absolute;\n right: 0;\n top: 0;\n width: 16px;\n height: 100%;\n background: transparent;\n --color: transparent;\n cursor: pointer;\n \t--opacity: 0.3;\n \t--filter: brightness(80%);\n }\n \n\t\t\t\n\t\t\t\n cell-input-date input::before {\n content: attr(data-placeholder);\n position: absolute;\n display: flex;\n align-items: center;\n width: calc(100% - 22px);\n height: 100%;\n background-color: white;\n left: 1px;\n top: 1px;\n pointer-events: none;\n }\n\n cell-input-date input.has-value::before,\n cell-input-date input:focus::before {\n display: none;\n }\n\n cell-input-date input:focus {\n border: 1px solid #28a745;\n border-radius: 3px;\n }\n \n \n </style>\n\n <input\n type=\"${cell.getAttribute('date-type') || 'date'}\"\n data-placeholder=\"${cell.getAttribute('placeholder') || 'Select'}\"\n ${attr.join(\" \")}\n required\n />\n `;\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\n\t\tif (!this.#target) return v;\n\n\t\tlet formattedVal = v;\n\t\tif (formattedVal) {\n\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"date\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tformattedVal = formattedVal.substr(0, 16);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"time\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"00\" + d.getHours()).slice(-2) + \":\" + (\"00\" + d.getMinutes()).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar d = new Date(v);\n\t\t\t\t\tif (d != \"Invalid Date\" && !isNaN(d)) {\n\t\t\t\t\t\tformattedVal = (\"0000\" + d.getFullYear()).slice(-4) + \"-\" + (\"00\" + (d.getMonth() + 1)).slice(-2);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//trace.log(this.#type, formattedVal);\n\n\t\tthis.#target.value = formattedVal || \"\";\n\t\tthis.#target.classList.toggle(\"has-value\", !!formattedVal); // 💡 값이 있으면 클래스 추가\n\t\tthis.#validateInput(formattedVal);\n\n\t\treturn v;\n\t};\n\n\t#validateInput = (val) => {\n\t\tif (!this.#target || !super.cell) return;\n\n\t\tconst cell = this.closest(\"th,td\");\n\t\tconst min = cell?.getAttribute(\"min\");\n\t\tconst max = cell?.getAttribute(\"max\");\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (val !== \"\" && val !== null && val !== undefined) {\n\t\t\tlet isValid = this.#isValidDate(val);\n\n\t\t\t// 💡 형식 검증을 통과했더라도 min/max 범위를 벗어났다면 invalid 처리\n\t\t\tif (isValid) {\n\t\t\t\tif (min && val < min) isValid = false;\n\t\t\t\tif (max && val > max) isValid = false;\n\t\t\t}\n\n\t\t\tif (!isValid) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t}\n\t\t}\n\t};\n\n\t#isValidDate = (v) => {\n\t\t//if (ninegrid.isNull(v)) return true;\n\t\tif (typeof v !== \"string\") return false;\n\n\t\tlet isValid = true;\n\n\t\tswitch (this.#type) {\n\t\t\tcase \"date\":\n\t\t\tcase \"datetime-local\":\n\t\t\t\tconst year = Number(v.substr(0, 4));\n\t\t\t\tconst month = Number(v.substr(5, 2));\n\t\t\t\tconst day = Number(v.substr(8, 2));\n\n\t\t\t\tif (isNaN(year) || isNaN(month) || isNaN(day)) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month < 1 || month > 12 || day < 1 || day > 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if ([4, 6, 9, 11].includes(month) && day == 31) {\n\t\t\t\t\tisValid = false;\n\t\t\t\t} else if (month == 2) {\n\t\t\t\t\tlet isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));\n\t\t\t\t\tif (day > 29 || (day == 29 && !isleap)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (isValid) {\n\t\t\tswitch (this.#type) {\n\t\t\t\tcase \"datetime-local\":\n\t\t\t\t\tvar t = v.substr(10, 1);\n\t\t\t\t\tvar hour = Number(v.substr(11, 2));\n\t\t\t\t\tvar min = Number(v.substr(14, 2));\n\n\t\t\t\t\tif (t != \"T\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(hour) || isNaN(min)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (hour < 0 || hour > 23 || min < 0 || min > 59) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"month\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar month = Number(v.substr(5, 2));\n\n\t\t\t\t\tif (isNaN(year) || isNaN(month)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (month < 1 || month > 12) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"week\":\n\t\t\t\t\tvar year = Number(v.substr(0, 4));\n\t\t\t\t\tvar w = v.substr(5, 1);\n\t\t\t\t\tvar week = Number(v.substr(6, 2));\n\n\t\t\t\t\tif (w != \"W\") {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (isNaN(year) || isNaN(week)) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t} else if (week <= 0 || week > 53) {\n\t\t\t\t\t\tisValid = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn isValid;\n\t}\n}\n\nif (!customElements.get('cell-input-date')) {\n\tcustomElements.define(\"cell-input-date\", CellInputDate);\n}","import { EditableCellElement } from \"./core/CellElement.js\";\nimport {trace} from \"@nopeer\";\n\nclass CellCheckbox extends EditableCellElement {\n #target;\n #label;\n #isRadio;\n #trueText;\n #falseText;\n\n constructor() {\n super();\n\n\n }\n\n connectedCallback() {\n this.#renderer();\n\n super.connectedCallback();\n\n this.#init();\n }\n\n get trueValue() {\n return super.attr[\"true-value\"] || \"Y\";\n }\n get falseValue() {\n return super.attr[\"false-value\"] || \"N\";\n }\n\n get dataSource() {\n return [\n { value: this.trueValue, text: this.#trueText },\n { value: this.falseValue, text: this.#falseText }\n ];\n }\n\n #init = () => {\n this.#target = this.querySelector(\"input\");\n this.#label = this.querySelector(\"span\");\n\n this.#trueText = super.attr[\"true-text\"] || \"\";\n this.#falseText = super.attr[\"false-text\"] || \"\";\n //this.#isRadio = super.attr[\"is-radio\"] || false;\n\n // 헤더에 있는 체크박스인 경우 (전체 선택/해제 기능)\n if (this.closest(\"thead\")) {\n this.#target.addEventListener(\"change\", (e) => {\n super.sheet.querySelector(`tbody.body [data-col=\"${super.cell.dataset.col}\"] cell-checkbox`)?.selectAll(e.target.checked);\n });\n }\n\n // 스페이스바 입력 시 값 토글 처리\n this.cell?.addEventListener(\"keydown\", (e) => {\n\n e.preventDefault();\n\n if (e.code === \"Space\") return;\n if (this.closest(\"thead\")) return; // 헤더는 제외\n if (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n if (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\n //this.value = newVal;\n if (this.#isRadio) {\n this.selectAll(false);\n }\n\n this.value = newVal;\n\n super.sheet.invalidate();\n });\n\n\n this.#target.addEventListener(\"change\", (event) => {\n if (!this.closest(\"tbody\")) return;\n\n //const newVal = this.value === this.trueValue ? this.falseValue : this.trueValue;\n if (this.#isRadio) {\n this.selectAll(false);\n this.value = this.trueValue;\n }\n else {\n this.value = event.target.checked ? this.trueValue : this.falseValue;\n }\n\n super.sheet.rowManager.refresh(true);\n //super.sheet.invalidate();\n });\n }\n\n #renderer = () => {\n\n const $cell = this.closest(\"th,td\");\n\n this.#isRadio = $cell?.getAttribute(\"is-radio\") || false;\n\n const trueValue = $cell?.getAttribute(\"true-value\") || false;\n //const selectedBorderColor = this.getAttribute(\"selected-border-color\") || \"dimgray\";\n\n const originalContent = $cell?.getAttribute(\"content\") || \"\";\n const childHtml = this.#isRadio ? `<input type=\"radio\" value=\"${trueValue}\" />` : `<label><input type=\"checkbox\" /><span>${originalContent}</span></label>`;\n\n // 🎯 div.ng-wrap 없이 cell-checkbox(Host) 자체를 플렉스 컨테이너로 활용하여 중앙정렬 보장\n this.innerHTML = `\n <style>\n .CELL-CHECKBOX {\n cell-checkbox {\n justify-content: center;\n }\n label {\n display: flex;\n }\n input {\n background-color: #ffffff;\n }\n \n \n /* 라디오 버튼 스타일 */\n input[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n .CELL-CHECKBOX[text-align='left'] {\n cell-checkbox {\n justify-content: flex-start;\n }\n }\n .CELL-CHECKBOX[text-align='center'] {\n cell-checkbox {\n justify-content: center;\n }\n }\n .CELL-CHECKBOX[text-align='right'] {\n cell-checkbox {\n justify-content: flex-end;\n }\n label {\n flex-direction: row-reverse;\n }\n }\n \n \n \n cell-checkbox {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n }\n cell-checkbox label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n cursor: pointer;\n user-select: none;\n }\n cell-checkbox input {\n outline: none;\n }\n \n </style>\n ${childHtml}\n `;\n }\n\n refresh = () => {\n const val = super.refresh(); // CellElement의 원시값 직통 조회 활용\n\n if (!this.closest(\"tbody\") && !this.closest(\"thead\")) return val;\n\n // 체크박스 상태 동기화\n if (this.#target) {\n this.#target.checked = (val === this.trueValue);\n this.#validateInput(val);\n }\n\n // 라벨 텍스트 동기화\n if (this.#label) {\n const displayText = (val === this.trueValue) ? this.#trueText : ((val === this.falseValue) ? this.#falseText : val);\n this.#label.textContent = displayText;\n }\n\n return val;\n };\n\n #validateInput = (val) => {\n\n if (!this.#target) return;\n\n super.cell.classList.remove(\"invalid\");\n\n if (val !== \"\" && val !== null && val !== undefined) {\n if (val !== this.trueValue && val !== this.falseValue) {\n super.cell.classList.add(\"invalid\");\n }\n }\n };\n\n selectAll = (v) => {\n if (this.closest(\"thead\")) return; // 헤더 자신은 제외\n\n const data = super.host.data.getArray();\n const colIndex = super.host.fields.indexOf(super.cell.dataset.bind);\n\n if (colIndex < 0) return;\n\n for (let i = 0; i < data.length; i++) {\n if (super.attr.enable && super.getExprValue(super.attr.enable, data[i], i, super.cell) === false) continue;\n if (super.attr.readonly && super.getExprValue(super.attr.readonly, data[i], i, super.cell) === true) continue;\n if (super.attr.visible && super.getExprValue(super.attr.visible, data[i], i, super.cell) === false) continue;\n\n data[i].v[colIndex] = v ? this.trueValue : this.falseValue;\n }\n\n super.sheet.invalidate();\n };\n}\n\nif (!customElements.get('cell-checkbox')) {\n customElements.define(\"cell-checkbox\", CellCheckbox);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport {NINE_TABLE} from \"@\";\n\nclass CellRadio extends EditableCellElement {\n\t#target;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\n\t#host;\n\t#sheet;\n\t#cell;\n\t#tr;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#keyName = this.closest(\"th,td\").getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = this.closest(\"th,td\").getAttribute(\"value-name\") || \"v\";\n\n\t\tthis.#renderer();\n\n\t\tsuper.connectedCallback();\n\n\n\n\t\tthis.#rendererRadio();\n\n\t\tthis.#initEvent();\n\n\t\t// 3. 사용자 인터랙션 (스페이스바로 라디오 순회 변경)\n\n\t}\n\n\t#initEvent = () => {\n\t\tsuper.cell.addEventListener(\"keydown\", e => {\n\n\t\t\te.preventDefault();\n\n\t\t\tif (e.code !== \"Space\") return;\n\t\t\tif (this.cell.hasAttribute(\"readonly\") || this.cell.classList.contains(\"readonly\")) return;\n\t\t\tif (this.cell.getAttribute(\"disabled\") === \"true\") return;\n\n\t\t\tlet matchIndex = -1;\n\n\t\t\tconst targets = Array.from(this.querySelectorAll(\"input\"));\n\t\t\ttargets.forEach(($el,index) => {\n\t\t\t\tif (this.value === $el.getAttribute(\"value\")) {\n\t\t\t\t\tmatchIndex = index;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tmatchIndex = (matchIndex === targets.length - 1) ? 0 : (matchIndex >= 0 ? matchIndex + 1 : 0);\n\t\t\tthis.value = targets[matchIndex].getAttribute(\"value\");\n\n\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t});\n\t};\n\n\t#rendererRadio = () => {\n\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\ttrace.log(\"==============================================\");\n\t\ttrace.log(this.sheet, this.#dataSource);\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(\"1111\");\n\t\t}, 300)\n\n\t\tthis.#target.replaceChildren();\n\n\t\tif (this.#dataSource && Array.isArray(this.#dataSource)) {\n\n\t\t\tconst fragment = document.createDocumentFragment();\n\n\t\t\tthis.#dataSource.forEach(v => {\n\t\t\t\tconst codeVal = v[this.#keyName] !== undefined ? v[this.#keyName] : '';\n\t\t\t\tconst nameVal = v[this.#valueName] !== undefined ? v[this.#valueName] : '';\n\n\t\t\t\t// <label> 생성\n\t\t\t\tconst label = document.createElement('label');\n\n\t\t\t\t// <input type=\"radio\" value=\"...\"> 생성\n\t\t\t\tconst input = document.createElement('input');\n\t\t\t\tinput.type = 'radio';\n\t\t\t\tinput.value = codeVal;\n\n\t\t\t\t// <span>텍스트</span> 생성 (textContent를 써야 XSS 방어 및 안전합니다)\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = nameVal;\n\n\t\t\t\t// 조립\n\t\t\t\tlabel.appendChild(input);\n\t\t\t\tlabel.appendChild(span);\n\t\t\t\tfragment.appendChild(label);\n\t\t\t});\n\n\t\t\tthis.#target.appendChild(fragment);\n\n\t\t\tthis.querySelectorAll(\"input\").forEach($el => {\n\t\t\t\t$el.addEventListener(\"change\", (e) => {\n\t\t\t\t\tthis.value = e.target.value;\n\t\t\t\t\tsuper.sheet.rowManager.refresh(true);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\n\t\t// 4. 마우스 클릭 시 값 변경 및 즉시 반영\n\n\t};\n\n\t#renderer = () => {\n\n\t\tthis.innerHTML = `\n <style>\n \t.CELL-RADIO {\n \t\t\tinput[type=\"radio\"] {\n appearance: none;\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background-color: #ffffff;\n border: 1px solid #9ca3af;\n border-radius: 50%; /* 동그랗게 처리 */\n outline: none;\n cursor: pointer;\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n }\n \n /* 체크(선택)되었을 때의 스타일 */\n input[type=\"radio\"]:checked {\n background-color: #ffffff;\n border-color: #2563eb;\n /* 내부의 작은 채워진 동그란 원 아이콘 */\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3.5\" cx=\"50%\" cy=\"50%\" fill=\"%232563eb\" /></svg>');\n background-repeat: no-repeat;\n background-position: center;\n }\n }\n \n \t.CELL-RADIO[text-align='left'] {\n cell-radio {\n justify-content: flex-start;\n }\n }\n .CELL-RADIO[text-align='center'] {\n cell-radio {\n justify-content: center;\n }\n }\n .CELL-RADIO[text-align='right'] {\n cell-radio {\n justify-content: flex-end;\n }\n }\n \n cell-radio {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n \n div {\n \tdisplay: flex;\n \t\t\t\t\tflex-direction: row;\n }\n }\n\n cell-radio.invalid::after {\n content: '';\n margin-left: 4px;\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n\n cell-radio input {\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n padding: 0;\n margin: 0;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border: 1px solid dimgray;\n border-radius: 50%;\n outline: 0;\n cursor: pointer;\n }\n\n cell-radio input:checked {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"14\" width=\"14\" xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"3\" cx=\"50%\" cy=\"50%\" fill=\"dimgray\" /></svg>');\n }\n\n cell-radio label {\n display: flex;\n align-items: center;\n margin-right: 8px;\n cursor: pointer;\n user-select: none;\n }\n\n cell-radio label.disabled {\n pointer-events: none;\n opacity: 0.5;\n }\n\n cell-radio span {\n margin-left: 4px;\n font-size: 12px;\n }\n </style>\n \n <div></div>\n `;\n\n\t\tthis.#target = this.querySelector(\"div\");\n\t};\n\n\trerenderer = () => {\n\t\tthis.#rendererRadio();\n\t\tthis.refresh();\n\t};\n\n\trefresh = () => {\n\n\t\tconst v = super.refresh();\n\n\t\tif (!this.#target) return v;\n\n\t\tthis.querySelectorAll(\"input\").forEach($el => {\n\t\t\t$el.checked = (this.value == $el.getAttribute(\"value\")) ? true : false;\n\t\t});\n\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst idx = this.#dataSource.findIndex(m => this.value === m[this.#keyName]);\n\t\tif (idx < 0) {\n\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-radio')) {\n\tcustomElements.define(\"cell-radio\", CellRadio);\n}","import { trace } from \"@nopeer\";\n\nexport class CellComboPanel extends HTMLElement {\n\t#parent;\n\t#keyName;\n\t#valueName;\n\t#isOpen = false;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tthis.#initEvents();\n\t}\n\n\t#initData = (dataSource, keyName, valueName, multi, separator) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource || dataSource.length === 0) return;\n\n\t\t// 1. 부모(parent)의 items 속성 확인 (예: \"CODE,NAME,DESC\" 형태)\n\t\tconst itemsAttr = this.#parent.getAttribute(\"items\");\n\t\tlet fieldKeys = [];\n\n\t\tif (itemsAttr) {\n\t\t\tfieldKeys = itemsAttr.split(\",\").map(s => s.trim());\n\t\t} else {\n\t\t\tfieldKeys = [valueName].filter(Boolean);\n\t\t}\n\n\t\tconst activeColumnCount = fieldKeys.length;\n\n\t\t// 2. 🎯 [수정] multi 모드 여부에 따라 0번 컬럼(체크박스) 가시성 제어\n\t\t//trace.log(grd.shadowRoot, grd.shadowRoot.querySelectorAll('nine-table-body table'));\n\t\tgrd.shadowRoot.querySelector(\".ng-container-left\").style.display = multi ? '' : 'none';\n\n\t\tgrd.shadowRoot.querySelectorAll('table colgroup col, tbody td').forEach(($el, idx) => {\n\t\t\ttrace.log($el);\n\n\t\t\tconst col = parseInt($el.dataset.col, 10);\n\t\t\tif (col >= 2) {\t// row-indicator, checkbox 제외\n\t\t\t\t$el.style.display = (col - 2 >= activeColumnCount) ? 'none' : '';\n\t\t\t}\n\t\t});\n\n\t\t// 3. 동적 데이터 매핑 (dataSource 원본 객체에서 fieldKeys 순서대로 tmp1 ~ tmpN에 매핑)\n\t\tconst formattedData = dataSource.map(item => {\n\t\t\tconst row = {\n\t\t\t\tCHK: \"N\",\n\t\t\t\tk: keyName && item[keyName] !== undefined ? item[keyName] : (item[0] !== undefined ? item[0] : \"\")\n\t\t\t};\n\n\t\t\tfieldKeys.forEach((key, idx) => {\n\t\t\t\trow[`tmp${idx + 1}`] = item[key] !== undefined ? item[key] : (item[idx] !== undefined ? item[idx] : \"\");\n\t\t\t});\n\t\t\treturn row;\n\t\t});\n\n\t\tgrd.data.set(formattedData);\n\n\t\t// 4. 멀티 모드일 때 기존 선택값 반영\n\t\tif (multi && this.#parent.value) {\n\t\t\tconst selectedKeys = String(this.#parent.value).split(separator || \",\");\n\t\t\tgrd.data.getValidData().forEach(m => {\n\t\t\t\tif (selectedKeys.includes(String(m.v[1]))) {\n\t\t\t\t\tm.v[0] = \"Y\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tgrd.refreshData();\n\t\t}\n\t};\n\n\topen = (parent, dataSource, keyName, valueName, multi, separator) => {\n\t\tthis.#parent = parent;\n\t\tthis.#keyName = keyName;\n\t\tthis.#valueName = valueName;\n\t\tthis.#isOpen = true;\n\n\t\ttrace.log(new Date());\n\n\t\tthis.classList.add(\"active\");\n\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tif (!grd || !dataSource) return;\n\n\t\t// 🎯 패널을 열자마자 active를 주어 레이아웃(offsetHeight) 확보 및 초기화 수행\n\n\n\t\t// 검색어 초기화 및 체크박스 기본값 설정\n\t\tthis.querySelector(\".search-input\").value = \"\";\n\t\tthis.querySelector(\"#chkAll\").checked = true;\n\n\t\t// 데이터 개수 및 모드에 따른 클래스 제어\n\t\tif (dataSource.length > 10) {\n\t\t\tthis.classList.add(\"expand\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"expand\");\n\t\t}\n\n\t\tif (multi) {\n\t\t\tthis.classList.add(\"multi\");\n\t\t} else {\n\t\t\tthis.classList.remove(\"multi\");\n\t\t}\n\n\t\t// 데이터 및 멀티컬럼 구조 초기화 실행\n\n\t\t// 🎯 [필터 패널 방식 위치 정렬 적용] 시트(sheet) 기준 상대 좌표계산\n\t\tconst sheet = parent.closest(\"nine-table-sheet\");\n\t\tconst btnEl = parent.querySelector(\".btn1\");\n\t\tif (!btnEl || !sheet) return;\n\n\t\tconst btnRect = btnEl.getBoundingClientRect();\n\t\tconst sheetRect = sheet.getBoundingClientRect();\n\n\t\tlet left = btnRect.left - sheetRect.left;\n\t\tlet top = btnRect.bottom - sheetRect.top + 2;\n\n\t\t// 화면 오른쪽 밖으로 넘칠 경우 보정\n\t\tconst panelWidth = this.offsetWidth || 250;\n\t\tconst panelHeight = this.offsetHeight || 250;\n\t\tif (left + panelWidth > sheetRect.width) {\n\t\t\tleft = Math.max(0, sheetRect.width - panelWidth - 5);\n\t\t}\n\n\t\tif (left < 0) {\n\t\t\tleft = 5;\n\t\t}\n\n\t\tif (top + panelHeight > sheetRect.height) {\n\t\t\tconst upwardTop = (btnRect.top - sheetRect.top) - panelHeight - 2;\n\t\t\tif (upwardTop >= 0) {\n\t\t\t\ttop = upwardTop; // 위쪽 공간이 있으면 위로 팝업\n\t\t\t} else {\n\t\t\t\ttop = Math.max(0, sheetRect.height - panelHeight - 5); // 위아래 다 부족하면 시트 하단에 밀착\n\t\t\t}\n\t\t}\n\n\t\tthis.style.left = `${left}px`;\n\t\tthis.style.top = `${top}px`;\n\n\t\t// 내부 그리드 행 클릭 이벤트 바인딩 (싱글 모드용)\n\t\ttrace.log(new Date());\n\n\t\tsetTimeout(() => {\n\t\t\ttrace.log(new Date());\n\t\t\tthis.#initData(dataSource, keyName, valueName, multi, separator);\n\t\t\ttrace.log(new Date());\n\t\t\tconst viewContainer = grd.shadowRoot.querySelector(\".ng-container-body table tbody.body\");\n\n\t\t\t// 중복 바인딩 방지를 위한 플래그 체크 또는 기존 리스너 관리\n\t\t\tif (!viewContainer.__hasClickEvent) {\n\n\t\t\t\tviewContainer.addEventListener(\"mousedown\", (e) => {\n\t\t\t\t\ttrace.log(\"==========================================\", e.target);\n\n\t\t\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\t\t\tif (!tr) return;\n\n\t\t\t\t\ttrace.log(\"==========================================\", multi);\n\n\t\t\t\t\tif (!multi) {\n\t\t\t\t\t\tthis.#onClickRow(e);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tviewContainer.__hasClickEvent = true;\n\t\t\t}\n\n\t\t\ttrace.log(new Date());\n\t\t}, 100);\n\t}\n\n\tclose = () => {\n\t\tthis.classList.remove(\"active\");\n\t\tthis.#isOpen = false;\n\t\tif (this.#parent && this.#parent.cell) {\n\t\t\tthis.#parent.cell.focus();\n\t\t}\n\t}\n\n\t#onClickRow = (e) => {\n\n\t\tconst sheet = e.target.closest(\"nine-table-sheet\");\n\t\tconst tr = e.target.closest(\"tr\");\n\n\t\tconst rowIndex = parseInt(tr.dataset.row, 10);\n\t\tconst record = sheet.view.get(rowIndex);\n\n\t\tthis.#parent.value = record.k;\n\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onOk = () => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst data = grd.data.getValidData();\n\n\t\tconst selectedKeys = [];\n\t\tdata.forEach(o => {\n\t\t\tif (o.v[0] === \"Y\") {\n\t\t\t\tselectedKeys.push(o.v[1]);\n\t\t\t}\n\t\t});\n\n\t\tthis.#parent.value = selectedKeys.join(this.#parent.getAttribute(\"multi-separator\") || \",\");\n\t\t//this.#parent.sheet.invalidate();\n\t\tthis.#parent.sheet.rowManager.refresh(true);\n\n\t\tthis.close();\n\t}\n\n\t#onSelectAll = (e) => {\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\t\tconst isChecked = e.target.checked ? \"Y\" : \"N\";\n\t\tgrd.data.getValidData().forEach(m => { m.v[0] = isChecked; });\n\t\tgrd.refreshData();\n\t}\n\n\t#onInput = (e) => {\n\t\tconst keyword = e.target.value.toLowerCase();\n\t\tconst grd = this.querySelector(\"nine-table-simple\");\n\n\t\t// 동적 컬럼(모든 밸류) 대상 검색 대응\n\t\tgrd.data.getValidDataNF().forEach(m => {\n\t\t\tconst match = Object.values(m.v).some(val =>\n\t\t\t\tval !== null && val !== undefined && String(val).toLowerCase().includes(keyword)\n\t\t\t);\n\t\t\tm.__ng.filtered = !match;\n\t\t});\n\n\t\tgrd.data.resetRecords();\n\t\tgrd.dataManager.viewRecords.reset();\n\t}\n\n\tget isOpen() {\n\t\treturn this.#isOpen;\n\t}\n\n\tget targetCell() {\n\t\treturn this.#parent;\n\t}\n\n\t#initEvents = () => {\n\t\tthis.querySelector(\".search-input\").addEventListener(\"input\", this.#onInput);\n\t\tthis.querySelector(\"#btnOk\").addEventListener(\"click\", this.#onOk);\n\t\tthis.querySelector(\"#chkAll\").addEventListener(\"change\", this.#onSelectAll);\n\n\n\n\t\t// 🎯 [개선] open() 할 때마다 붙일 필요 없이, 내부 그리드 영역에 이벤트 위임 처리\n\n\t\t/**\n\t\t// shadowRoot 내부 또는 컴포넌트 전체 영역을 감싸는 리스너 등록\n\t\tthis.querySelector(\"nine-table-simple\").addEventListener(\"click\", (e) => {\n\t\t\ttrace.log(e);\n\n\t\t\tconst tr = e.target.closest(\"tr\");\n\t\t\tif (!tr) return;\n\n\t\t\t// 멀티 모드가 아닐 때만 행 클릭 동작 수행\n\t\t\tconst isMulti = this.classList.contains(\"multi\");\n\t\t\tif (!isMulti) {\n\t\t\t\tthis.#onClickRow(e, false, grd);\n\t\t\t}\n\t\t}); */\n\n\t\t// 패널 외부 클릭 시 닫기\n\t\tdocument.addEventListener(\"mousedown\", (e) => {\n\t\t\tconst path = e.composedPath ? e.composedPath() : [];\n\n\t\t\t// 패널 자신이나 현재 열려 있는 필터 버튼이 경로에 포함되어 있다면 닫지 않음\n\t\t\tif (path.includes(this)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.close();\n\t\t});\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n \n cell-combo-panel.active {\n display: flex;\n }\n cell-combo-panel .head {\n display: none;\n padding: 6px;\n background: #f8f9fa;\n border-bottom: 1px solid #e5e7eb;\n }\n cell-combo-panel .head input[type=\"text\"] {\n width: 100%;\n height: 26px;\n padding: 0 6px;\n box-sizing: border-box;\n border: 1px solid #d1d5db;\n border-radius: 3px;\n outline: none;\n font-size: 12px;\n }\n cell-combo-panel.expand .head {\n display: flex;\n }\n cell-combo-panel nine-table-simple {\n width: 100%;\n flex: 1;\n border: none;\n }\n cell-combo-panel .footer {\n display: none;\n height: 32px;\n background: #f3f4f6;\n border-top: 1px solid #e5e7eb;\n align-items: center;\n padding: 0 8px;\n box-sizing: border-box;\n }\n cell-combo-panel.multi .footer {\n display: flex;\n justify-content: space-between;\n }\n cell-combo-panel .footer label {\n font-size: 12px;\n cursor: pointer;\n user-select: none;\n }\n cell-combo-panel .footer button {\n height: 22px;\n padding: 0 12px;\n font-size: 11px;\n cursor: pointer;\n background: #2563eb;\n color: white;\n border: none;\n border-radius: 3px;\n }\n cell-combo-panel .footer button:hover {\n background: #1d4ed8;\n }\n </style>\n \n <div class=\"head\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" />\n </div>\n \n <nine-table-simple class=\"combo-list\" theme=\"simple\">\n <table auto-fit-col=\"true\">\n <colgroup>\n <col width=\"30\" fixed=\"left\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"100\" />\n <col width=\"0\" />\n </colgroup>\n <tbody>\n <tr>\n <td cell-type=\"checkbox\" data-bind=\"CHK\"></td>\n <td data-bind=\"tmp1\" />\n <td data-bind=\"tmp2\" />\n <td data-bind=\"tmp3\" />\n <td data-bind=\"tmp4\" />\n <td data-bind=\"tmp5\" />\n <td data-bind=\"tmp6\" />\n <td data-bind=\"tmp7\" />\n <td data-bind=\"tmp8\" />\n <td data-bind=\"tmp9\" />\n <td data-bind=\"tmp10\" />\n <td data-bind=\"k\" />\n </tr>\n </tbody>\n </table>\n </nine-table-simple>\n \n <div class=\"footer\">\n <div>\n <input id=\"chkAll\" type=\"checkbox\" checked>\n <label for=\"chkAll\">Select All</label>\n </div>\n <button id=\"btnOk\">OK</button>\n </div>\n `;\n\t};\n}\n\nif (!customElements.get('cell-combo-panel')) {\n\tcustomElements.define(\"cell-combo-panel\", CellComboPanel);\n}","import { trace } from \"@nopeer\";\nimport { EditableCellElement } from \"./core/CellElement.js\";\nimport \"./cell-combo-panel.js\";\n\nexport class CellCombo extends EditableCellElement {\n\t#targetBtn;\n\t#dataSource = [];\n\t#keyName;\n\t#valueName;\n\t#multi;\n\t#multiSeparator;\n\t#panel;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\n\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback();\n\n\t\tthis.#keyName = super.cell.getAttribute(\"key-name\") || \"k\";\n\t\tthis.#valueName = super.cell.getAttribute(\"value-name\") || \"v\";\n\t\tthis.#multi = super.cell.getAttribute('multi') === \"true\";\n\t\tthis.#multiSeparator = super.cell.getAttribute(\"multi-separator\") || \",\";\n\n\t\tthis.#initData();\n\t\tthis.#initEvent();\n\t}\n\n\trerenderer = () => {\n\t\ttrace.log(\"rerenderer\");\n\t\tthis.#initData();\n\t\tthis.refresh();\n\t};\n\n\t#initData = () => {\n\t\tif (!super.sheet || !super.cell) return;\n\n\t\tconst dataSource = super.cell?.getAttribute(\"data-source\");\n\t\tif (!dataSource) return;\n\n\t\t// 🎯 공통 표현식 평가기를 통해 데이터 소스(배열 또는 함수 결과) 획득\n\t\t//this.#host.exprEngine.evaluate(dataSource, data, row);\n\n\t\tthis.#dataSource = super.getExprValue(dataSource, super.tr.data, super.tr.dataset.row);\n\t\t//trace.log(\"*******************************\", this.#dataSource);\n\t}\n\n\t#initEvent = () => {\n\t\t// 엔터 키 입력 시 드롭다운 토글\n\t\tthis.addEventListener(\"keydown\", e => {\n\t\t\tif (e.code === \"Enter\") {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.#togglePanel();\n\t\t\t}\n\t\t});\n\n\t\t// Light DOM 기준이므로 this 안에서 버튼 탐색\n\t\tthis.querySelectorAll(\"button\").forEach(btn => {\n\t\t\tbtn.addEventListener(\"click\", (e) => {\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.#togglePanel();\n\t\t\t});\n\t\t});\n\t}\n\n\t#togglePanel = () => {\n\t\ttrace.log(new Date());\n\t\tif (!this.#panel) {\n\t\t\t// 🎯 필터링 패널 방식과 동일하게 현재 셀이 속한 sheet(또는 그리드) 탐색\n\t\t\tthis.#panel = super.sheet.querySelector(\"cell-combo-panel\");\n\t\t\tif (!this.#panel) {\n\t\t\t\tthis.#panel = document.createElement(\"cell-combo-panel\");\n\t\t\t\tsuper.sheet.appendChild(this.#panel);\n\t\t\t}\n\t\t}\n\n\t\ttrace.log(new Date());\n\n\t\tif (this.#panel.isOpen && this.#panel.targetCell === this) {\n\t\t\tthis.#panel.close();\n\t\t} else {\n\t\t\tthis.#panel.open(this, this.#dataSource, this.#keyName, this.#valueName, this.#multi, this.#multiSeparator);\n\t\t}\n\n\t\ttrace.log(new Date());\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-combo {\n height: 100%;\n width: calc(100% - 8px);\n display: flex;\n align-items: center;\n margin-left: 4px;\n margin-right: 4px;\n box-sizing: border-box;\n }\n cell-combo.invalid .btn2::after {\n content: '';\n width: 16px;\n height: 16px;\n border: none;\n background-repeat: no-repeat;\n background-position: center;\n background-size: auto;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"fill: none; stroke-width: 2px; stroke: darkgoldenrod;\" viewBox=\"0 0 16 16\"><path d=\"m8 1 7 14H1L8 1z\"></path><path d=\"M7.99 12H8v.01h-.01zM8 6v4\"></path></svg>');\n }\n cell-combo button {\n outline: none;\n cursor: pointer;\n font: inherit;\n }\n cell-combo button.btn1 {\n width: calc(100% - 24px);\n height: 26px;\n border: 1px solid #eee;\n border-right: none;\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n text-align: left;\n background-color: white;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 4px;\n color: #000;\n }\n cell-combo button.btn2 {\n padding: 3px;\n width: 24px;\n height: 26px;\n border: 1px solid #eee;\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n background-color: #f9f9f9;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #333;\n }\n cell-combo button.btn2:after {\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n }\n </style>\n <button class=\"btn1\" type=\"button\" tabindex=\"-1\">Select</button>\n <button class=\"btn2\" type=\"button\" tabindex=\"-1\"></button>\n `;\n\n\t\t// Light DOM 구조이므로 this에서 직접 쿼리\n\t\tthis.#targetBtn = this.querySelector(\".btn1\");\n\t};\n\n\trefresh = () => {\n\t\tconst v = super.refresh();\n\t\tif (!this.#targetBtn) return v;\n\n\t\t// 현재 값에 매칭되는 텍스트(표시명) 계산\n\t\tthis.#targetBtn.textContent = this.#getDisplayText() || \"Select\";\n\t\tthis.#validateInput();\n\n\t\treturn v;\n\t};\n\n\t#getDisplayText = () => {\n\t\tif (!this.value || !Array.isArray(this.#dataSource)) return \"\";\n\n\t\tif (this.#multi) {\n\t\t\tconst keys = String(this.value).split(this.#multiSeparator);\n\t\t\treturn this.#dataSource\n\t\t\t\t.filter(m => keys.includes(String(m[this.#keyName])))\n\t\t\t\t.map(m => m[this.#valueName])\n\t\t\t\t.join(this.#multiSeparator);\n\t\t} else {\n\t\t\tconst found = this.#dataSource.find(m => String(m[this.#keyName]) === String(this.value));\n\t\t\treturn found ? found[this.#valueName] : this.value;\n\t\t}\n\t}\n\n\t#validateInput = () => {\n\t\tif (!super.cell) return;\n\t\tsuper.cell.classList.remove(\"invalid\");\n\n\t\tif (this.value === null || this.value === undefined || this.value === \"\" || !Array.isArray(this.#dataSource)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst list = this.#multi ? String(this.value).split(this.#multiSeparator) : [this.value];\n\t\tfor (const v of list) {\n\t\t\tconst idx = this.#dataSource.findIndex(m => String(v) === String(m[this.#keyName]));\n\t\t\tif (idx < 0) {\n\t\t\t\tsuper.cell.classList.add(\"invalid\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tget dataSource() {\n\t\treturn this.#dataSource;\n\t}\n}\n\nif (!customElements.get('cell-combo')) {\n\tcustomElements.define(\"cell-combo\", CellCombo);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\"; // Inherits from CellElement instead of EditableCellElement\n\nclass CellRenderer extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\t\tsuper.connectedCallback();\n\n\t\t// Debug trace for inspecting component context and parent elements\n\t\t// trace.log(\"******************\", this, this.host, this.sheet, this.tr, this.cell);\n\n\t\tthis.#renderer();\n\n\t\t// Cache the internal text span target element\n\t\tthis.#target = this.querySelector(\"span\");\n\t}\n\n\t/**\n\t * Refreshes the cell display value based on binding and expression evaluations.\n\t */\n\trefresh = () => {\n\n\t\tsuper.refresh();\n\n\t\tif (this.cell.getAttribute(\"html\") === \"true\") {\n\t\t\tthis.#target.innerHTML = this.getDisplayText();\n\t\t} else {\n\t\t\tthis.#target.textContent = this.getDisplayText();\n\t\t}\n\t};\n\n\t/**\n\t * Renders the internal markup and CSS layout rules for the cell renderer.\n\t */\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <span></span>\n `;\n\t};\n}\n\n// Register the custom element if not already defined\nif (!customElements.get(\"cell-renderer\")) {\n\tcustomElements.define(\"cell-renderer\", CellRenderer);\n}","import { CellElement } from \"./core/CellElement.js\";\nimport { NINE_TABLE } from \"@/core/constants.js\";\nimport { trace } from \"@nopeer\";\n\nexport class CellButton extends CellElement {\n\t#target;\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tconnectedCallback() {\n\n\t\tthis.#renderer();\n\n\t\t// 부모 클래스의 connectedCallback 호출 (필수)\n\t\tsuper.connectedCallback();\n\n\t\tthis.#target = this.querySelector(\"button\");\n\n\t\tthis.#target.removeEventListener(\"click\", this.#cellButtonClick);\n\t\tthis.#target.addEventListener(\"click\", this.#cellButtonClick);\n\t}\n\n\t#cellButtonClick = e => {\n\t\te.stopPropagation();\n\n\t\tconst rowid = parseInt(this.cell.dataset.row, 10);\n\n\t\tconst customEvent = new CustomEvent(NINE_TABLE.EVENT.CELL_BUTTON_CLICK, {\n\t\t\tbubbles: true,\n\t\t\tcomposed: true,\n\t\t\tdetail: {\n\t\t\t\toriginalEvent: e,\n\t\t\t\tcell: this.cell,\n\t\t\t\trow: rowid,\n\t\t\t\tcol: parseInt(this.cell.dataset.col, 10),\n\t\t\t\tbind: this.dataset.bind,\n\t\t\t\tdata: this.host.data.get(rowid),\n\t\t\t\tvalue: this.value,\n\t\t\t}\n\t\t});\n\n\t\tthis.dispatchEvent(customEvent);\n\t};\n\n\t/**\n\t * 레거시 dataRefresh 패턴 반영 (표현식 동적 평가 및 스타일링)\n\t */\n\trefresh = () => {\n\t\tconst rawValue = super.refresh ? super.refresh() : this.value;\n\t\t//let displayValue = this.getDisplayText(rawValue);\n\t\tthis.#target.innerHTML = this.getDisplayText(rawValue);\n\n\t\t/**\n\t\t// 행 데이터 및 인덱스 확보\n\t\tconst rowIdx = parseInt(super.cell.dataset.row, 10);\n\t\tconst rowData = super.host?.data?.get ? super.host.data.get(rowIdx) : (this.closest(\"tr\")?.data);\n\n\t\tif (rowData && !isNaN(rowIdx)) {\n\t\t\t[\"color\", \"background\", \"border\"].forEach(attrName => {\n\t\t\t\tconst expr = this.getAttribute(attrName);\n\t\t\t\tif (expr && this.#target) {\n\t\t\t\t\tconst evaluatedVal = super.getExprValue ? super.getExprValue(expr, rowData, rowIdx, super.cell) : expr;\n\t\t\t\t\tthis.#target.style[attrName] = evaluatedVal;\n\t\t\t\t}\n\t\t\t});\n\t\t} */\n\t};\n\n\t#renderer = () => {\n\t\t/**\n\t\tconst allowedAttrs = [\"color\", \"background\", \"border\", \"class\", \"style\"];\n\t\tconst attrList = [];\n\n\t\tfor (let i = 0; i < this.attributes.length; i++) {\n\t\t\tconst attr = this.attributes[i];\n\t\t\tif (allowedAttrs.includes(attr.name)) {\n\t\t\t\tattrList.push(`${attr.name}=\"${attr.value}\"`);\n\t\t\t}\n\t\t} */\n\n\t\tconst cell = this.closest(\"th,td\");\n\n\t\tconst buttonText = \"...\";//this.getAttribute(\"text\") || super.attr[\"text\"] || \"\";\n\t\tconst height = (parseInt(cell.offsetHeight, 10) || 32) - 8;\n\n\t\tthis.innerHTML = `\n <style>\n /* 셀(td, th) 내부 패딩 제거 및 꽉 채우기 설정 */\n cell-button {\n display: flex;\n align-items: stretch;\n justify-content: stretch;\n width: 100%;\n height: ${height}px;\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n cell-button .button {\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n border-radius: 0; /* 셀에 꽉 차게 보이려면 0이 깔끔할 수 있음 */\n border: 1px solid #d1d5db;\n background-color: #f3f4f6;\n color: #1f2937;\n outline: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n cell-button .button:hover {\n background-color: #e5e7eb;\n }\n cell-button .button:active {\n background-color: #d1d5db;\n }\n </style>\n <button class=\"button\">${buttonText}</button>\n `;\n\t};\n}\n\nif (!customElements.get('cell-button')) {\n\tcustomElements.define(\"cell-button\", CellButton);\n}","import { trace } from \"@nopeer\";\nimport { CellElement } from \"./core/CellElement.js\";\n\nclass CellRowIndicator extends CellElement {\n\t#mainTarget;\n\t#subTarget;\n\t#statusTarget;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.applyBaseStyle();\n\t}\n\n\tconnectedCallback() {\n\t\tthis.#renderer();\n\t\tsuper.connectedCallback?.();\n\n\t\tif (this.cell) {\n\t\t\tthis.cell.removeAttribute(\"tabindex\");\n\t\t\tthis.cell.dataset.bind = \"rowState\";\n\n\t\t\tif (!this.cell.dataset.expr) {\n\t\t\t\tthis.cell.dataset.expr = \"data.__ng._[ninegrid.ROW.ORDER]\";\n\t\t\t}\n\n\t\t\tthis.cell.setAttribute(\"text-align\", \"center\");\n\t\t}\n\n\t\tthis.#mainTarget = this.querySelector(\".ng-row-main\");\n\t\tthis.#subTarget = this.querySelector(\".ng-row-sub\");\n\t\tthis.#statusTarget = this.querySelector(\".ng-row-status\");\n\t}\n\n\t#renderer = () => {\n\t\tthis.innerHTML = `\n <style>\n cell-row-indicator {\n display: block;\n position: absolute; /* 💡 셀 전체를 강제로 꽉 채움 */\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n box-sizing: border-box;\n user-select: none;\n }\n /* 메인 행 번호 (중앙 정렬을 위해 플렉스 적용) */\n .ng-row-main {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n text-align: center;\n overflow: hidden;\n }\n \n /* 🎯 천단위 콤마 및 분할 스타일링 */\n .ng-row-prefix {\n \tfont-weight: normal;\n font-size: 0.40rem; /* 앞자리(천단위 이상)는 아주 작게 */\n }\n .ng-row-suffix {\n font-size: 0.55rem; /* 마지막 3자리 및 콤마는 현재 셀 기본 폰트 크기 유지 */\n }\n \n /* 우측 하단: 원본/이빨빠진 번호 */\n .ng-row-sub {\n position: absolute;\n right: 2px;\n bottom: 1px;\n font-size: 0.40rem;\n line-height: 1;\n opacity: 0.2;\n pointer-events: none;\n }\n /* 우측 상단: 상태 표시 */\n .ng-row-status {\n position: absolute;\n right: 2px;\n top: 1px;\n font-size: 0.55rem;\n line-height: 1;\n pointer-events: none;\n }\n </style>\n \n <span class=\"ng-row-main\"></span>\n <span class=\"ng-row-sub\"></span>\n <span class=\"ng-row-status\"></span>\n `;\n\t}\n\n\t/**\n\t * 행 번호 및 상태 갱신\n\t */\n\trefresh = () => {\n\t\tif (!this.cell || !this.tr) return;\n\n\t\tconst row = this.row;\n\t\tif (isNaN(row)) return;\n\n\t\tconst rawRecord = this.tr.data;\n\n\t\tif (rawRecord && rawRecord.__ng) {\n\t\t\tconst rowState = rawRecord.__ng.rowState;\n\n\t\t\t/**\n\t\t\t// 1. 행 상태에 따른 클래스 제어 및 우측 상단 상태 표시\n\t\t\tif (rowState === ninegrid.ROW_STATE.INSERT) {\n\t\t\t\tthis.classList.add('added');\n\t\t\t\tthis.classList.remove('updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"➕\";\n\t\t\t} else if (rowState === ninegrid.ROW_STATE.UPDATE) {\n\t\t\t\tthis.classList.add('updated');\n\t\t\t\tthis.classList.remove('added');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"✏️\";\n\t\t\t} else {\n\t\t\t\tthis.classList.remove('added', 'updated');\n\t\t\t\tif (this.#statusTarget) this.#statusTarget.textContent = \"\";\n\t\t\t} */\n\n\t\t\t/**\n\t\t\t// 2. 필터링 등으로 순번이 밀렸을 때 우측 하단에 원본 번호 표시\n\t\t\tif (rawRecord.__ng.i !== undefined) {\n\t\t\t\tconst currentSeq = row + 1;\n\t\t\t\tconst originalSeq = rawRecord.__ng.i + 1;\n\n\t\t\t\tif (this.#subTarget) {\n\t\t\t\t\tif (currentSeq !== originalSeq) {\n\t\t\t\t\t\tthis.#subTarget.textContent = originalSeq;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#subTarget.textContent = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} */\n\t\t}\n\n\t\tconst displayNum = this.index + 1;\n\n\t\t// 천단위 콤마 포맷팅 (예: 1234567 -> \"1,234,567\")\n\t\tconst formattedNum = displayNum.toLocaleString();\n\n\t\t// 3자리 이상일 경우 마지막 3자리(와 콤마 포함된 덩어리)를 기준으로 앞자리와 분리\n\t\tif (displayNum >= 10000) {\n\t\t\t// 뒤에서 4글자(콤마 + 3자리)를 기준으로 분리합니다. (예: \"1,234\" 와 \"567\")\n\t\t\tconst splitIndex = formattedNum.length - 4;\n\t\t\tconst prefixPart = formattedNum.substring(0, splitIndex + 1); // 천단위 이상 (작은 폰트)\n\t\t\tconst suffixPart = formattedNum.substring(splitIndex + 1); // 마지막 콤마 + 3자리 (기본 폰트)\n\n\t\t\tthis.#mainTarget.innerHTML = `\n <span class=\"ng-row-prefix\">${prefixPart}</span>\n <span class=\"ng-row-suffix\">${suffixPart}</span>\n `;\n\t\t} else {\n\t\t\t// 1000 미만인 경우 콤마만 있거나 일반 숫자로 그대로 표시\n\t\t\tthis.#mainTarget.innerHTML = `${formattedNum}`;\n\t\t}\n\n\t\tconst isSorted = this.sheet.querySelector(\"thead .asc,thead .desc\") ? true : false;\n\t\tconst isFitered = this.sheet.querySelector(\"thead nine-table-filter-button.filtered\") ? true : false;\n\n\t\tthis.#subTarget.innerHTML = row;\n\t\tthis.#subTarget.style.display = (isSorted || isFitered) ? \"\" : \"none\";\n\t};\n}\n\nif (!customElements.get('cell-row-indicator')) {\n\tcustomElements.define(\"cell-row-indicator\", CellRowIndicator);\n}","// ui/col/col-expand.js\nimport { TableCompiler, COLLAPSED_WIDTH } from \"@/ui/layout/core/TableCompiler.js\";\n\nexport class ColExpand extends HTMLElement {\n #sheet;\n #cell;\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n this.#cell = this.closest('th, td');\n this.#sheet = this.closest('nine-table-sheet');\n\n if (this.#cell) {\n this.#cell.style.position = 'relative';\n }\n\n const isCollapsed =\n this.getAttribute('collapsed') === 'true' ||\n this.#cell?.getAttribute('collapsed') === 'true';\n\n if (isCollapsed) {\n requestAnimationFrame(() => {\n this.collapse(true);\n });\n } else {\n this.classList.remove('collapsed');\n this.classList.add('expand');\n }\n\n this.removeEventListener('click', this.#onClick);\n this.addEventListener('click', this.#onClick);\n }\n\n #onClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.classList.contains('expand')) {\n this.collapse();\n } else {\n this.expand();\n }\n };\n\n /**\n * 🎯 원래 너비(dataset.expandWidth)로 복구\n */\n expand = () => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n this.classList.remove('collapsed');\n this.classList.add('expand');\n this.#cell.setAttribute('collapsed', 'false');\n this.#cell.style.color = '';\n\n const targetWidth = parseInt(this.#cell.dataset.expandWidth, 10) || 100;\n\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, targetWidth);\n } else {\n const singleWidth = Math.max(30, Math.floor(targetWidth / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, singleWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n collapse = (isInitialInit = false) => {\n if (!this.#sheet?.colResizer || !this.#cell) return;\n const colIndex = parseInt(this.#cell.dataset.col, 10);\n const colSpan = this.#cell.colSpan || 1;\n\n if (this.classList.contains('expand')) {\n const col = this.#sheet.querySelector(`colgroup col[data-col=\"${colIndex}\"]`);\n const currentW = col ? parseInt(col.getAttribute('width'), 10) : 0;\n if (currentW > COLLAPSED_WIDTH) {\n this.#cell.dataset.expandWidth = String(currentW * colSpan);\n }\n }\n\n this.classList.remove('expand');\n this.classList.add('collapsed');\n this.#cell.setAttribute('collapsed', 'true');\n this.#cell.style.color = 'transparent';\n\n // 🎯 colSpan이 1이면 16px(COLLAPSED_WIDTH)을 그대로 적용, 2 이상이면 균등 분할\n if (colSpan === 1) {\n this.#sheet.colResizer.setColumnWidth(colIndex, COLLAPSED_WIDTH);\n } else {\n const splitWidth = Math.max(10, Math.floor(COLLAPSED_WIDTH / colSpan));\n for (let i = 0; i < colSpan; i++) {\n this.#sheet.colResizer.setColumnWidth(colIndex + i, splitWidth);\n }\n }\n\n requestAnimationFrame(() => {\n if (typeof this.#sheet.refreshLayout === 'function') {\n this.#sheet.refreshLayout();\n }\n });\n };\n\n disconnectedCallback() {\n this.removeEventListener('click', this.#onClick);\n }\n}\n\nif (!customElements.get('nine-table-col-expand')) {\n customElements.define('nine-table-col-expand', ColExpand);\n}","// ui/menu/nine-table-menu.js (수정본)\n\nimport { trace } from \"@nopeer\";\nimport { ColFixManager } from \"@/ui/col/ColFixManager.js\";\n\nexport class ContextMenu extends HTMLElement {\n #tableHost;\n #panel;\n\n connectedCallback() {\n const root = this.getRootNode();\n this.#tableHost = root instanceof ShadowRoot ? root.host : (this.closest('nine-table') || root.host);\n\n if (!this.#tableHost) {\n this.#tableHost = this.parentElement?.closest('nine-table') || this.assignedSlot?.closest('nine-table');\n }\n\n if (!this.#tableHost) return;\n\n //this.#tableHost.addEventListener('contextmenu', this.#onContextMenu);\n }\n\n #onContextMenu = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n const targetCell = path.find(el => el.tagName === 'TH' || el.tagName === 'TD');\n\n if (!targetCell) return;\n\n const targetTable = path.find(el => el.tagName === 'TABLE') || targetCell.closest('table');\n\n e.preventDefault();\n e.stopPropagation();\n\n this.openMenu(e.clientX, e.clientY, targetCell, targetTable);\n };\n\n /**\n * 🎯 우클릭이 발생한 대상 시트(NineTableSheet) 구하기\n */\n #getTargetSheet(targetCell) {\n return targetCell?.closest('nine-table-sheet') || this.#tableHost.activeSheet || this.#tableHost;\n }\n\n #getFixManager(targetCell) {\n const sheet = this.#getTargetSheet(targetCell);\n if (!sheet) return null;\n\n if (!sheet.colFix) {\n sheet.colFix = new ColFixManager(sheet);\n }\n return sheet.colFix;\n }\n\n #parseCustomMenuItems(containerElement, activeTable) {\n const items = [];\n const activeTableId = activeTable?.id;\n const allUls = Array.from(containerElement.querySelectorAll(':scope > ul'));\n\n allUls.forEach(rootUl => {\n const targetTableAttr = rootUl.getAttribute('target-table');\n\n if (!targetTableAttr || (activeTableId && targetTableAttr === activeTableId)) {\n const parsedList = this.#traverseUl(rootUl);\n items.push(...parsedList);\n }\n });\n\n return items;\n }\n\n #traverseUl(ulEl) {\n const list = [];\n Array.from(ulEl.children).forEach(child => {\n const tagName = child.tagName.toLowerCase();\n\n if (tagName === 'hr' || child.classList.contains('separator')) {\n list.push({ type: 'separator' });\n return;\n }\n\n if (tagName === 'li') {\n let name = '';\n const spanEl = child.querySelector(':scope > span');\n if (spanEl) {\n name = spanEl.textContent.trim();\n } else {\n name = Array.from(child.childNodes)\n .filter(n => n.nodeType === Node.TEXT_NODE)\n .map(n => n.textContent.trim())\n .join('');\n }\n\n const subUl = child.querySelector(':scope > ul');\n const item = {\n menuId: child.id || name,\n name: name,\n className: child.className || '',\n disabled: child.hasAttribute('disabled') || child.getAttribute('disabled') === 'true',\n isCustom: true\n };\n\n if (subUl) {\n item.items = this.#traverseUl(subUl);\n }\n\n list.push(item);\n }\n });\n return list;\n }\n\n #buildMenuItems(activeTable, isHeaderCell, targetCell) {\n const useDefault = this.getAttribute('use-default-menu') !== 'false';\n let rawItems = [];\n\n const customItems = this.#parseCustomMenuItems(this, activeTable);\n if (customItems.length > 0) {\n rawItems.push(...customItems);\n }\n\n const fixManager = this.#getFixManager(targetCell);\n const currentFixState = fixManager?.getFixState(targetCell, activeTable) ?? 'none';\n const isFixable = isHeaderCell && (fixManager?.canFixColumn(targetCell, activeTable) ?? false);\n\n let fixMenuItem = null;\n if (currentFixState === 'left' || currentFixState === 'right') {\n fixMenuItem = {\n menuId: 'unfix-column',\n name: 'Unfix Column',\n className: 'ng-menu-unfix-col',\n disabled: !isHeaderCell\n };\n } else {\n fixMenuItem = {\n menuId: 'fix-column',\n name: 'Fix Column',\n className: 'ng-menu-fix-col',\n disabled: !isFixable\n };\n }\n\n if (useDefault) {\n rawItems.push(\n { type: 'separator' },\n {\n menuId: 'sort',\n name: 'Sort',\n className: 'ng-menu-sort',\n disabled: !isHeaderCell\n },\n fixMenuItem,\n { type: 'separator' },\n { menuId: 'filtering', name: 'Filtering', className: 'ng-menu-filtering' },\n { menuId: 'maximize', name: 'Maximize', className: 'maximize' },\n {\n menuId: 'export',\n name: 'Export',\n className: 'export',\n items: [\n { menuId: 'export-excel', name: 'Excel', className: 'export-excel' },\n { menuId: 'export-pdf', name: 'PDF', className: 'export-pdf', disabled: true }\n ]\n },\n {\n menuId: 'properties',\n name: 'Options',\n className: 'options',\n items: [\n { menuId: 'show-title-bar', name: 'Title Bar Show/Hide', className: 'show-title-bar' },\n { menuId: 'show-status-bar', name: 'Status Bar Show/Hide', className: 'show-status-bar' },\n { menuId: 'auto-fit-col', name: 'Auto Fit Columns', className: 'auto-fit-col' }\n ]\n }\n );\n }\n\n const cleanedItems = [];\n rawItems.forEach((item) => {\n if (item.type === 'separator') {\n if (cleanedItems.length === 0 || cleanedItems[cleanedItems.length - 1].type === 'separator') {\n return;\n }\n }\n cleanedItems.push(item);\n });\n\n if (cleanedItems.length > 0 && cleanedItems[cleanedItems.length - 1].type === 'separator') {\n cleanedItems.pop();\n }\n\n return cleanedItems;\n }\n\n openMenu(x, y, targetCell, targetTable) {\n const targetParent = this.#tableHost.shadowRoot || this.#tableHost;\n\n if (!this.#panel) {\n this.#panel = document.createElement('nine-table-menu-panel');\n targetParent.appendChild(this.#panel);\n }\n\n const isHeaderCell = !!targetCell.closest('thead');\n const menuItems = this.#buildMenuItems(targetTable, isHeaderCell, targetCell);\n\n this.#panel.render(menuItems, (e) => this.#handleMenuClick(e, targetCell, targetTable));\n\n const targetSheet = this.#getTargetSheet(targetCell);\n this.#syncMenuStates(targetSheet);\n\n // 🎯 targetCell을 3번째 인자로 전달하여 셀 우측선 정렬\n this.#panel.openAt(x, y);\n }\n\n /**\n * 🎯 메뉴 항목 활성화 체크 표시(✓) 동기화\n */\n #syncMenuStates(targetSheet) {\n if (!this.#panel || !targetSheet) return;\n\n // 🎯 클릭된 개별 시트의 filtering 상태 검사\n const isFiltering = targetSheet.filtering?.isFiltering?.() || false;\n this.#panel.toggleItemState('filtering', 'on', isFiltering);\n\n const autoFit = this.#tableHost.getAttribute('auto-fit-col') === 'true';\n this.#panel.toggleItemState('auto-fit-col', 'on', autoFit);\n\n const showTitle = this.#tableHost.getAttribute('show-title-bar') === 'true';\n this.#panel.toggleItemState('show-title-bar', 'on', showTitle);\n }\n\n #handleMenuClick(e, targetCell, targetTable) {\n const menuId = e.menuId;\n\n const customEvent = new CustomEvent('menu-click', {\n detail: { menuId, targetCell, targetTable, originalEvent: e },\n bubbles: true,\n composed: true\n });\n this.dispatchEvent(customEvent);\n\n const baseCol = parseInt(targetCell.dataset.col, 10);\n\n // 🎯 클릭된 셀의 소속 시트 인스턴스 타겟팅\n const targetSheet = this.#getTargetSheet(targetCell);\n\n switch (menuId) {\n case 'fix-column':\n case 'unfix-column':\n const fixManager = this.#getFixManager(targetCell);\n fixManager?.executeFixToggle(menuId, targetCell);\n break;\n\n case 'sort':\n if (!isNaN(baseCol)) {\n targetSheet.sorting?.handleSortFromMenu?.(baseCol, targetCell);\n }\n break;\n\n case 'filtering':\n targetSheet?.filtering?.toggle();\n break;\n\n case 'auto-fit-col':\n this.#tableHost.setAttribute('auto-fit-col', this.#tableHost.getAttribute('auto-fit-col') === 'true' ? 'false' : 'true');\n break;\n\n case 'show-title-bar':\n this.#tableHost.setAttribute('show-title-bar', this.#tableHost.getAttribute('show-title-bar') === 'true' ? 'false' : 'true');\n break;\n }\n\n this.#panel.close();\n }\n\n disconnectedCallback() {\n this.#tableHost?.removeEventListener('contextmenu', this.#onContextMenu);\n }\n}\n\nif (!customElements.get('nine-table-menu')) {\n customElements.define('nine-table-menu', ContextMenu);\n}","// ui/menu/nine-table-menu-panel.js\n\nexport class MenuPanel extends HTMLElement {\n #onCallback;\n #closeHandler = null; // 🎯 이벤트 누수 방지용 리스너 참조\n\n constructor() {\n super();\n }\n\n connectedCallback() {\n // 🎯 [보정 1] 패널 자체의 기본 레이아웃 스타일은 element style로 직접 지정\n this.style.position = 'fixed';\n this.style.display = 'none';\n this.style.zIndex = '99999';\n\n this.innerHTML = `\n <style>\n \n nine-table-menu-panel .menu-wrapper {\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 150px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: 12px;\n }\n nine-table-menu-panel ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n nine-table-menu-panel li {\n position: relative;\n padding: 6px 16px;\n cursor: pointer;\n color: #374151;\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-sizing: border-box;\n }\n nine-table-menu-panel li:hover {\n background-color: #f3f4f6;\n color: #111827;\n }\n nine-table-menu-panel li.on::before {\n content: '✓';\n position: absolute;\n left: 4px;\n font-weight: bold;\n }\n nine-table-menu-panel li.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n background: transparent !important;\n }\n nine-table-menu-panel li.ng-menu-separator {\n height: 1px;\n background: #e5e7eb;\n margin: 4px 0;\n padding: 0;\n cursor: default;\n }\n nine-table-menu-panel li.submenu::after {\n content: '▶';\n font-size: 9px;\n margin-left: 8px;\n color: #9ca3af;\n }\n nine-table-menu-panel .ng-menu-sublist {\n display: none;\n position: absolute;\n top: -4px;\n left: 100%;\n background: #ffffff;\n border: 1px solid #d1d5db;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-radius: 4px;\n padding: 4px 0;\n min-width: 140px;\n }\n nine-table-menu-panel li.submenu:hover > .ng-menu-sublist {\n display: block;\n }\n </style>\n <div class=\"menu-wrapper\">\n <ul class=\"menu-container\"></ul>\n </div>\n `;\n }\n\n render(items, callback) {\n this.#onCallback = callback;\n const container = this.querySelector('.menu-container');\n if (!container) return;\n\n container.innerHTML = '';\n\n this.#appendItems(container, items);\n this.#bindClickEvents();\n }\n\n /**\n * 🎯 패널의 우측선과 targetCell의 우측선을 일치시키는 포지셔닝\n */\n openAt(x, y, targetCell = null) {\n this.style.display = 'block';\n\n if (targetCell) {\n const cellRect = targetCell.getBoundingClientRect();\n // 셀의 오른쪽 경계선 좌표\n const cellRightX = cellRect.right;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const panelWidth = wrapper.getBoundingClientRect().width;\n\n // 패널 우측선을 셀 우측선에 맞춤 (Left = cellRight - panelWidth)\n let calculatedLeft = cellRightX - panelWidth;\n\n // 뷰포트 왼쪽 밖으로 벗어나는 예외 처리\n if (calculatedLeft < 0) {\n calculatedLeft = cellRect.left; // 공간이 부족하면 셀 좌측선에 맞춤\n }\n\n // 뷰포트 아래쪽 벗어남 처리\n const panelHeight = wrapper.getBoundingClientRect().height;\n let calculatedTop = y;\n if (y + panelHeight > window.innerHeight) {\n calculatedTop = y - panelHeight;\n }\n\n this.style.left = `${calculatedLeft}px`;\n this.style.top = `${calculatedTop}px`;\n });\n } else {\n // 기본 마우스 클릭 좌표 기반 (Fallback)\n this.style.left = `${x}px`;\n this.style.top = `${y}px`;\n\n requestAnimationFrame(() => {\n const wrapper = this.querySelector('.menu-wrapper');\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n\n if (x + rect.width > window.innerWidth) {\n this.style.left = `${x - rect.width}px`;\n }\n if (y + rect.height > window.innerHeight) {\n this.style.top = `${y - rect.height}px`;\n }\n });\n }\n\n // 바깥 클릭 핸들러 등록\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n }\n\n this.#closeHandler = (e) => {\n const path = e.composedPath ? e.composedPath() : [];\n if (!path.includes(this) && !this.contains(e.target)) {\n this.close();\n }\n };\n\n setTimeout(() => {\n window.addEventListener('pointerdown', this.#closeHandler);\n }, 0);\n }\n\n close() {\n this.style.display = 'none';\n if (this.#closeHandler) {\n window.removeEventListener('pointerdown', this.#closeHandler);\n this.#closeHandler = null;\n }\n }\n\n toggleItemState(menuId, className, condition) {\n const li = this.querySelector(`li[menu-id=\"${menuId}\"]`);\n if (li) {\n condition ? li.classList.add(className) : li.classList.remove(className);\n }\n }\n\n #appendItems(parentUl, items) {\n items.forEach(item => {\n if (item.type === 'separator') {\n const sep = document.createElement('li');\n sep.className = 'ng-menu-separator';\n parentUl.appendChild(sep);\n return;\n }\n\n const li = document.createElement('li');\n li.setAttribute('menu-id', item.menuId);\n li.className = `${item.className || ''} ${item.items ? 'submenu' : ''} ${item.disabled ? 'disabled' : ''}`.trim();\n\n const span = document.createElement('span');\n span.textContent = item.name;\n li.appendChild(span);\n\n if (item.items && item.items.length > 0) {\n const subUl = document.createElement('ul');\n subUl.className = 'ng-menu-sublist';\n this.#appendItems(subUl, item.items);\n li.appendChild(subUl);\n }\n\n parentUl.appendChild(li);\n });\n }\n\n #bindClickEvents() {\n this.querySelectorAll('li[menu-id]').forEach(li => {\n li.addEventListener('click', (e) => {\n e.stopPropagation();\n if (li.classList.contains('disabled')) return;\n\n const menuId = li.getAttribute('menu-id');\n this.#onCallback?.({ menuId, target: li });\n this.close();\n });\n });\n }\n\n disconnectedCallback() {\n this.close();\n }\n}\n\nif (!customElements.get('nine-table-menu-panel')) {\n customElements.define('nine-table-menu-panel', MenuPanel);\n}"],"names":["target","start","end","mid","elementDebounceState","dblClickEvent","dblClickFn","pointerEvent","pointerFn","debounceTime","el","state","e","_text","_font","stripHtml","__name","html","tmp","canvas","context","w","h","v","cleanText","metrics","ascent","descent","_Trace","traceOrigin","Trace","trace","NINE_TABLE","_ngRow","parent","__privateAdd","_parent","_newrow","__publicField","__privateGet","__privateSet","ngRow","_ngData","host","_host","_nextId","_defaultHeight","_getValidRecords","o","_a","at","colnm","validRecords","targetRecord","idx","rowIndex","colIndex","value","rowData","_conv","fields","_initialize","templateElements","_getDefaultMeta","_invalidate","$sheets","$el","dataSource","loadData","rowid","_json2Array","jsonArray","arr","json","_defaultInsert","updateState","row","_","a","b","rowidx","targetId","item","COL_IDX","oldValue","isSingle","targetArr","result","t","i","__privateWrapper","ngData","_ngDataManager","ds","nRow","rowIdx","_b","ngDataManager","_fields","type","fName","f","_adjust","map","name","_init","rawTables","tbl","fieldName","fieldType","attr","expr","lastIndex","targetField","found","_NineTableSheets","NineTableSheets","_NineTableSheetsFooter","_NineTableSheetsFooter_instances","__privateMethod","render_fn","isMultiSelect","tabItem","index","_switchSheet","updateSplitters","sheets","s","activeSheets","sheet","currentIdx","targetSplitter","tabBar","body","tabItems","sheetElements","tab","isActive","clickedTab","activeTabs","targetSheet","tabsHtml","table","className","tabName","NineTableSheetsFooter","_SheetTabItem","SheetTabItem","_Toolbar","_Toolbar_instances","_customContainer","bindEvents_fn","element","text","titleEl","syncStateFromHost_fn","isSimple","showToolbar","showMenu","caption","link","currentCaption","menuBtn","Toolbar","_NineTableHScrollBar","_owner","_dragging","_elements","_interval1","_interval2","_resizeObserver","_observeResize","track","thumb","bodyWidth","tableWidth","needsHScroll","trackWidth","thumbWidth","currentLeft","maxScrollLeft","l","maxThumbLeft","_thumbMoveTo","x","trackBound","targetX","newScrollLeft","headerBody","footerBody","delayScroll","pos","thumbLeft","currentThumbLeft","clearTimer","evt","trackRect","onMouseMove","moveEvent","onMouseUp","initWhenReady","NineTableHScrollBar","_NineTableVScrollBar","_sheet","_startY","_startScrollTop","_startThumbTop","_getScaleInfo","viewRecords","totalCount","scrollHolder","rawContentHeight","rowHeight","MAX_BROWSER_HEIGHT","useScaling","scaleFactor","contentHeight","_getViewHeight","thead","_c","tfoot","_f","_e","_d","tbodyHead","_j","_i","_h","_g","fixedHeight","bodyHeight","needsVScroll","trackHeight","thumbHeight","currentScrollTop","maxScrollTop","thumbTop","maxThumbTop","deltaY","targetThumbTop","ratio","viewHeight","visibleRowCount","targetRow","clickY","currentTopRow","NineTableVScrollBar","GROUP_IDX","_GroupingManager","_groupColumns","_groupMap","_isApplying","groupColumns","sourceTable","$tr","$cell","groupId","rowIds","dataManager","GroupingManager","_Grouping","rawRecords","validRaw","groupMap","nestedTree","_Grouping_static","buildNestedMap_fn","flatResult","renderItems","flattenTree_fn","mapOrArray","depth","resultArr","parentId","counter","isLastLevel","groupKey","subMapOrRecords","collectLeafRowIds_fn","groupRecord","collectLeafRecords_fn","record","records","remainingCols","key","subRecords","subVal","r","Grouping","_RowManager","_BUFFER_ROW_COUNT","_element","_containerTemplates","_templateRowHeights","_cachedTemplateHeight","_sheetHeight","_cachedRowCount","_isProgrammaticScroll","_isGrouped","force","bodyViewport","_measureAndCacheHeight","_renderAllContainers","_handleScroll","scrollTop","_handleGroupedScroll","templateLength","rawTotalVirtualHeight","totalVirtualHeight","actualScrollTop","maxStartIndex","clampedScrollTop","startIndex","renderOffsetTop","firstTr","currentStartIndex","$tbody","tbodyIdx","dataIndex","_bindRowData","allRenderItems","totalVirtualCount","bodyContent","getItemHeight","dataRowsHeight","groupHeightsTotal","itemHeights","viewportClientHeight","accumulatedHeight","offsetY","visibleRowsCount","dynamicBuffer","targetStart","targetEnd","renderedItems","selector","container","trs","itemIndex","chunkTrs","tr","subIdx","virtualIndex","isTrGroup","_bindGroupRowData","subRowIndex","matrixRow","indices","allRecords","childrenRecords","customComp","tableEl","tbody","templateTrs","trTemplates","fragment","renderedTrs","sum","_updateRowCount","visibleRows","groupDepth","_renderRows","_syncRowHeights","targetFixedType","clonedTr","targetTbody","tmpl","leftTable","bodyTable","rightTable","leftRows","bodyRows","rightRows","maxRows","heights","maxHeight","_initResizeObserver","entries","entry","height","dataRow","align","onRendered","targetScrollTop","rawTargetScrollTop","RowManager","COLLAPSED_WIDTH","_TableCompiler","$srcTable","$table","_TableCompiler_static","syncColAttributes_fn","cols","grid","rowSpan","colSpan","c","$col","fixed","TableCompiler","_CellSelection","_CellSelection_instances","_range","startRow","startCol","endRow","endCol","containers","getMatrixRow_fn","cell","col","cellEndRow","cellEndCol","$focusTd","initEvents_fn","$td","r1","r2","c1","c2","expanded","loopCount","nsR","neR","nsC","neC","sameGroupTrs","mainZone","lastMatrixRow","lastCol","targetEl","targetCell","allCells","rect","targetTr","CellSelection","_CellNavigation","_CellNavigation_instances","_currentCell","_currentTr","_currentRow","_currentCol","_getMinCol","cells","minCol","_getMaxCol","maxCol","_getMaxColCell","targetTrs","_getNextCol","td","next","_getPreviousCol","currentCol","currentTrCells","_findTargetTrsByMatrix","smallerCols","matchedTrs","mRow","getMatrixRowFromTr_fn","foundInSpan","_getNearElement","targetMatrixRow","searchedTrs","trDataRow","trSubIdx","span","cellDataRowStart","cellSubRowStart","cellStartMatrix","cellEndMatrix","nextMatrixRow","nextCol","prevTrs","maxColCell","maxMatrixRowLimit","maxMatrixRow","nextDataRow","nextSubRowIndex","retries","actualMatrixRow","ensureCellVisible_fn","retryCell","mRowAttr","bodyContainer","cellRect","viewportRect","containerRect","headerRect","isAbove","isBelow","subrow","CellNavigation","RESIZE_OFFSET","_ColResizer","_ColResizer_instances","_panel","_tooltip","_targetColIndex","_nextColIndex","_targetContainerType","_targetCell","_startX","_startColWidth","_nextColStartWidth","_startCellWidth","_startLeft","_onPointerMove","headerPart","offsetX","isLeftEdge","isRightEdge","prevCell","_onPointerDown","getContainerType_fn","baseColIndex","checkIsAutoFit_fn","nextColEl","targetRect","sheetRect","targetColEl","attrW","updatePositions_fn","_onDragMove","_onDragEnd","diff","isAutoFit","finalWidth","newColWidth","newNextWidth","_onDblClick","tbodyCell","extraPadding","fieldIdx","font","headerText","maxTextWidth","val","size","calculatedWidth","containerType","firstColgroup","totalWidth","colWidths","colIdx","tables","globalColIndex","width","targetCols","firstContainer","resolvedContainerType","sourceCol","clientX","maxDiff","minDiff","currentColWidth","realCellWidth","maxCellWidth","currentCellWidth","sizeBadge","ColResizer","_ColMover","_ColMover_instances","_grip","_indi","_isDragging","_sourceCell","_sourceColIndex","_shiftX","_timer","checkIsMovable_fn","startX","startY","cancelTimer","onPointerMovePending","startDrag_fn","updateGripPosition_fn","targetElement","getDeepElementFromPoint_fn","targetColIndex","colMinLeft","colMaxRight","cCol","cSpan","cEnd","cRect","midX","calculatedTargetCol","indicatorLeft","sourceGroup","getColGroupRange_fn","movingSpan","sourceRowStart","sourceRowSpan","sourceRowEnd","targetRowStart","targetRowSpan","targetRowEnd","isRowSpanCompatible","isOutOfBoundsOfParent","pStart","pEnd","isDroppingInsideOtherGroup","spannedCells","sCell","sRowStart","sRowSpan","sRowEnd","sStart","sSpan","sEnd","moveEndCol","isSelfGroup","relativeTop","fullHeight","_onPointerUp","fromColIndex","toColIndex","colgroup","targetCol","spanCount","isInRange","targetViewportCol","fixedType","group","targetRowCell","y","root","nested","headerCells","hasStrictChildren","isValidGroup","parentGroupRange","subCell","subStart","subSpan","subEnd","isRealGroup","createGroupHeaderPreview_fn","groupRange","isGroup","origTable","minLeft","maxRight","minTop","maxBottom","targetCells","computedStyle","groupWidth","groupHeight","headerContent","style","clonedCell","preview","bounds","left","ColMover","_ColFixManager","baseCol","colEl","fixedAttr","targetBoundaryCol","theadTrs","cellBoundaryFound","cEndCol","action","fixType","cIdx","minBaseCol","rIdx","rSpan","trIndex","isBroken","correspondingCol","isColFixed","ColFixManager","_NineTableFilterPanel","_NineTableFilterPanel_instances","_nineTable","_view","_button","_renderer","_onInput","_onSelectAll","_onOk","_closeHandler","path","filterRecords","checkedRecords","chk","filterParams","colInfo","filterKey","selectedVals","btn","query","data2Idx","matchedValues","isChecked","chkIdx","_onCancel","filterBtn","panelWidth","top","searchBox","loadVirtualFilterItems_fn","filteredRecords","activeFilters","exprEngine","bindKey","exprKey","activeSelectedVals","uniqueMap","rawVal","displayVal","uniqueList","selectAllChk","NineTableFilterPanel","_NineTableFilterButton","_columns","isFiltered","_onClick","panel","seen","uniqueKey","NineTableFilterButton","_Filtering","_Filtering_instances","_isFiltering","_filterPanel","_filters","_initFilterPanel","applyFiltering_fn","oFilter","jsonFilter","k","sheetIndex","filterRules","targetKey","allowedValues","isExpr","recordIdx","isPass","allowedSet","Filtering","_Sorting","_Sorting_instances","syncHeaderUI_fn","handleSort_fn","colName","exprVal","isAsc","isDesc","existingColIndex","m","ruleData","applySorting_fn","colRule","asc","Sorting","_SheetView","_sortingColumns","_filterRules","_viewIndexes","_cachedVisibleRecords","visibleRecords","_convSingle","filterSlot","_applySorting","groupResult","columns","rulesWithIdx","rule","idxA","idxB","valA","valB","isEmptyA","isEmptyB","strA","strB","SheetView","_PreCompiler","_PreCompiler_static","ensureColgroup_fn","ensureThead_fn","ensureSectionTbodys_fn","ensureRowIndicator_fn","normalizeColAttributes_fn","createColIndicator_fn","normalizeCollapsibleAttributes_fn","generateCell_fn","initColExpanders_fn","initFilterButtons_fn","_k","applyInitialCellWidths_fn","tdTmpl","firstRow","cnt","numToExcelCol_fn","background","num","n","headTbody","footTbody","colCount","containerWidth","defaultWidth","widthVal","$tbl","targetAttributes","autoIdCounter","tagName","$datalist","$option","uniqueFuncName","innerAttrs","cellType","originalContent","hostFilter","tableFilter","finalFiltering","currentWidth","expandBtn","targetWidth","section","rows","indicatorCell","startColIdx","targetIdx","PreCompiler","_NineTableSheet","_NineTableSheet_instances","_index","_rowManager","_cellSelection","_cellNavigation","_colResizer","_colMover","_colFix","_sorting","_filtering","_grouping","_source","_adjustOverlay","$thead","$overlay","enable","_autoFit","totalOriginalWidth","colList","headerCell","collapsedTotalWidth","availableWidth","allocatedTotal","calculatedCols","exactWidth","baseWidth","remainderPixels","uncollapsedCols","finalSumWidth","_renderSplitContainers","_updateContainerWidths","_syncHeaderAndFooterHeights","_initRowHoverEvent","prefix","firstTable","_createSplitTable","scrollLeft","_render","isSimple_get","leftHeaderRows","bodyHeaderRows","rightHeaderRows","_applyMaxHeights","leftFooterRows","bodyFooterRows","rightFooterRows","activeRowIndex","relatedTarget","attrTrue","sourceTableTrue","NineTableSheet","_LayoutManager","owner","_applyAutoHeight","maxDisplayRows","maxRowHeight","toolbarEl","footerEl","toolbarHeight","footerHeight","calculatedHeight","isAutoHeight","sheetCount","sheetsHtml","sheetId","sheetTag","splitterTag","cssFiles","npmCssImports","file","customCssImports","LayoutManager","_ExprEngine","_exprCache","match","rowItem","trimmedExpr","compiledExpr","evalFn","ExprEngine","_NineTable","_NineTable_instances","_shadowRoot","_dataManager","_layoutManager","_templateCnt","_dispatchLoad","checkCount","maxChecks","checkTimer","loadSheetCnt","$sheet","idOrIndex","fn","bindDynamicSetters_fn","extractedMethodNames","matches","methodName","internalValue","newValue","NineTable","_BasicCellElement","BasicCellElement","exprCache","_CellElement","_tr","_cell","_attr","defaultValue","rawRecord","cleanExpr","childRecords","funcName","field","acc","button","curRow","renderer","prop","updateRowState","data","CellElement","_EditableCellElement","EditableCellElement","_CellInputText","_target","_initEvent","maxbyte","maxByteNum","event","CellInputText","_CellInputNumber","_validateInput","strVal","dotIdx","_onKeyDown","selectionStart","scale","validKey","isNumKey","CellInputNumber","_CellInputColor","_btn","_isValidColor","g","CellInputColor","_CellInputDate","_type","formattedVal","d","min","max","isValid","_isValidDate","year","month","day","isleap","hour","week","CellInputDate","_CellCheckbox","_label","_isRadio","_trueText","_falseText","newVal","trueValue","childHtml","displayText","CellCheckbox","_CellRadio","_dataSource","_keyName","_valueName","matchIndex","targets","_rendererRadio","codeVal","nameVal","label","input","CellRadio","_CellComboPanel","_isOpen","_initData","keyName","valueName","multi","separator","grd","itemsAttr","fieldKeys","activeColumnCount","formattedData","selectedKeys","btnEl","btnRect","panelHeight","upwardTop","viewContainer","_onClickRow","keyword","_initEvents","CellComboPanel","_CellCombo","_targetBtn","_multi","_multiSeparator","_togglePanel","_getDisplayText","keys","list","CellCombo","_CellRenderer","CellRenderer","_CellButton","_cellButtonClick","customEvent","rawValue","buttonText","CellButton","_CellRowIndicator","_mainTarget","_subTarget","_statusTarget","displayNum","formattedNum","splitIndex","prefixPart","suffixPart","isSorted","isFitered","CellRowIndicator","_ColExpand","singleWidth","isInitialInit","currentW","splitWidth","ColExpand","_ContextMenu","_ContextMenu_instances","_tableHost","_onContextMenu","targetTable","targetParent","isHeaderCell","menuItems","buildMenuItems_fn","handleMenuClick_fn","getTargetSheet_fn","syncMenuStates_fn","getFixManager_fn","parseCustomMenuItems_fn","containerElement","activeTable","items","activeTableId","rootUl","targetTableAttr","parsedList","traverseUl_fn","ulEl","child","spanEl","subUl","useDefault","rawItems","customItems","fixManager","currentFixState","isFixable","fixMenuItem","cleanedItems","isFiltering","autoFit","showTitle","menuId","ContextMenu","_MenuPanel","_MenuPanel_instances","_onCallback","callback","appendItems_fn","bindClickEvents_fn","cellRightX","wrapper","calculatedLeft","calculatedTop","condition","li","parentUl","sep","MenuPanel"],"mappings":"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"}
|