@ninebone/table 0.1.45 → 0.1.46

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.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\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\t//const 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\t//const 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 `);\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\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\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-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(`thead 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 = [\n 'layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table', 'col-resize', 'sorting', 'fitering', 'cell-select', 'col-expand',\n 'cell-combo',\n ];\n // 2. npm 패키지 CSS 배열 생성\n /**\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}.css\";`\n ); */\n const npmCssImports = [\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/nine-table.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","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","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","customCssImports","file","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.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\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\t//const 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\t//const 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 `);\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\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\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-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(`thead 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\n /**\n const cssFiles = [\n 'layout', 'nine-table-sheet', 'nine-table-vscrollbar', 'nine-table-hscrollbar', 'table', 'col-resize', 'sorting', 'fitering', 'cell-select', 'col-expand',\n 'cell-combo',\n ]; */\n\n\n const cssFiles = [\n '_nine-table',\n ];\n // 2. npm 패키지 CSS 배열 생성\n /**\n const npmCssImports = cssFiles.map(file =>\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/${file}.css\";`\n ); */\n const npmCssImports = [\n `@import \"https://cdn.jsdelivr.net/npm/@ninebone/table@${__APP_VERSION__}/dist/css/nine-table.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","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","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","customCssImports","file","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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"}