@ubermensch1218/hwpxeditor 0.1.1 → 0.1.2

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,"sources":["../src/index.ts","../src/components/editor/Editor.tsx","../src/lib/store.ts","../src/lib/view-model.ts","../src/lib/hwp-units.ts","../src/lib/image-extractor.ts","../src/lib/format-bridge.ts","../src/lib/skeleton-loader.ts","../src/components/toolbar/MenuBar.tsx","../src/components/toolbar/ClipboardGroup.tsx","../src/components/toolbar/ToolbarButton.tsx","../src/components/toolbar/RibbonGroup.tsx","../src/components/toolbar/InsertGroup.tsx","../src/components/toolbar/RibbonToolbar.tsx","../src/lib/constants.ts","../src/components/toolbar/ToolbarDropdown.tsx","../src/components/toolbar/StyleSelector.tsx","../src/components/toolbar/FontSelector.tsx","../src/components/toolbar/FontSizeInput.tsx","../src/components/toolbar/CharFormatButtons.tsx","../src/components/toolbar/ColorPicker.tsx","../src/components/toolbar/AlignmentButtons.tsx","../src/components/toolbar/LineSpacingControl.tsx","../src/components/toolbar/ToolbarDivider.tsx","../src/components/toolbar/SecondaryToolbar.tsx","../src/components/ruler/HorizontalRuler.tsx","../src/components/sidebar/FormatSidebar.tsx","../src/components/sidebar/SidebarSection.tsx","../src/components/sidebar/SidebarField.tsx","../src/components/sidebar/BorderSettings.tsx","../src/components/sidebar/BackgroundSettings.tsx","../src/components/sidebar/CharFormatPanel.tsx","../src/components/sidebar/ParaFormatPanel.tsx","../src/components/sidebar/PageSetupPanel.tsx","../src/components/sidebar/ImageLayoutPanel.tsx","../src/components/sidebar/ImagePropertiesPanel.tsx","../src/components/sidebar/TablePropertiesPanel.tsx","../src/components/editor/ParagraphBlock.tsx","../src/components/editor/RunSpan.tsx","../src/components/editor/TableBlock.tsx","../src/components/editor/TableCell.tsx","../src/components/editor/ImageBlock.tsx","../src/components/editor/TextBoxBlock.tsx","../src/components/editor/EquationBlock.tsx","../src/components/editor/Page.tsx","../src/components/editor/PageView.tsx","../src/components/editor/SaveDialog.tsx","../src/components/upload/FileUpload.tsx","../src/components/upload/NewDocumentButton.tsx","../src/components/dialog/CharFormatDialog.tsx","../src/components/dialog/Dialog.tsx","../src/components/dialog/DialogTabs.tsx","../src/components/dialog/DialogSection.tsx","../src/components/dialog/ParaFormatDialog.tsx","../src/components/dialog/BulletNumberDialog.tsx","../src/components/dialog/CharMapDialog.tsx","../src/components/dialog/TemplateDialog.tsx","../src/components/dialog/HeaderFooterDialog.tsx","../src/components/dialog/FindReplaceDialog.tsx","../src/components/dialog/WordCountDialog.tsx"],"sourcesContent":["/**\n * @hwpx/editor — React editor components for HWPX documents.\n *\n * Provides a Korean word processor-style UI with ribbon toolbar,\n * format sidebar, ruler, and full page editing.\n */\n\n// ── Editor components ─────────────────────────────────────────────────────\nexport { Editor } from \"./components/editor/Editor\";\nexport { PageView } from \"./components/editor/PageView\";\nexport { Page } from \"./components/editor/Page\";\nexport { ParagraphBlock } from \"./components/editor/ParagraphBlock\";\nexport { RunSpan } from \"./components/editor/RunSpan\";\nexport { ImageBlock } from \"./components/editor/ImageBlock\";\nexport { TableBlock } from \"./components/editor/TableBlock\";\nexport { TableCell } from \"./components/editor/TableCell\";\n\n// ── Toolbar components ────────────────────────────────────────────────────\nexport { RibbonToolbar } from \"./components/toolbar/RibbonToolbar\";\nexport { SecondaryToolbar } from \"./components/toolbar/SecondaryToolbar\";\nexport { ToolbarButton } from \"./components/toolbar/ToolbarButton\";\nexport { ToolbarDropdown } from \"./components/toolbar/ToolbarDropdown\";\nexport { ToolbarDivider } from \"./components/toolbar/ToolbarDivider\";\nexport { ColorPicker } from \"./components/toolbar/ColorPicker\";\nexport { RibbonGroup } from \"./components/toolbar/RibbonGroup\";\nexport { ClipboardGroup } from \"./components/toolbar/ClipboardGroup\";\nexport { InsertGroup } from \"./components/toolbar/InsertGroup\";\nexport { StyleSelector } from \"./components/toolbar/StyleSelector\";\nexport { FontSelector } from \"./components/toolbar/FontSelector\";\nexport { FontSizeInput } from \"./components/toolbar/FontSizeInput\";\nexport { CharFormatButtons } from \"./components/toolbar/CharFormatButtons\";\nexport { AlignmentButtons } from \"./components/toolbar/AlignmentButtons\";\nexport { LineSpacingControl } from \"./components/toolbar/LineSpacingControl\";\n\n// ── Sidebar components ────────────────────────────────────────────────────\nexport { FormatSidebar } from \"./components/sidebar/FormatSidebar\";\nexport { SidebarSection } from \"./components/sidebar/SidebarSection\";\nexport { SidebarField } from \"./components/sidebar/SidebarField\";\nexport { CharFormatPanel } from \"./components/sidebar/CharFormatPanel\";\nexport { ParaFormatPanel } from \"./components/sidebar/ParaFormatPanel\";\nexport { BorderSettings } from \"./components/sidebar/BorderSettings\";\nexport { BackgroundSettings } from \"./components/sidebar/BackgroundSettings\";\n\n// ── Ruler ─────────────────────────────────────────────────────────────────\nexport { HorizontalRuler } from \"./components/ruler/HorizontalRuler\";\n\n// ── Upload components ─────────────────────────────────────────────────────\nexport { FileUpload } from \"./components/upload/FileUpload\";\nexport { NewDocumentButton } from \"./components/upload/NewDocumentButton\";\n\n// ── Store ─────────────────────────────────────────────────────────────────\nexport { useEditorStore } from \"./lib/store\";\nexport type {\n SelectionState,\n ActiveFormat,\n ExtendedFormat,\n UIState,\n EditorStore,\n} from \"./lib/store\";\n\n// ── Constants ─────────────────────────────────────────────────────────────\nexport {\n FONT_FAMILIES,\n FONT_SIZES,\n STYLE_PRESETS,\n ALIGNMENT_OPTIONS,\n LINE_SPACING_OPTIONS,\n UNDERLINE_TYPES,\n COLOR_PRESETS,\n HIGHLIGHT_COLORS,\n} from \"./lib/constants\";\nexport type {\n FontFamily,\n StylePreset,\n AlignmentType,\n AlignmentOption,\n LineSpacingOption,\n SidebarTab,\n} from \"./lib/constants\";\n\n// ── Format bridge ─────────────────────────────────────────────────────────\nexport {\n readCharFormat,\n readParaFormat,\n readStyleInfo,\n getDocumentStyles,\n readFormatFromSelection,\n} from \"./lib/format-bridge\";\nexport type { CharFormat, ParaFormat } from \"./lib/format-bridge\";\n\n// ── View model ────────────────────────────────────────────────────────────\nexport { buildViewModel } from \"./lib/view-model\";\nexport type {\n RunVM,\n TableCellVM,\n TableVM,\n ImageVM,\n ParagraphVM,\n SectionVM,\n EditorViewModel,\n} from \"./lib/view-model\";\n\n// ── Utilities ─────────────────────────────────────────────────────────────\nexport { hwpToPx, pxToHwp, hwpToMm, mmToHwp } from \"./lib/hwp-units\";\nexport { extractImages } from \"./lib/image-extractor\";\nexport { ensureSkeletonLoaded, createNewDocument } from \"./lib/skeleton-loader\";\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ensureSkeletonLoaded } from \"@/lib/skeleton-loader\";\nimport { MenuBar } from \"../toolbar/MenuBar\";\nimport { RibbonToolbar } from \"../toolbar/RibbonToolbar\";\nimport { SecondaryToolbar } from \"../toolbar/SecondaryToolbar\";\nimport { HorizontalRuler } from \"../ruler/HorizontalRuler\";\nimport { FormatSidebar } from \"../sidebar/FormatSidebar\";\nimport { PageView } from \"./PageView\";\nimport { SaveDialog } from \"./SaveDialog\";\nimport { FileUpload } from \"../upload/FileUpload\";\nimport { NewDocumentButton } from \"../upload/NewDocumentButton\";\nimport { CharFormatDialog } from \"../dialog/CharFormatDialog\";\nimport { ParaFormatDialog } from \"../dialog/ParaFormatDialog\";\nimport { BulletNumberDialog } from \"../dialog/BulletNumberDialog\";\nimport { CharMapDialog } from \"../dialog/CharMapDialog\";\nimport { TemplateDialog } from \"../dialog/TemplateDialog\";\nimport { HeaderFooterDialog } from \"../dialog/HeaderFooterDialog\";\nimport { FindReplaceDialog } from \"../dialog/FindReplaceDialog\";\nimport { WordCountDialog } from \"../dialog/WordCountDialog\";\nimport { PanelRight } from \"lucide-react\";\n\nexport function Editor() {\n const doc = useEditorStore((s) => s.doc);\n const loading = useEditorStore((s) => s.loading);\n const error = useEditorStore((s) => s.error);\n const uiState = useEditorStore((s) => s.uiState);\n const toggleSidebar = useEditorStore((s) => s.toggleSidebar);\n\n // Pre-load skeleton on mount\n useEffect(() => {\n ensureSkeletonLoaded().catch(console.error);\n }, []);\n\n // Global keyboard shortcuts\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n const store = useEditorStore.getState();\n if (!store.doc) return;\n\n const mod = e.ctrlKey || e.metaKey;\n\n if (mod && e.key === \"s\") {\n e.preventDefault();\n store.openSaveDialog();\n return;\n }\n\n // Undo / Redo (works without selection)\n if (mod && e.key === \"z\" && !e.shiftKey) {\n e.preventDefault();\n store.undo();\n return;\n }\n if (mod && (e.key === \"y\" || (e.key === \"z\" && e.shiftKey))) {\n e.preventDefault();\n store.redo();\n return;\n }\n\n // Dialog shortcuts (⌘L = char format, ⌘T = para format, Ctrl+F10 = char map)\n if (mod && e.key === \"l\") {\n e.preventDefault();\n store.openCharFormatDialog();\n return;\n }\n if (mod && e.key === \"t\") {\n e.preventDefault();\n store.openParaFormatDialog();\n return;\n }\n if (e.key === \"F10\" && (e.ctrlKey || e.metaKey)) {\n e.preventDefault();\n store.openCharMapDialog();\n return;\n }\n if (mod && (e.key === \"f\" || e.key === \"h\")) {\n e.preventDefault();\n store.openFindReplaceDialog();\n return;\n }\n\n if (!store.selection) return;\n\n if (mod && e.key === \"b\") {\n e.preventDefault();\n store.toggleBold();\n } else if (mod && e.key === \"i\") {\n e.preventDefault();\n store.toggleItalic();\n } else if (mod && e.key === \"u\") {\n e.preventDefault();\n store.toggleUnderline();\n } else if (mod && e.key === \"d\") {\n e.preventDefault();\n store.toggleStrikethrough();\n } else if (mod && e.key === \"e\") {\n e.preventDefault();\n store.setAlignment(\"CENTER\");\n } else if (mod && e.key === \"r\") {\n e.preventDefault();\n store.setAlignment(\"RIGHT\");\n } else if (mod && e.key === \"j\") {\n e.preventDefault();\n store.setAlignment(\"JUSTIFY\");\n }\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-screen items-center justify-center\">\n <div className=\"text-gray-500\">로딩 중...</div>\n </div>\n );\n }\n\n if (!doc) {\n return (\n <div className=\"flex h-screen flex-col items-center justify-center gap-6 bg-gray-100 p-8\">\n <h1 className=\"text-2xl font-bold text-gray-800\">HWPX Editor</h1>\n <p className=\"text-gray-500 max-w-md text-center\">\n HWPX 문서를 열거나 새 문서를 만들어 편집하세요.\n </p>\n <div className=\"w-full max-w-md\">\n <FileUpload />\n </div>\n <div className=\"flex gap-3\">\n <NewDocumentButton />\n </div>\n {error && (\n <div className=\"bg-red-50 text-red-600 px-4 py-2 rounded-lg text-sm\">\n {error}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"flex h-screen flex-col\">\n <SaveDialog />\n <CharFormatDialog />\n <ParaFormatDialog />\n <BulletNumberDialog />\n <CharMapDialog />\n <TemplateDialog />\n <HeaderFooterDialog />\n <FindReplaceDialog />\n <WordCountDialog />\n {/* Menu bar */}\n <MenuBar />\n {/* Ribbon toolbar */}\n <RibbonToolbar />\n {/* Secondary toolbar (formatting bar) */}\n <SecondaryToolbar />\n {/* Horizontal ruler */}\n <HorizontalRuler />\n {/* Error banner */}\n {error && (\n <div className=\"bg-red-50 text-red-600 px-4 py-2 text-sm border-b border-red-200\">\n {error}\n </div>\n )}\n {/* Main content area: Page + Sidebar */}\n <div className=\"flex flex-1 overflow-hidden\">\n <PageView />\n <FormatSidebar />\n {/* Sidebar toggle when closed */}\n {!uiState.sidebarOpen && (\n <button\n onClick={toggleSidebar}\n className=\"absolute right-2 top-[140px] z-10 p-1.5 bg-white border border-gray-200 rounded shadow-sm text-gray-400 hover:text-gray-600 hover:bg-gray-50\"\n title=\"서식 사이드바 열기\"\n >\n <PanelRight className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n {/* Status bar */}\n <StatusBar />\n </div>\n );\n}\n\nfunction StatusBar() {\n const doc = useEditorStore((s) => s.doc);\n const viewModel = useEditorStore((s) => s.viewModel);\n const openWordCountDialog = useEditorStore((s) => s.openWordCountDialog);\n\n if (!doc || !viewModel) return null;\n\n const text = doc.text;\n const charCount = text.replace(/\\s/g, \"\").length;\n // Estimate page count (1 section = 1 page minimum)\n const sectionCount = viewModel.sections.length;\n\n return (\n <div className=\"h-5 flex items-center justify-end px-3 bg-gray-100 border-t border-gray-200 text-[10px] text-gray-500\">\n <button\n onClick={openWordCountDialog}\n className=\"hover:text-gray-700 hover:underline\"\n title=\"글자 수 세기 대화상자 열기\"\n >\n 글자 수 (공백 제외): {charCount.toLocaleString()} | 쪽: {sectionCount}\n </button>\n </div>\n );\n}\n","/**\n * Zustand store — manages HwpxDocument + EditorViewModel + actions.\n */\n\nimport { create } from \"zustand\";\nimport type { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { buildViewModel, type EditorViewModel } from \"./view-model\";\nimport {\n readFormatFromSelection,\n type CharFormat,\n type ParaFormat,\n} from \"./format-bridge\";\nimport type { AlignmentType, OrientationType, SidebarTab } from \"./constants\";\nimport { mmToHwp } from \"./hwp-units\";\n\nexport interface SelectionState {\n sectionIndex: number;\n paragraphIndex: number;\n type: \"paragraph\" | \"cell\" | \"table\";\n // For cell/table selection\n tableIndex?: number;\n row?: number;\n col?: number;\n // For multi-cell selection (range)\n endRow?: number;\n endCol?: number;\n // For object selection (image/table/textBox context)\n objectType?: \"image\" | \"table\" | \"textBox\";\n imageIndex?: number;\n textBoxIndex?: number;\n // For text range selection within a paragraph\n textStartOffset?: number;\n textEndOffset?: number;\n}\n\nexport interface ActiveFormat {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n}\n\nexport interface ExtendedFormat {\n char: CharFormat;\n para: ParaFormat;\n}\n\nexport interface UIState {\n sidebarOpen: boolean;\n sidebarTab: SidebarTab;\n saveDialogOpen: boolean;\n charFormatDialogOpen: boolean;\n paraFormatDialogOpen: boolean;\n bulletNumberDialogOpen: boolean;\n charMapDialogOpen: boolean;\n templateDialogOpen: boolean;\n headerFooterDialogOpen: boolean;\n findReplaceDialogOpen: boolean;\n wordCountDialogOpen: boolean;\n}\n\nexport interface Template {\n id: string;\n name: string;\n path: string;\n description?: string;\n createdAt: number;\n}\n\ninterface UndoEntry {\n sectionElements: Element[];\n headerElements: Element[];\n selection: SelectionState | null;\n}\n\nexport interface EditorStore {\n doc: HwpxDocument | null;\n viewModel: EditorViewModel | null;\n revision: number;\n selection: SelectionState | null;\n activeFormat: ActiveFormat;\n extendedFormat: ExtendedFormat;\n uiState: UIState;\n loading: boolean;\n error: string | null;\n undoStack: UndoEntry[];\n redoStack: UndoEntry[];\n templates: Template[];\n\n // Actions\n setDocument: (doc: HwpxDocument) => void;\n rebuild: () => void;\n setSelection: (sel: SelectionState | null) => void;\n setActiveFormat: (fmt: Partial<ActiveFormat>) => void;\n refreshExtendedFormat: () => void;\n\n // UI actions\n toggleSidebar: () => void;\n setSidebarTab: (tab: SidebarTab) => void;\n openTemplateDialog: () => void;\n closeTemplateDialog: () => void;\n openHeaderFooterDialog: () => void;\n closeHeaderFooterDialog: () => void;\n setHeaderFooter: (opts: { headerText?: string; footerText?: string }) => void;\n openFindReplaceDialog: () => void;\n closeFindReplaceDialog: () => void;\n findAndReplace: (search: string, replacement: string, count?: number) => number;\n openWordCountDialog: () => void;\n closeWordCountDialog: () => void;\n\n // Template actions\n addTemplate: (name: string, path: string, description?: string) => void;\n removeTemplate: (id: string) => void;\n loadTemplates: () => void;\n saveTemplates: () => void;\n\n // Text editing\n updateParagraphText: (\n sectionIndex: number,\n paragraphIndex: number,\n text: string,\n ) => void;\n updateCellText: (\n sectionIndex: number,\n paragraphIndex: number,\n tableIndex: number,\n row: number,\n col: number,\n text: string,\n ) => void;\n\n // Formatting\n toggleBold: () => void;\n toggleItalic: () => void;\n toggleUnderline: () => void;\n toggleStrikethrough: () => void;\n setFontFamily: (fontFamily: string) => void;\n setFontSize: (size: number) => void;\n setTextColor: (color: string) => void;\n setHighlightColor: (color: string) => void;\n setAlignment: (alignment: AlignmentType) => void;\n setLineSpacing: (spacing: number) => void;\n\n // Block operations\n deleteBlock: (sectionIndex: number, paragraphIndex: number) => void;\n insertBlockAt: (\n sectionIndex: number,\n paragraphIndex: number,\n text?: string,\n ) => void;\n\n // Paragraph editing\n splitParagraph: (\n sectionIndex: number,\n paragraphIndex: number,\n offset: number,\n ) => void;\n mergeParagraphWithPrevious: (\n sectionIndex: number,\n paragraphIndex: number,\n ) => void;\n\n // Undo/Redo\n pushUndo: () => void;\n undo: () => void;\n redo: () => void;\n\n // Content insertion\n addParagraph: (text?: string) => void;\n addTable: (\n sectionIndex: number,\n paragraphIndex: number,\n rows: number,\n cols: number,\n ) => void;\n insertImage: (\n data: Uint8Array,\n mediaType: string,\n widthMm: number,\n heightMm: number,\n ) => void;\n insertColumnBreak: () => void;\n insertPageBreak: () => void;\n\n // Image editing\n updatePictureSize: (widthMm: number, heightMm: number) => void;\n resizeImage: (deltaWidthHwp: number, deltaHeightHwp: number) => void;\n setImageOutMargin: (margins: Partial<{ top: number; bottom: number; left: number; right: number }>) => void;\n\n // Table editing\n setTablePageBreak: (mode: \"CELL\" | \"NONE\") => void;\n setTableRepeatHeader: (repeat: boolean) => void;\n setTableSize: (widthMm: number, heightMm: number) => void;\n setTableOutMargin: (margins: Partial<{ top: number; bottom: number; left: number; right: number }>) => void;\n setTableInMargin: (margins: Partial<{ top: number; bottom: number; left: number; right: number }>) => void;\n resizeTableColumn: (sectionIdx: number, paraIdx: number, tableIdx: number, colIdx: number, deltaHwp: number) => void;\n setSelectedCellsSize: (widthMm?: number, heightMm?: number) => void;\n mergeSelectedCells: () => void;\n unmergeSelectedCells: () => void;\n\n // Paragraph indent\n setFirstLineIndent: (valueHwp: number) => void;\n setLeftIndent: (valueHwp: number) => void;\n\n // Page numbering\n setPageNumbering: (opts: { position: string; startNumber: number }) => void;\n\n // Footnote / Endnote\n insertFootnote: () => void;\n insertEndnote: () => void;\n\n // Watermark\n setWatermarkText: (text: string) => void;\n\n // Dialog open/close\n openCharFormatDialog: () => void;\n closeCharFormatDialog: () => void;\n openParaFormatDialog: () => void;\n closeParaFormatDialog: () => void;\n openBulletNumberDialog: () => void;\n closeBulletNumberDialog: () => void;\n openCharMapDialog: () => void;\n closeCharMapDialog: () => void;\n\n // Text insertion at cursor\n insertTextAtCursor: (text: string) => void;\n insertTab: () => void;\n insertTextBox: (text: string, widthMm: number, heightMm: number) => void;\n\n // Page setup\n updatePageSize: (width: number, height: number) => void;\n updatePageMargins: (margins: Partial<{ left: number; right: number; top: number; bottom: number; header: number; footer: number; gutter: number }>) => void;\n updatePageOrientation: (orientation: OrientationType) => void;\n setColumnCount: (colCount: number, gapMm?: number) => void;\n\n // File operations\n saveDocument: () => Promise<void>;\n saveDocumentAs: (filename: string) => Promise<void>;\n openSaveDialog: () => void;\n closeSaveDialog: () => void;\n setLoading: (loading: boolean) => void;\n setError: (error: string | null) => void;\n}\n\nconst defaultCharFormat: CharFormat = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n fontFamily: null,\n fontSize: null,\n textColor: null,\n highlightColor: null,\n letterSpacing: null,\n};\n\nconst defaultParaFormat: ParaFormat = {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n};\n\nexport const useEditorStore = create<EditorStore>((set, get) => ({\n doc: null,\n viewModel: null,\n revision: 0,\n selection: null,\n activeFormat: { bold: false, italic: false, underline: false, strikethrough: false },\n undoStack: [],\n redoStack: [],\n extendedFormat: { char: defaultCharFormat, para: defaultParaFormat },\n uiState: { sidebarOpen: true, sidebarTab: \"char\", saveDialogOpen: false, charFormatDialogOpen: false, paraFormatDialogOpen: false, bulletNumberDialogOpen: false, charMapDialogOpen: false, templateDialogOpen: false, headerFooterDialogOpen: false, findReplaceDialogOpen: false, wordCountDialogOpen: false },\n loading: false,\n error: null,\n templates: [],\n\n setDocument: (doc) => {\n const viewModel = buildViewModel(doc);\n set({ doc, viewModel, revision: get().revision + 1, error: null });\n },\n\n rebuild: () => {\n const { doc } = get();\n if (!doc) return;\n const viewModel = buildViewModel(doc);\n set({ viewModel, revision: get().revision + 1 });\n },\n\n setSelection: (selection) => {\n set({ selection });\n // Auto-refresh extended format when selection changes\n if (selection) {\n // Use setTimeout to avoid synchronous read during render\n setTimeout(() => get().refreshExtendedFormat(), 0);\n }\n },\n\n setActiveFormat: (fmt) =>\n set((s) => ({ activeFormat: { ...s.activeFormat, ...fmt } })),\n\n refreshExtendedFormat: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const fmt = readFormatFromSelection(\n doc,\n selection.sectionIndex,\n selection.paragraphIndex,\n );\n set({\n extendedFormat: fmt,\n activeFormat: {\n bold: fmt.char.bold,\n italic: fmt.char.italic,\n underline: fmt.char.underline,\n strikethrough: fmt.char.strikethrough,\n },\n });\n } catch (e) {\n console.error(\"refreshExtendedFormat failed:\", e);\n }\n },\n\n // UI actions\n toggleSidebar: () =>\n set((s) => ({\n uiState: { ...s.uiState, sidebarOpen: !s.uiState.sidebarOpen },\n })),\n\n setSidebarTab: (tab) =>\n set((s) => ({\n uiState: { ...s.uiState, sidebarTab: tab },\n })),\n\n openTemplateDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, templateDialogOpen: true } })),\n\n closeTemplateDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, templateDialogOpen: false } })),\n\n openHeaderFooterDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, headerFooterDialogOpen: true } })),\n\n closeHeaderFooterDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, headerFooterDialogOpen: false } })),\n\n setHeaderFooter: ({ headerText, footerText }) => {\n const { doc, selection } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n const props = section.properties;\n if (headerText != null) props.setHeaderText(headerText);\n if (footerText != null) props.setFooterText(footerText);\n get().rebuild();\n } catch (e) {\n console.error(\"setHeaderFooter failed:\", e);\n }\n },\n\n openFindReplaceDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, findReplaceDialogOpen: true } })),\n\n closeFindReplaceDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, findReplaceDialogOpen: false } })),\n\n findAndReplace: (search, replacement, count) => {\n const { doc } = get();\n if (!doc) return 0;\n try {\n get().pushUndo();\n const replaced = doc.replaceText(search, replacement, count);\n get().rebuild();\n return replaced;\n } catch (e) {\n console.error(\"findAndReplace failed:\", e);\n return 0;\n }\n },\n\n openWordCountDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, wordCountDialogOpen: true } })),\n\n closeWordCountDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, wordCountDialogOpen: false } })),\n\n addTemplate: (name, path, description) => {\n const template: Template = {\n id: `tpl-${Date.now()}`,\n name,\n path,\n description,\n createdAt: Date.now(),\n };\n set((s) => ({ templates: [...s.templates, template] }));\n get().saveTemplates();\n },\n\n removeTemplate: (id) => {\n set((s) => ({ templates: s.templates.filter((t) => t.id !== id) }));\n get().saveTemplates();\n },\n\n loadTemplates: () => {\n try {\n const stored = localStorage.getItem(\"hwpx-templates\");\n if (stored) {\n const templates = JSON.parse(stored) as Template[];\n set({ templates });\n }\n } catch (e) {\n console.error(\"loadTemplates failed:\", e);\n }\n },\n\n saveTemplates: () => {\n try {\n const { templates } = get();\n localStorage.setItem(\"hwpx-templates\", JSON.stringify(templates));\n } catch (e) {\n console.error(\"saveTemplates failed:\", e);\n }\n },\n\n setLoading: (loading) => set({ loading }),\n setError: (error) => set({ error }),\n\n updateParagraphText: (sectionIndex, paragraphIndex, text) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) return;\n const oldText = para.text;\n if (oldText === text) return;\n get().pushUndo();\n para.text = text;\n get().rebuild();\n } catch (e) {\n console.error(\"updateParagraphText failed:\", e);\n }\n },\n\n updateCellText: (sectionIndex, paragraphIndex, tableIndex, row, col, text) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) return;\n const table = para.tables[tableIndex];\n if (!table) return;\n table.setCellText(row, col, text);\n get().rebuild();\n } catch (e) {\n console.error(\"updateCellText failed:\", e);\n }\n },\n\n toggleBold: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newBold = !activeFormat.bold;\n try {\n get().pushUndo();\n const charPrIdRef = doc.ensureRunStyle({\n bold: newBold,\n italic: activeFormat.italic,\n underline: activeFormat.underline,\n strikethrough: activeFormat.strikethrough,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n // Check if there's a text range selection\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n set({ activeFormat: { ...activeFormat, bold: newBold } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleBold failed:\", e);\n }\n },\n\n toggleItalic: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newItalic = !activeFormat.italic;\n try {\n get().pushUndo();\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: newItalic,\n underline: activeFormat.underline,\n strikethrough: activeFormat.strikethrough,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n set({ activeFormat: { ...activeFormat, italic: newItalic } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleItalic failed:\", e);\n }\n },\n\n toggleUnderline: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newUnderline = !activeFormat.underline;\n try {\n get().pushUndo();\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: activeFormat.italic,\n underline: newUnderline,\n strikethrough: activeFormat.strikethrough,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n set({ activeFormat: { ...activeFormat, underline: newUnderline } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleUnderline failed:\", e);\n }\n },\n\n toggleStrikethrough: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newStrike = !activeFormat.strikethrough;\n try {\n get().pushUndo();\n const cf = get().extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: activeFormat.italic,\n underline: activeFormat.underline,\n strikethrough: newStrike,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: cf.fontSize ?? undefined,\n textColor: cf.textColor ?? undefined,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n set({ activeFormat: { ...activeFormat, strikethrough: newStrike } });\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"toggleStrikethrough failed:\", e);\n }\n },\n\n setFontFamily: (fontFamily) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily,\n fontSize: cf.fontSize ?? undefined,\n textColor: cf.textColor ?? undefined,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setFontFamily failed:\", e);\n }\n },\n\n setFontSize: (size) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: size,\n textColor: cf.textColor ?? undefined,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setFontSize failed:\", e);\n }\n },\n\n setTextColor: (color) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: cf.fontSize ?? undefined,\n textColor: color,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setTextColor failed:\", e);\n }\n },\n\n setHighlightColor: (color) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: cf.fontSize ?? undefined,\n textColor: cf.textColor ?? undefined,\n highlightColor: color,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n\n const hasTextRange =\n selection.textStartOffset != null &&\n selection.textEndOffset != null &&\n selection.textStartOffset < selection.textEndOffset;\n\n if (hasTextRange) {\n para.applyCharFormatToRange(selection.textStartOffset!, selection.textEndOffset!, charPrIdRef);\n } else {\n para.charPrIdRef = charPrIdRef;\n }\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setHighlightColor failed:\", e);\n }\n },\n\n setAlignment: (alignment) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment,\n lineSpacingValue: Math.round(pf.lineSpacing * 100),\n baseParaPrId: (() => {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return undefined;\n const para = section.paragraphs[selection.paragraphIndex];\n return para?.paraPrIdRef ?? undefined;\n })(),\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setAlignment failed:\", e);\n }\n },\n\n setLineSpacing: (spacing) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment: pf.alignment,\n lineSpacingValue: Math.round(spacing * 100),\n baseParaPrId: (() => {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return undefined;\n const para = section.paragraphs[selection.paragraphIndex];\n return para?.paraPrIdRef ?? undefined;\n })(),\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setLineSpacing failed:\", e);\n }\n },\n\n splitParagraph: (sectionIndex, paragraphIndex, offset) => {\n const { doc } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const para = section.paragraphs[paragraphIndex];\n if (!para) return;\n const fullText = para.text;\n const before = fullText.substring(0, offset);\n const after = fullText.substring(offset);\n\n // Update current paragraph text\n para.text = before;\n\n // Insert new paragraph after current one\n doc.insertParagraphAt(sectionIndex, paragraphIndex + 1, after, {\n paraPrIdRef: para.paraPrIdRef ?? undefined,\n charPrIdRef: para.charPrIdRef ?? undefined,\n });\n\n // Move selection to the new paragraph\n set({\n selection: {\n sectionIndex,\n paragraphIndex: paragraphIndex + 1,\n type: \"paragraph\",\n },\n });\n get().rebuild();\n } catch (e) {\n console.error(\"splitParagraph failed:\", e);\n }\n },\n\n mergeParagraphWithPrevious: (sectionIndex, paragraphIndex) => {\n const { doc } = get();\n if (!doc) return;\n if (paragraphIndex <= 0) return;\n try {\n get().pushUndo();\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const prevPara = section.paragraphs[paragraphIndex - 1];\n const currPara = section.paragraphs[paragraphIndex];\n if (!prevPara || !currPara) return;\n\n const prevText = prevPara.text;\n const currText = currPara.text;\n\n // Merge text into previous paragraph\n prevPara.text = prevText + currText;\n\n // Remove current paragraph\n doc.removeParagraph(sectionIndex, paragraphIndex);\n\n // Move selection to previous paragraph\n set({\n selection: {\n sectionIndex,\n paragraphIndex: paragraphIndex - 1,\n type: \"paragraph\",\n },\n });\n get().rebuild();\n } catch (e) {\n console.error(\"mergeParagraphWithPrevious failed:\", e);\n }\n },\n\n pushUndo: () => {\n const { doc, selection, undoStack } = get();\n if (!doc) return;\n try {\n const sections = doc.oxml.sections;\n const headers = doc.oxml.headers;\n const entry: UndoEntry = {\n sectionElements: sections.map((s) => s.element.cloneNode(true) as Element),\n headerElements: headers.map((h) => h.element.cloneNode(true) as Element),\n selection: selection ? { ...selection } : null,\n };\n // Limit stack size to 50\n const newStack = undoStack.length >= 50\n ? [...undoStack.slice(undoStack.length - 49), entry]\n : [...undoStack, entry];\n set({ undoStack: newStack, redoStack: [] });\n } catch (e) {\n console.error(\"pushUndo failed:\", e);\n }\n },\n\n undo: () => {\n const { doc, selection, undoStack, redoStack } = get();\n if (!doc || undoStack.length === 0) return;\n try {\n const sections = doc.oxml.sections;\n const headers = doc.oxml.headers;\n\n // Save current state to redo stack\n const currentEntry: UndoEntry = {\n sectionElements: sections.map((s) => s.element.cloneNode(true) as Element),\n headerElements: headers.map((h) => h.element.cloneNode(true) as Element),\n selection: selection ? { ...selection } : null,\n };\n\n // Pop from undo stack\n const entry = undoStack[undoStack.length - 1]!;\n const newUndoStack = undoStack.slice(0, -1);\n\n // Restore section elements\n sections.forEach((s, i) => {\n if (entry.sectionElements[i]) {\n s.replaceElement(entry.sectionElements[i]!);\n }\n });\n // Restore header elements\n headers.forEach((h, i) => {\n if (entry.headerElements[i]) {\n h.replaceElement(entry.headerElements[i]!);\n }\n });\n\n doc.oxml.invalidateCharPropertyCache();\n set({\n undoStack: newUndoStack,\n redoStack: [...redoStack, currentEntry],\n selection: entry.selection,\n });\n get().rebuild();\n } catch (e) {\n console.error(\"undo failed:\", e);\n }\n },\n\n redo: () => {\n const { doc, selection, undoStack, redoStack } = get();\n if (!doc || redoStack.length === 0) return;\n try {\n const sections = doc.oxml.sections;\n const headers = doc.oxml.headers;\n\n // Save current state to undo stack\n const currentEntry: UndoEntry = {\n sectionElements: sections.map((s) => s.element.cloneNode(true) as Element),\n headerElements: headers.map((h) => h.element.cloneNode(true) as Element),\n selection: selection ? { ...selection } : null,\n };\n\n // Pop from redo stack\n const entry = redoStack[redoStack.length - 1]!;\n const newRedoStack = redoStack.slice(0, -1);\n\n // Restore section elements\n sections.forEach((s, i) => {\n if (entry.sectionElements[i]) {\n s.replaceElement(entry.sectionElements[i]!);\n }\n });\n // Restore header elements\n headers.forEach((h, i) => {\n if (entry.headerElements[i]) {\n h.replaceElement(entry.headerElements[i]!);\n }\n });\n\n doc.oxml.invalidateCharPropertyCache();\n set({\n undoStack: [...undoStack, currentEntry],\n redoStack: newRedoStack,\n selection: entry.selection,\n });\n get().rebuild();\n } catch (e) {\n console.error(\"redo failed:\", e);\n }\n },\n\n deleteBlock: (sectionIndex, paragraphIndex) => {\n const { doc } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n doc.removeParagraph(sectionIndex, paragraphIndex);\n // Adjust selection if it pointed at or after the deleted block\n const { selection } = get();\n if (selection && selection.sectionIndex === sectionIndex) {\n if (selection.paragraphIndex === paragraphIndex) {\n set({ selection: null });\n } else if (selection.paragraphIndex > paragraphIndex) {\n set({\n selection: {\n ...selection,\n paragraphIndex: selection.paragraphIndex - 1,\n },\n });\n }\n }\n get().rebuild();\n } catch (e) {\n console.error(\"deleteBlock failed:\", e);\n }\n },\n\n insertBlockAt: (sectionIndex, paragraphIndex, text = \"\") => {\n const { doc } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n doc.insertParagraphAt(sectionIndex, paragraphIndex, text);\n // Shift selection if it's at or after the insertion point\n const { selection } = get();\n if (\n selection &&\n selection.sectionIndex === sectionIndex &&\n selection.paragraphIndex >= paragraphIndex\n ) {\n set({\n selection: {\n ...selection,\n paragraphIndex: selection.paragraphIndex + 1,\n },\n });\n }\n get().rebuild();\n } catch (e) {\n console.error(\"insertBlockAt failed:\", e);\n }\n },\n\n addParagraph: (text = \"\") => {\n const { doc } = get();\n if (!doc) return;\n try {\n doc.addParagraph(text);\n get().rebuild();\n } catch (e) {\n console.error(\"addParagraph failed:\", e);\n }\n },\n\n addTable: (sectionIndex, paragraphIndex, rows, cols) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const para = section.paragraphs[paragraphIndex];\n if (!para) return;\n para.addTable(rows, cols);\n get().rebuild();\n } catch (e) {\n console.error(\"addTable failed:\", e);\n }\n },\n\n insertImage: (data, mediaType, widthMm, heightMm) => {\n const { doc } = get();\n if (!doc) return;\n try {\n doc.addImage(data, { mediaType, widthMm, heightMm });\n get().rebuild();\n } catch (e) {\n console.error(\"insertImage failed:\", e);\n }\n },\n\n insertColumnBreak: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const para = doc.addParagraph(\"\");\n para.columnBreak = true;\n get().rebuild();\n } catch (e) {\n console.error(\"insertColumnBreak failed:\", e);\n }\n },\n\n insertPageBreak: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const para = doc.addParagraph(\"\");\n para.pageBreak = true;\n get().rebuild();\n } catch (e) {\n console.error(\"insertPageBreak failed:\", e);\n }\n },\n\n // Image editing actions\n updatePictureSize: (widthMm, heightMm) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.objectType !== \"image\") return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n try {\n para.setPictureSize(selection.imageIndex ?? 0, mmToHwp(widthMm), mmToHwp(heightMm));\n get().rebuild();\n } catch (e) {\n console.error(\"updatePictureSize failed:\", e);\n }\n },\n\n resizeImage: (deltaWidthHwp, deltaHeightHwp) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.objectType !== \"image\") return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const imgIdx = selection.imageIndex ?? 0;\n const pics = para.pictures;\n const pic = pics[imgIdx];\n if (!pic) return;\n try {\n get().pushUndo();\n // Read current size from curSz\n const vm = get().viewModel;\n const imgVM = vm?.sections[selection.sectionIndex]?.paragraphs[selection.paragraphIndex]?.images[imgIdx];\n if (!imgVM) return;\n const newW = Math.max(imgVM.widthHwp + deltaWidthHwp, 200);\n const newH = Math.max(imgVM.heightHwp + deltaHeightHwp, 200);\n para.setPictureSize(imgIdx, newW, newH);\n get().rebuild();\n } catch (e) {\n console.error(\"resizeImage failed:\", e);\n }\n },\n\n setImageOutMargin: (margins) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.objectType !== \"image\") return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const imgIdx = selection.imageIndex ?? 0;\n try {\n get().pushUndo();\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n para.setPictureOutMargin(imgIdx, converted);\n get().rebuild();\n } catch (e) {\n console.error(\"setImageOutMargin failed:\", e);\n }\n },\n\n // Table editing actions\n setTablePageBreak: (mode) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n table.pageBreak = mode;\n get().rebuild();\n } catch (e) {\n console.error(\"setTablePageBreak failed:\", e);\n }\n },\n\n setTableRepeatHeader: (repeat) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n table.repeatHeader = repeat;\n get().rebuild();\n } catch (e) {\n console.error(\"setTableRepeatHeader failed:\", e);\n }\n },\n\n setTableSize: (widthMm, heightMm) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n table.setSize(mmToHwp(widthMm), mmToHwp(heightMm));\n get().rebuild();\n } catch (e) {\n console.error(\"setTableSize failed:\", e);\n }\n },\n\n setTableOutMargin: (margins) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n table.setOutMargin(converted);\n get().rebuild();\n } catch (e) {\n console.error(\"setTableOutMargin failed:\", e);\n }\n },\n\n setTableInMargin: (margins) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n table.setInMargin(converted);\n get().rebuild();\n } catch (e) {\n console.error(\"setTableInMargin failed:\", e);\n }\n },\n\n resizeTableColumn: (sectionIdx, paraIdx, tableIdx, colIdx, deltaHwp) => {\n const { doc } = get();\n if (!doc) return;\n const section = doc.sections[sectionIdx];\n if (!section) return;\n const para = section.paragraphs[paraIdx];\n if (!para) return;\n const table = para.tables[tableIdx];\n if (!table) return;\n try {\n get().pushUndo();\n const colCount = table.columnCount;\n // Get current widths via the grid\n const grid = table.getCellMap();\n const widths: number[] = [];\n for (let c = 0; c < colCount; c++) {\n const pos = grid[0]?.[c];\n widths.push(pos ? pos.cell.width : 0);\n }\n // Adjust left column (colIdx) and right column (colIdx+1)\n if (colIdx < colCount - 1) {\n const newLeft = Math.max(widths[colIdx]! + deltaHwp, 200);\n const newRight = Math.max(widths[colIdx + 1]! - deltaHwp, 200);\n table.setColumnWidth(colIdx, newLeft);\n table.setColumnWidth(colIdx + 1, newRight);\n } else {\n // Last column: adjust its width and the table total width\n const newWidth = Math.max(widths[colIdx]! + deltaHwp, 200);\n table.setColumnWidth(colIdx, newWidth);\n const totalWidth = widths.reduce((a, b) => a + b, 0) + deltaHwp;\n table.setSize(Math.max(totalWidth, 200));\n }\n get().rebuild();\n } catch (e) {\n console.error(\"resizeTableColumn failed:\", e);\n }\n },\n\n setSelectedCellsSize: (widthMm, heightMm) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.type !== \"cell\" || selection.tableIndex == null) return;\n\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n\n try {\n get().pushUndo();\n\n // Determine the selected range\n const startRow = Math.min(selection.row ?? 0, selection.endRow ?? selection.row ?? 0);\n const endRow = Math.max(selection.row ?? 0, selection.endRow ?? selection.row ?? 0);\n const startCol = Math.min(selection.col ?? 0, selection.endCol ?? selection.col ?? 0);\n const endCol = Math.max(selection.col ?? 0, selection.endCol ?? selection.col ?? 0);\n\n const grid = table.getCellMap();\n\n // Set width for selected columns\n if (widthMm != null) {\n const widthHwp = mmToHwp(widthMm);\n const processedCols = new Set<number>();\n for (let c = startCol; c <= endCol; c++) {\n if (!processedCols.has(c)) {\n table.setColumnWidth(c, widthHwp);\n processedCols.add(c);\n }\n }\n }\n\n // Set height for selected rows (update each cell's height)\n if (heightMm != null) {\n const heightHwp = mmToHwp(heightMm);\n const processedCells = new Set<Element>();\n for (let r = startRow; r <= endRow; r++) {\n for (let c = startCol; c <= endCol; c++) {\n const pos = grid[r]?.[c];\n if (pos && !processedCells.has(pos.cell.element)) {\n pos.cell.setSize(undefined, heightHwp);\n processedCells.add(pos.cell.element);\n }\n }\n }\n }\n\n get().rebuild();\n } catch (e) {\n console.error(\"setSelectedCellsSize failed:\", e);\n }\n },\n\n mergeSelectedCells: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.type !== \"cell\") return;\n if (selection.row == null || selection.col == null) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const tbl = para.tables[selection.tableIndex ?? 0];\n if (!tbl) return;\n\n const startRow = Math.min(selection.row, selection.endRow ?? selection.row);\n const endRow = Math.max(selection.row, selection.endRow ?? selection.row);\n const startCol = Math.min(selection.col, selection.endCol ?? selection.col);\n const endCol = Math.max(selection.col, selection.endCol ?? selection.col);\n if (startRow === endRow && startCol === endCol) return; // Single cell, nothing to merge\n\n get().pushUndo();\n tbl.mergeCells(startRow, startCol, endRow, endCol);\n // Update selection to just the merged cell\n set({\n selection: { ...selection, row: startRow, col: startCol, endRow: startRow, endCol: startCol },\n });\n get().rebuild();\n } catch (e) {\n console.error(\"mergeSelectedCells failed:\", e);\n }\n },\n\n unmergeSelectedCells: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.type !== \"cell\") return;\n if (selection.row == null || selection.col == null) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const tbl = para.tables[selection.tableIndex ?? 0];\n if (!tbl) return;\n\n const cell = tbl.cell(selection.row, selection.col);\n if (!cell) return;\n const [rowSpan, colSpan] = cell.span;\n if (rowSpan === 1 && colSpan === 1) return; // Not merged\n\n get().pushUndo();\n tbl.unmergeCells(selection.row, selection.col);\n // Expand selection to cover all unmerged cells\n set({\n selection: {\n ...selection,\n endRow: selection.row + rowSpan - 1,\n endCol: selection.col + colSpan - 1,\n },\n });\n get().rebuild();\n } catch (e) {\n console.error(\"unmergeSelectedCells failed:\", e);\n }\n },\n\n setFirstLineIndent: (valueHwp) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment: pf.alignment,\n lineSpacingValue: Math.round(pf.lineSpacing * 100),\n indent: valueHwp,\n marginLeft: pf.indentLeft,\n baseParaPrId: para.paraPrIdRef ?? undefined,\n });\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setFirstLineIndent failed:\", e);\n }\n },\n\n setLeftIndent: (valueHwp) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment: pf.alignment,\n lineSpacingValue: Math.round(pf.lineSpacing * 100),\n marginLeft: valueHwp,\n indent: pf.firstLineIndent,\n baseParaPrId: para.paraPrIdRef ?? undefined,\n });\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setLeftIndent failed:\", e);\n }\n },\n\n setPageNumbering: (opts) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n get().pushUndo();\n const props = section.properties;\n if (opts.position === \"none\") {\n // Remove page number text by setting empty header/footer\n props.setHeaderText(\"\");\n props.setFooterText(\"\");\n } else if (opts.position.startsWith(\"header\")) {\n props.setFooterText(\"\"); // clear footer\n const pageNumText = `- {{page}} -`;\n props.setHeaderText(pageNumText);\n } else if (opts.position.startsWith(\"footer\")) {\n props.setHeaderText(\"\"); // clear header\n const pageNumText = `- {{page}} -`;\n props.setFooterText(pageNumText);\n }\n // Set start number if > 0\n if (opts.startNumber > 0) {\n section.properties.setStartNumbering({ page: opts.startNumber });\n }\n get().rebuild();\n } catch (e) {\n console.error(\"setPageNumbering failed:\", e);\n }\n },\n\n // Footnote / Endnote\n insertFootnote: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n try {\n get().pushUndo();\n // Insert a footnote element into the paragraph's run\n // Since the core doesn't have a dedicated API, we'll add via raw XML manipulation\n const paraEl = para.element;\n const NS = \"http://www.hancom.co.kr/hwpml/2011/paragraph\";\n const runs = paraEl.getElementsByTagNameNS(NS, \"run\");\n const lastRun = runs.length > 0 ? runs[runs.length - 1]! : null;\n if (lastRun) {\n const fnEl = paraEl.ownerDocument.createElementNS(NS, \"hp:footNote\");\n // Count existing footnotes in the section to get the marker number\n const existingFn = section.element.getElementsByTagNameNS(NS, \"footNote\");\n const fnNum = existingFn.length + 1;\n fnEl.setAttribute(\"number\", String(fnNum));\n // Add a sub-paragraph with placeholder text\n const subPara = paraEl.ownerDocument.createElementNS(NS, \"hp:subPara\");\n const subRun = paraEl.ownerDocument.createElementNS(NS, \"hp:run\");\n const tEl = paraEl.ownerDocument.createElementNS(NS, \"hp:t\");\n tEl.textContent = `각주 ${fnNum}`;\n subRun.appendChild(tEl);\n subPara.appendChild(subRun);\n fnEl.appendChild(subPara);\n lastRun.appendChild(fnEl);\n }\n get().rebuild();\n } catch (e) {\n console.error(\"insertFootnote failed:\", e);\n }\n },\n\n insertEndnote: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n try {\n get().pushUndo();\n const paraEl = para.element;\n const NS = \"http://www.hancom.co.kr/hwpml/2011/paragraph\";\n const runs = paraEl.getElementsByTagNameNS(NS, \"run\");\n const lastRun = runs.length > 0 ? runs[runs.length - 1]! : null;\n if (lastRun) {\n const enEl = paraEl.ownerDocument.createElementNS(NS, \"hp:endNote\");\n const existingEn = section.element.getElementsByTagNameNS(NS, \"endNote\");\n const enNum = existingEn.length + 1;\n enEl.setAttribute(\"number\", String(enNum));\n const subPara = paraEl.ownerDocument.createElementNS(NS, \"hp:subPara\");\n const subRun = paraEl.ownerDocument.createElementNS(NS, \"hp:run\");\n const tEl = paraEl.ownerDocument.createElementNS(NS, \"hp:t\");\n tEl.textContent = `미주 ${enNum}`;\n subRun.appendChild(tEl);\n subPara.appendChild(subRun);\n enEl.appendChild(subPara);\n lastRun.appendChild(enEl);\n }\n get().rebuild();\n } catch (e) {\n console.error(\"insertEndnote failed:\", e);\n }\n },\n\n setWatermarkText: (text) => {\n const vm = get().viewModel;\n if (!vm) return;\n // Watermark is a UI-only feature stored in the view model\n set({\n viewModel: { ...vm, watermarkText: text },\n revision: get().revision + 1,\n });\n },\n\n // Page setup actions\n updatePageSize: (width, height) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n section.properties.setPageSize({ width: mmToHwp(width), height: mmToHwp(height) });\n get().rebuild();\n } catch (e) {\n console.error(\"updatePageSize failed:\", e);\n }\n },\n\n updatePageMargins: (margins) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n section.properties.setPageMargins(converted);\n get().rebuild();\n } catch (e) {\n console.error(\"updatePageMargins failed:\", e);\n }\n },\n\n updatePageOrientation: (orientation) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n const ps = section.properties.pageSize;\n if (orientation === \"LANDSCAPE\" && ps.width < ps.height) {\n section.properties.setPageSize({ width: ps.height, height: ps.width, orientation: \"LANDSCAPE\" });\n } else if (orientation === \"PORTRAIT\" && ps.width > ps.height) {\n section.properties.setPageSize({ width: ps.height, height: ps.width, orientation: \"PORTRAIT\" });\n } else {\n section.properties.setPageSize({ orientation });\n }\n get().rebuild();\n } catch (e) {\n console.error(\"updatePageOrientation failed:\", e);\n }\n },\n\n setColumnCount: (colCount, gapMm) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n get().pushUndo();\n section.properties.setColumnLayout({\n colCount: Math.max(1, colCount),\n sameGap: gapMm != null ? mmToHwp(gapMm) : undefined,\n });\n get().rebuild();\n } catch (e) {\n console.error(\"setColumnCount failed:\", e);\n }\n },\n\n // File operations\n saveDocument: async () => {\n get().openSaveDialog();\n },\n\n saveDocumentAs: async (filename) => {\n const { doc } = get();\n if (!doc) return;\n try {\n set({ loading: true });\n const bytes = await doc.save();\n const blob = new Blob([bytes as unknown as BlobPart], {\n type: \"application/vnd.hancom.hwpx\",\n });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename.endsWith(\".hwpx\") ? filename : `${filename}.hwpx`;\n a.click();\n URL.revokeObjectURL(url);\n get().closeSaveDialog();\n } catch (e) {\n console.error(\"save failed:\", e);\n set({ error: \"문서 저장에 실패했습니다.\" });\n } finally {\n set({ loading: false });\n }\n },\n\n openSaveDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, saveDialogOpen: true } })),\n\n closeSaveDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, saveDialogOpen: false } })),\n\n // Dialog open/close\n openCharFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charFormatDialogOpen: true } })),\n closeCharFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charFormatDialogOpen: false } })),\n openParaFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, paraFormatDialogOpen: true } })),\n closeParaFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, paraFormatDialogOpen: false } })),\n openBulletNumberDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, bulletNumberDialogOpen: true } })),\n closeBulletNumberDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, bulletNumberDialogOpen: false } })),\n openCharMapDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charMapDialogOpen: true } })),\n closeCharMapDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charMapDialogOpen: false } })),\n\n insertTextAtCursor: (text) => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n get().pushUndo();\n para.text = para.text + text;\n get().rebuild();\n } catch (e) {\n console.error(\"insertTextAtCursor failed:\", e);\n }\n },\n\n insertTab: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n get().pushUndo();\n para.addTab({ charPrIdRef: para.charPrIdRef ?? undefined });\n get().rebuild();\n } catch (e) {\n console.error(\"insertTab failed:\", e);\n }\n },\n\n insertTextBox: (text, widthMm, heightMm) => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n get().pushUndo();\n para.addTextBox(text, {\n width: mmToHwp(widthMm),\n height: mmToHwp(heightMm),\n charPrIdRef: para.charPrIdRef ?? undefined,\n });\n get().rebuild();\n } catch (e) {\n console.error(\"insertTextBox failed:\", e);\n }\n },\n}));\n","/**\n * EditorViewModel — pure data structures derived from HwpxDocument for rendering.\n */\n\nimport type {\n HwpxDocument,\n RunStyle,\n HwpxTableGridPosition,\n} from \"@ubermensch1218/hwpxcore\";\nimport { parseHeaderXml, serializeXml } from \"@ubermensch1218/hwpxcore\";\nimport type { Header, ParagraphProperty } from \"@ubermensch1218/hwpxcore\";\nimport { hwpToPx } from \"./hwp-units\";\nimport { extractImages } from \"./image-extractor\";\n\n// ── ViewModel types ────────────────────────────────────────────────────────\n\nexport interface RunVM {\n text: string;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n color: string | null;\n fontFamily: string | null;\n fontSize: number | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n charPrIdRef: string | null;\n hasTab?: boolean; // true if this run contains a tab character\n hasFwSpace?: boolean; // true if this run is a full-width space\n hasLineBreak?: boolean; // true if this run is a line break\n hyperlink?: string; // URL if this run is inside a hyperlink\n}\n\nexport interface MarginVM {\n top: number;\n bottom: number;\n left: number;\n right: number;\n}\n\nexport interface TableCellVM {\n row: number;\n col: number;\n rowSpan: number;\n colSpan: number;\n widthPx: number;\n heightPx: number;\n text: string;\n isAnchor: boolean; // true if this is the top-left of a merged region\n}\n\nexport interface TableVM {\n rowCount: number;\n colCount: number;\n cells: TableCellVM[][]; // 2D grid [row][col], non-anchor cells have isAnchor=false\n tableIndex: number; // index within the paragraph\n pageBreak: string; // \"CELL\", \"NONE\", etc.\n repeatHeader: boolean;\n widthHwp: number;\n heightHwp: number;\n outMargin: MarginVM; // table outer margin in hwpUnits\n inMargin: MarginVM; // table inner cell margin in hwpUnits\n columnWidths: number[]; // per-column width in hwpUnits\n}\n\nexport interface ImageVM {\n dataUrl: string;\n widthPx: number;\n heightPx: number;\n widthHwp: number;\n heightHwp: number;\n binaryItemIdRef: string;\n outMargin: MarginVM;\n}\n\nexport interface EquationVM {\n script: string; // HWP equation script\n widthPx: number;\n heightPx: number;\n textColor: string;\n font: string;\n baseLine: number;\n}\n\nexport interface TextBoxVM {\n text: string;\n widthPx: number;\n heightPx: number;\n widthHwp: number;\n heightHwp: number;\n x: number;\n y: number;\n borderColor: string;\n fillColor: string;\n textBoxIndex: number;\n}\n\nexport interface ParagraphVM {\n runs: RunVM[];\n tables: TableVM[];\n images: ImageVM[];\n textBoxes: TextBoxVM[];\n equations: EquationVM[];\n alignment: string;\n lineSpacing: number;\n spacingBefore: number;\n spacingAfter: number;\n firstLineIndent: number;\n marginLeftPx: number;\n marginRightPx: number;\n paragraphIndex: number; // global index across all sections\n defaultFontSize: number | null;\n defaultFontFamily: string | null;\n}\n\nexport interface FootnoteVM {\n marker: string; // e.g. \"1\", \"2\", ...\n text: string;\n}\n\nexport interface ColumnLayoutVM {\n colCount: number;\n sameGap: number; // gap in px\n type: string; // \"NEWSPAPER\", \"BALANCED\", etc.\n}\n\nexport interface PageNumVM {\n pos: string; // \"BOTTOM_CENTER\", \"TOP_CENTER\", etc.\n formatType: string; // \"DIGIT\", \"ROMAN\", etc.\n sideChar: string; // e.g. \"-\" for \"- 1 -\"\n}\n\nexport interface PageBorderFillVM {\n type: string; // \"BOTH\", \"EVEN\", \"ODD\"\n borderFillIdRef: string;\n textBorder: string; // \"PAPER\", \"CONTENT\"\n fillArea: string; // \"PAPER\", \"CONTENT\"\n}\n\nexport interface SectionVM {\n pageWidthPx: number;\n pageHeightPx: number;\n marginTopPx: number;\n marginBottomPx: number;\n marginLeftPx: number;\n marginRightPx: number;\n headerHeightPx: number;\n footerHeightPx: number;\n paragraphs: ParagraphVM[];\n sectionIndex: number;\n headerText: string;\n footerText: string;\n footnotes: FootnoteVM[];\n endnotes: FootnoteVM[];\n columnLayout: ColumnLayoutVM;\n pageNum: PageNumVM | null;\n pageBorderFill: PageBorderFillVM | null;\n}\n\nexport interface EditorViewModel {\n sections: SectionVM[];\n watermarkText: string;\n}\n\n// ── Builder ────────────────────────────────────────────────────────────────\n\nfunction extractRunStyle(\n style: RunStyle | null,\n doc?: HwpxDocument | null,\n): {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n color: string | null;\n fontFamily: string | null;\n fontSize: number | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n} {\n if (!style) {\n return {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n color: null,\n fontFamily: null,\n fontSize: null,\n highlightColor: null,\n letterSpacing: null,\n };\n }\n\n const bold = style.attributes[\"bold\"] === \"1\";\n const italic = style.attributes[\"italic\"] === \"1\";\n\n // Check underline child element\n const underlineChild = style.childAttributes[\"underline\"];\n const underline =\n underlineChild != null &&\n underlineChild[\"type\"] != null &&\n underlineChild[\"type\"] !== \"NONE\";\n\n // Strikethrough\n const strikeChild = style.childAttributes[\"strikeout\"];\n const strikethrough =\n strikeChild != null &&\n strikeChild[\"type\"] != null &&\n strikeChild[\"type\"] !== \"NONE\";\n\n const color = style.attributes[\"textColor\"] ?? null;\n\n // Highlight\n const highlightColor = style.attributes[\"shadeColor\"] ?? null;\n\n // Font family — resolve numeric ID to face name\n let fontFamily: string | null = null;\n const fontRef = style.childAttributes[\"fontRef\"];\n if (fontRef) {\n const hangulId = fontRef[\"hangul\"] ?? fontRef[\"latin\"] ?? null;\n if (hangulId != null && doc) {\n fontFamily = doc.fontFaceName(hangulId) ?? hangulId;\n } else {\n fontFamily = hangulId;\n }\n }\n\n // Font size (height in hwpUnits / 100 = pt)\n let fontSize: number | null = null;\n const sizeStr = style.attributes[\"height\"];\n if (sizeStr) {\n const hwpVal = parseInt(sizeStr, 10);\n if (!isNaN(hwpVal)) fontSize = hwpVal / 100;\n }\n\n // Letter spacing\n let letterSpacing: number | null = null;\n const spacingStr = style.attributes[\"spacing\"];\n if (spacingStr) {\n const val = parseInt(spacingStr, 10);\n if (!isNaN(val) && val !== 0) letterSpacing = val;\n }\n\n return { bold, italic, underline, strikethrough, color, fontFamily, fontSize, highlightColor, letterSpacing };\n}\n\n/** Find equation elements inside a run. */\nfunction findEquationRefs(\n runElement: Element,\n): { script: string; width: number; height: number; textColor: string; font: string; baseLine: number }[] {\n const results: { script: string; width: number; height: number; textColor: string; font: string; baseLine: number }[] = [];\n\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"equation\") continue;\n\n let width = 0;\n let height = 0;\n let script = \"\";\n const textColor = el.getAttribute(\"textColor\") ?? \"#000000\";\n const font = el.getAttribute(\"font\") ?? \"HancomEQN\";\n const baseLine = parseInt(el.getAttribute(\"baseLine\") ?? \"85\", 10);\n\n const eqChildren = el.childNodes;\n for (let j = 0; j < eqChildren.length; j++) {\n const ec = eqChildren.item(j);\n if (!ec || ec.nodeType !== 1) continue;\n const eel = ec as Element;\n const eName = eel.localName || eel.nodeName.split(\":\").pop() || \"\";\n\n if (eName === \"sz\") {\n width = parseInt(eel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(eel.getAttribute(\"height\") ?? \"0\", 10);\n } else if (eName === \"script\") {\n script = eel.textContent ?? \"\";\n }\n }\n\n results.push({ script, width, height, textColor, font, baseLine });\n }\n\n return results;\n}\n\n/** Find drawText (text box) elements inside a run. */\nfunction findTextBoxRefs(\n runElement: Element,\n): { text: string; width: number; height: number; x: number; y: number; borderColor: string; fillColor: string }[] {\n const results: { text: string; width: number; height: number; x: number; y: number; borderColor: string; fillColor: string }[] = [];\n\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"drawText\") continue;\n\n let width = 0;\n let height = 0;\n let x = 0;\n let y = 0;\n let borderColor = \"#000000\";\n let fillColor = \"#FFFFFF\";\n let text = \"\";\n\n const boxChildren = el.childNodes;\n for (let j = 0; j < boxChildren.length; j++) {\n const bc = boxChildren.item(j);\n if (!bc || bc.nodeType !== 1) continue;\n const bel = bc as Element;\n const bName = bel.localName || bel.nodeName.split(\":\").pop() || \"\";\n\n if (bName === \"sz\") {\n width = parseInt(bel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(bel.getAttribute(\"height\") ?? \"0\", 10);\n } else if (bName === \"pos\") {\n x = parseInt(bel.getAttribute(\"horzOffset\") ?? \"0\", 10);\n y = parseInt(bel.getAttribute(\"vertOffset\") ?? \"0\", 10);\n } else if (bName === \"lineShape\") {\n borderColor = bel.getAttribute(\"color\") ?? \"#000000\";\n }\n }\n\n // Get fill color from fillBrush/winBrush\n const fillBrushes = el.getElementsByTagName(\"*\");\n for (let k = 0; k < fillBrushes.length; k++) {\n const fb = fillBrushes.item(k);\n if (!fb) continue;\n const fbName = fb.localName || fb.nodeName.split(\":\").pop() || \"\";\n if (fbName === \"winBrush\") {\n fillColor = fb.getAttribute(\"faceColor\") ?? \"#FFFFFF\";\n }\n }\n\n // Get text from sub-paragraphs\n const textEls = el.getElementsByTagName(\"*\");\n for (let k = 0; k < textEls.length; k++) {\n const te = textEls.item(k);\n if (!te) continue;\n const teName = te.localName || te.nodeName.split(\":\").pop() || \"\";\n if (teName === \"t\") {\n text += te.textContent ?? \"\";\n }\n }\n\n results.push({ text, width, height, x, y, borderColor, fillColor });\n }\n\n return results;\n}\n\n/** Find binaryItemIDRef from a picture element inside a run. */\nfunction findPictureRefs(\n runElement: Element,\n): { binaryItemIdRef: string; width: number; height: number }[] {\n const results: { binaryItemIdRef: string; width: number; height: number }[] = [];\n\n // Look for <pic> elements inside the run\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"pic\") continue;\n\n // Get size from curSz\n let width = 0;\n let height = 0;\n const picChildren = el.childNodes;\n for (let j = 0; j < picChildren.length; j++) {\n const pc = picChildren.item(j);\n if (!pc || pc.nodeType !== 1) continue;\n const pel = pc as Element;\n const pName = pel.localName || pel.nodeName.split(\":\").pop() || \"\";\n\n if (pName === \"curSz\") {\n width = parseInt(pel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(pel.getAttribute(\"height\") ?? \"0\", 10);\n }\n\n // Find img element inside pic (possibly nested in renderingInfo or directly)\n if (pName === \"img\") {\n const ref = pel.getAttribute(\"binaryItemIDRef\");\n if (ref) results.push({ binaryItemIdRef: ref, width, height });\n }\n }\n\n // Also search deeper for img (might be in a sub-element)\n const allDescendants = el.getElementsByTagName(\"*\");\n for (let k = 0; k < allDescendants.length; k++) {\n const desc = allDescendants.item(k);\n if (!desc) continue;\n const dName = desc.localName || desc.nodeName.split(\":\").pop() || \"\";\n if (dName === \"img\") {\n const ref = desc.getAttribute(\"binaryItemIDRef\");\n if (ref && !results.some((r) => r.binaryItemIdRef === ref)) {\n results.push({ binaryItemIdRef: ref, width, height });\n }\n }\n }\n }\n\n return results;\n}\n\n/** Parse the header element to get ParagraphProperty lookup. */\nfunction buildParaPrLookup(doc: HwpxDocument): Map<string, ParagraphProperty> {\n const lookup = new Map<string, ParagraphProperty>();\n try {\n const headers = doc.headers;\n if (headers.length === 0) return lookup;\n const headerEl = headers[0]!.element;\n const xml = serializeXml(headerEl);\n const parsed: Header = parseHeaderXml(xml);\n if (!parsed.refList?.paraProperties) return lookup;\n for (const prop of parsed.refList.paraProperties.properties) {\n if (prop.rawId) lookup.set(prop.rawId, prop);\n if (prop.id != null) lookup.set(String(prop.id), prop);\n }\n } catch {\n // ignore parse errors\n }\n return lookup;\n}\n\nexport function buildViewModel(doc: HwpxDocument): EditorViewModel {\n const imageMap = extractImages(doc.package);\n const paraPrLookup = buildParaPrLookup(doc);\n const sections: SectionVM[] = [];\n\n let globalParaIndex = 0;\n\n for (let sIdx = 0; sIdx < doc.sections.length; sIdx++) {\n const section = doc.sections[sIdx]!;\n const props = section.properties;\n const pageSize = props.pageSize;\n const pageMargins = props.pageMargins;\n\n // Extract header/footer text\n let headerText = \"\";\n let footerText = \"\";\n try {\n const hdr = props.getHeader(\"BOTH\");\n if (hdr) headerText = hdr.text;\n } catch { /* no header */ }\n try {\n const ftr = props.getFooter(\"BOTH\");\n if (ftr) footerText = ftr.text;\n } catch { /* no footer */ }\n\n // Extract footnotes from paragraph annotation elements\n const footnotes: FootnoteVM[] = [];\n const endnotes: FootnoteVM[] = [];\n try {\n const sectionEl = section.element;\n const allEls = sectionEl.getElementsByTagName(\"*\");\n let fnIdx = 1;\n let enIdx = 1;\n for (let k = 0; k < allEls.length; k++) {\n const el = allEls.item(k);\n if (!el) continue;\n const ln = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (ln === \"footNote\" || ln === \"endNote\") {\n // Extract text from sub paragraphs\n const subParas = el.getElementsByTagName(\"*\");\n let noteText = \"\";\n for (let m = 0; m < subParas.length; m++) {\n const sp = subParas.item(m);\n if (!sp) continue;\n const spName = sp.localName || sp.nodeName.split(\":\").pop() || \"\";\n if (spName === \"t\") noteText += sp.textContent ?? \"\";\n }\n if (ln === \"footNote\") {\n footnotes.push({ marker: String(fnIdx++), text: noteText });\n } else {\n endnotes.push({ marker: String(enIdx++), text: noteText });\n }\n }\n }\n } catch { /* ignore */ }\n\n // Extract column layout\n let columnLayoutVM: ColumnLayoutVM = { colCount: 1, sameGap: 0, type: \"NEWSPAPER\" };\n try {\n const colLayout = props.columnLayout;\n columnLayoutVM = {\n colCount: colLayout.colCount,\n sameGap: hwpToPx(colLayout.sameGap),\n type: colLayout.type,\n };\n } catch { /* ignore */ }\n\n // Extract page numbering\n let pageNumVM: PageNumVM | null = null;\n try {\n const sectionEl = section.element;\n const pageNumEls = sectionEl.getElementsByTagName(\"*\");\n for (let k = 0; k < pageNumEls.length; k++) {\n const el = pageNumEls.item(k);\n if (!el) continue;\n const ln = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (ln === \"pageNum\") {\n pageNumVM = {\n pos: el.getAttribute(\"pos\") ?? \"BOTTOM_CENTER\",\n formatType: el.getAttribute(\"formatType\") ?? \"DIGIT\",\n sideChar: el.getAttribute(\"sideChar\") ?? \"\",\n };\n break;\n }\n }\n } catch { /* ignore */ }\n\n // Extract page border fill\n let pageBorderFillVM: PageBorderFillVM | null = null;\n try {\n const sectionEl = section.element;\n const borderFillEls = sectionEl.getElementsByTagName(\"*\");\n for (let k = 0; k < borderFillEls.length; k++) {\n const el = borderFillEls.item(k);\n if (!el) continue;\n const ln = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (ln === \"pageBorderFill\") {\n const type = el.getAttribute(\"type\") ?? \"BOTH\";\n // Use the BOTH type or first found\n if (type === \"BOTH\" || !pageBorderFillVM) {\n pageBorderFillVM = {\n type,\n borderFillIdRef: el.getAttribute(\"borderFillIDRef\") ?? \"0\",\n textBorder: el.getAttribute(\"textBorder\") ?? \"PAPER\",\n fillArea: el.getAttribute(\"fillArea\") ?? \"PAPER\",\n };\n if (type === \"BOTH\") break;\n }\n }\n }\n } catch { /* ignore */ }\n\n const sectionVM: SectionVM = {\n pageWidthPx: hwpToPx(pageSize.width),\n pageHeightPx: hwpToPx(pageSize.height),\n marginTopPx: hwpToPx(pageMargins.top),\n marginBottomPx: hwpToPx(pageMargins.bottom),\n marginLeftPx: hwpToPx(pageMargins.left),\n marginRightPx: hwpToPx(pageMargins.right),\n headerHeightPx: hwpToPx(pageMargins.header ?? 0),\n footerHeightPx: hwpToPx(pageMargins.footer ?? 0),\n paragraphs: [],\n sectionIndex: sIdx,\n headerText,\n footerText,\n footnotes,\n endnotes,\n columnLayout: columnLayoutVM,\n pageNum: pageNumVM,\n pageBorderFill: pageBorderFillVM,\n };\n\n const paragraphs = section.paragraphs;\n for (const para of paragraphs) {\n const runs: RunVM[] = [];\n const images: ImageVM[] = [];\n const textBoxes: TextBoxVM[] = [];\n const equations: EquationVM[] = [];\n let currentHyperlink: string | null = null; // Track hyperlink across runs\n\n for (const run of para.runs) {\n const style = run.style;\n const {\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n } = extractRunStyle(style, doc);\n\n // Process run children to handle tabs and text in order\n const runChildren = run.element.childNodes;\n let currentText = \"\";\n let hasTab = false;\n\n for (let i = 0; i < runChildren.length; i++) {\n const child = runChildren.item(i);\n if (!child) continue;\n\n if (child.nodeType === 1) {\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n\n if (localName === \"t\") {\n currentText += el.textContent ?? \"\";\n } else if (localName === \"tab\") {\n // Flush current text if any, then add tab\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n currentText = \"\";\n }\n // Add a tab run\n runs.push({\n text: \"\\t\",\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hasTab: true,\n });\n hasTab = true;\n } else if (localName === \"fwSpace\") {\n // Full-width space (전각 공백)\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n currentText = \"\";\n }\n runs.push({\n text: \"\\u3000\", // Full-width space character\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hasFwSpace: true,\n hyperlink: currentHyperlink ?? undefined,\n });\n } else if (localName === \"lineBreak\") {\n // Line break within paragraph\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n currentText = \"\";\n }\n runs.push({\n text: \"\\n\",\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hasLineBreak: true,\n });\n } else if (localName === \"fieldBegin\") {\n // Start of a field (e.g., hyperlink)\n const fieldType = el.getAttribute(\"type\");\n if (fieldType === \"HYPERLINK\") {\n // Flush current text before hyperlink\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n });\n currentText = \"\";\n }\n // Extract URL from stringParam elements\n const params = el.getElementsByTagName(\"*\");\n for (let pi = 0; pi < params.length; pi++) {\n const param = params.item(pi);\n if (!param) continue;\n const pName = param.localName || param.nodeName.split(\":\").pop() || \"\";\n if (pName === \"stringParam\") {\n const paramName = param.getAttribute(\"name\");\n if (paramName === \"Command\" || paramName === \"Path\") {\n const url = param.textContent?.trim();\n if (url) {\n currentHyperlink = url;\n break;\n }\n }\n }\n }\n }\n } else if (localName === \"fieldEnd\") {\n // End of a field\n if (currentHyperlink && currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink,\n });\n currentText = \"\";\n }\n currentHyperlink = null;\n }\n }\n }\n\n // Flush remaining text\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n }\n\n // If no content was found but run has text, use fallback\n if (runs.length === 0 || (!currentText && !hasTab)) {\n const text = run.text;\n if (text) {\n runs.push({\n text,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n });\n }\n }\n\n // Check for images inside this run\n const picRefs = findPictureRefs(run.element);\n for (let picIdx = 0; picIdx < picRefs.length; picIdx++) {\n const ref = picRefs[picIdx]!;\n const dataUrl = imageMap.get(ref.binaryItemIdRef);\n if (dataUrl) {\n const outMargin = para.getPictureOutMargin(images.length);\n images.push({\n dataUrl,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n widthHwp: ref.width,\n heightHwp: ref.height,\n binaryItemIdRef: ref.binaryItemIdRef,\n outMargin,\n });\n }\n }\n\n // Check for text boxes inside this run\n const textBoxRefs = findTextBoxRefs(run.element);\n for (let tbIdx = 0; tbIdx < textBoxRefs.length; tbIdx++) {\n const ref = textBoxRefs[tbIdx]!;\n textBoxes.push({\n text: ref.text,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n widthHwp: ref.width,\n heightHwp: ref.height,\n x: ref.x,\n y: ref.y,\n borderColor: ref.borderColor,\n fillColor: ref.fillColor,\n textBoxIndex: textBoxes.length,\n });\n }\n\n // Check for equations inside this run\n const equationRefs = findEquationRefs(run.element);\n for (const ref of equationRefs) {\n equations.push({\n script: ref.script,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n textColor: ref.textColor,\n font: ref.font,\n baseLine: ref.baseLine,\n });\n }\n }\n\n // Tables\n const tables: TableVM[] = [];\n const paraTables = para.tables;\n for (let tIdx = 0; tIdx < paraTables.length; tIdx++) {\n const table = paraTables[tIdx]!;\n const rowCount = table.rowCount;\n const colCount = table.columnCount;\n\n let cellGrid: HwpxTableGridPosition[][] = [];\n try {\n cellGrid = table.getCellMap();\n } catch {\n // If grid building fails, skip\n continue;\n }\n\n const cellsVM: TableCellVM[][] = [];\n for (let r = 0; r < rowCount; r++) {\n const row: TableCellVM[] = [];\n for (let c = 0; c < colCount; c++) {\n const pos = cellGrid[r]?.[c];\n if (!pos) {\n row.push({\n row: r,\n col: c,\n rowSpan: 1,\n colSpan: 1,\n widthPx: 0,\n heightPx: 0,\n text: \"\",\n isAnchor: false,\n });\n continue;\n }\n\n const isAnchor = pos.anchor[0] === r && pos.anchor[1] === c;\n row.push({\n row: r,\n col: c,\n rowSpan: pos.span[0],\n colSpan: pos.span[1],\n widthPx: hwpToPx(pos.cell.width),\n heightPx: hwpToPx(pos.cell.height),\n text: isAnchor ? pos.cell.text : \"\",\n isAnchor,\n });\n }\n cellsVM.push(row);\n }\n\n // Compute per-column widths - find a cell with colSpan=1 for each column\n const columnWidths: number[] = [];\n for (let c = 0; c < colCount; c++) {\n let width = 0;\n // First, try to find a cell with colSpan=1 in this column\n for (let r = 0; r < rowCount && width === 0; r++) {\n const pos = cellGrid[r]?.[c];\n if (pos && pos.anchor[1] === c && pos.span[1] === 1) {\n width = pos.cell.width;\n }\n }\n // If not found, distribute merged cell width\n if (width === 0) {\n const pos = cellGrid[0]?.[c];\n if (pos) {\n width = Math.round(pos.cell.width / pos.span[1]);\n }\n }\n columnWidths.push(width);\n }\n\n const outMargin = table.getOutMargin();\n const inMargin = table.getInMargin();\n\n tables.push({\n rowCount,\n colCount,\n cells: cellsVM,\n tableIndex: tIdx,\n pageBreak: table.pageBreak,\n repeatHeader: table.repeatHeader,\n widthHwp: table.width,\n heightHwp: table.height,\n outMargin,\n inMargin,\n columnWidths,\n });\n }\n\n // Extract default character formatting from paragraph's charPrIdRef\n let defaultFontSize: number | null = null;\n let defaultFontFamily: string | null = null;\n const paraCharPrIdRef = para.charPrIdRef;\n if (paraCharPrIdRef) {\n const charStyle = doc.charProperty(paraCharPrIdRef);\n if (charStyle) {\n const extracted = extractRunStyle(charStyle, doc);\n defaultFontSize = extracted.fontSize;\n defaultFontFamily = extracted.fontFamily;\n }\n }\n // Fallback: use first run's style if paragraph-level is missing\n if (defaultFontSize == null && runs.length > 0) {\n defaultFontSize = runs[0]!.fontSize;\n }\n if (defaultFontFamily == null && runs.length > 0) {\n defaultFontFamily = runs[0]!.fontFamily;\n }\n\n // Extract paragraph formatting from paraPrIdRef\n let alignment = \"LEFT\";\n let lineSpacing = 1.6;\n let spacingBefore = 0;\n let spacingAfter = 0;\n let firstLineIndent = 0;\n let marginLeftPx = 0;\n let marginRightPx = 0;\n\n const paraPrIdRef = para.paraPrIdRef;\n if (paraPrIdRef) {\n const paraPr = paraPrLookup.get(paraPrIdRef);\n if (paraPr) {\n // Alignment\n if (paraPr.align?.horizontal) {\n alignment = paraPr.align.horizontal.toUpperCase();\n }\n // Line spacing\n if (paraPr.lineSpacing?.value != null) {\n lineSpacing = paraPr.lineSpacing.value / 100;\n }\n // Margins and spacing\n if (paraPr.margin) {\n if (paraPr.margin.left) {\n marginLeftPx = hwpToPx(parseInt(paraPr.margin.left, 10) || 0);\n }\n if (paraPr.margin.right) {\n marginRightPx = hwpToPx(parseInt(paraPr.margin.right, 10) || 0);\n }\n if (paraPr.margin.intent) {\n firstLineIndent = hwpToPx(parseInt(paraPr.margin.intent, 10) || 0);\n }\n if (paraPr.margin.prev) {\n spacingBefore = hwpToPx(parseInt(paraPr.margin.prev, 10) || 0);\n }\n if (paraPr.margin.next) {\n spacingAfter = hwpToPx(parseInt(paraPr.margin.next, 10) || 0);\n }\n }\n }\n }\n\n sectionVM.paragraphs.push({\n runs,\n tables,\n images,\n textBoxes,\n equations,\n alignment,\n lineSpacing,\n spacingBefore,\n spacingAfter,\n firstLineIndent,\n marginLeftPx,\n marginRightPx,\n paragraphIndex: globalParaIndex,\n defaultFontSize,\n defaultFontFamily,\n });\n\n globalParaIndex++;\n }\n\n sections.push(sectionVM);\n }\n\n return { sections, watermarkText: \"\" };\n}\n","/**\n * HWPX unit conversion utilities.\n *\n * HWPX uses hwpUnit where 7200 hwpUnit = 1 inch = 25.4 mm.\n * Screen rendering at 96 DPI: 1 hwpUnit = 96/7200 px ≈ 0.01333 px.\n */\n\nconst HWP_UNITS_PER_INCH = 7200;\nconst PX_PER_INCH = 96;\nconst MM_PER_INCH = 25.4;\n\n/** Convert hwpUnit to pixels at 96 DPI. */\nexport function hwpToPx(hwpUnit: number): number {\n return (hwpUnit * PX_PER_INCH) / HWP_UNITS_PER_INCH;\n}\n\n/** Convert pixels (96 DPI) to hwpUnit. */\nexport function pxToHwp(px: number): number {\n return Math.round((px * HWP_UNITS_PER_INCH) / PX_PER_INCH);\n}\n\n/** Convert hwpUnit to millimeters. */\nexport function hwpToMm(hwpUnit: number): number {\n return (hwpUnit * MM_PER_INCH) / HWP_UNITS_PER_INCH;\n}\n\n/** Convert millimeters to hwpUnit. */\nexport function mmToHwp(mm: number): number {\n return Math.round((mm * HWP_UNITS_PER_INCH) / MM_PER_INCH);\n}\n","/**\n * Extract binary image data from an HwpxDocument package as data URLs.\n */\n\nimport type { HwpxPackage } from \"@ubermensch1218/hwpxcore\";\n\n/** Map of binaryItemIdRef → data:... URL for all images in the package. */\nexport function extractImages(pkg: HwpxPackage): Map<string, string> {\n const images = new Map<string, string>();\n const partNames = pkg.partNames();\n\n for (const name of partNames) {\n if (!name.startsWith(\"BinData/\")) continue;\n\n const ext = name.split(\".\").pop()?.toLowerCase() ?? \"\";\n let mediaType = \"application/octet-stream\";\n if (ext === \"png\") mediaType = \"image/png\";\n else if (ext === \"jpg\" || ext === \"jpeg\") mediaType = \"image/jpeg\";\n else if (ext === \"gif\") mediaType = \"image/gif\";\n else if (ext === \"bmp\") mediaType = \"image/bmp\";\n else if (ext === \"svg\") mediaType = \"image/svg+xml\";\n else if (ext === \"webp\") mediaType = \"image/webp\";\n else if (ext === \"tif\" || ext === \"tiff\") mediaType = \"image/tiff\";\n else if (ext === \"emf\") mediaType = \"image/x-emf\";\n else if (ext === \"wmf\") mediaType = \"image/x-wmf\";\n\n try {\n const data = pkg.getPart(name);\n const base64 = uint8ToBase64(data);\n const dataUrl = `data:${mediaType};base64,${base64}`;\n\n // Store with the filename (e.g. \"image1.png\")\n const fileName = name.replace(\"BinData/\", \"\");\n images.set(fileName, dataUrl);\n // Also store without extension (e.g. \"image1\") to match binaryItemIDRef\n const baseName = fileName.replace(/\\.[^.]+$/, \"\");\n if (baseName !== fileName) {\n images.set(baseName, dataUrl);\n }\n } catch {\n // Skip parts that can't be read\n }\n }\n\n return images;\n}\n\nfunction uint8ToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]!);\n }\n return btoa(binary);\n}\n","/**\n * format-bridge.ts — Bridge between UI and @ubermensch1218/hwpxcore formatting APIs.\n *\n * Reads charPr / paraPr from the document and converts to UI-friendly formats.\n * Also provides methods to apply format changes back to the document.\n */\n\nimport type {\n HwpxDocument,\n HwpxOxmlParagraph,\n RunStyle,\n ParagraphProperty,\n Header,\n Style,\n} from \"@ubermensch1218/hwpxcore\";\nimport {\n parseHeaderXml,\n} from \"@ubermensch1218/hwpxcore\";\nimport { serializeXml } from \"@ubermensch1218/hwpxcore\";\nimport type { AlignmentType } from \"./constants\";\n\n// ── Read format types ──────────────────────────────────────────────────────\n\nexport interface CharFormat {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n fontFamily: string | null;\n fontSize: number | null;\n textColor: string | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n}\n\nexport interface ParaFormat {\n alignment: AlignmentType;\n lineSpacing: number;\n spacingBefore: number;\n spacingAfter: number;\n indentLeft: number;\n indentRight: number;\n firstLineIndent: number;\n}\n\n// ── Parse header to get paragraph properties ───────────────────────────────\n\nfunction getParsedHeader(doc: HwpxDocument): Header | null {\n const headers = doc.headers;\n if (headers.length === 0) return null;\n const headerEl = headers[0]!.element;\n try {\n const xml = serializeXml(headerEl);\n return parseHeaderXml(xml);\n } catch {\n return null;\n }\n}\n\n// ── Read character formatting from a run style ─────────────────────────────\n\nexport function readCharFormat(style: RunStyle | null, doc?: HwpxDocument | null): CharFormat {\n const result: CharFormat = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n fontFamily: null,\n fontSize: null,\n textColor: null,\n highlightColor: null,\n letterSpacing: null,\n };\n\n if (!style) return result;\n\n result.bold = style.attributes[\"bold\"] === \"1\";\n result.italic = style.attributes[\"italic\"] === \"1\";\n\n // Underline\n const underlineChild = style.childAttributes[\"underline\"];\n result.underline =\n underlineChild != null &&\n underlineChild[\"type\"] != null &&\n underlineChild[\"type\"] !== \"NONE\";\n\n // Strikethrough\n const strikeChild = style.childAttributes[\"strikeout\"];\n result.strikethrough =\n strikeChild != null &&\n strikeChild[\"type\"] != null &&\n strikeChild[\"type\"] !== \"NONE\";\n\n // Text color\n result.textColor = style.attributes[\"textColor\"] ?? null;\n\n // Highlight color\n result.highlightColor = style.attributes[\"shadeColor\"] ?? null;\n\n // Letter spacing\n const spacing = style.attributes[\"spacing\"];\n if (spacing) {\n const val = parseInt(spacing, 10);\n if (!isNaN(val)) result.letterSpacing = val;\n }\n\n // Font family — look in fontRef child, resolve numeric ID to face name\n const fontRef = style.childAttributes[\"fontRef\"];\n if (fontRef) {\n const hangulId = fontRef[\"hangul\"] ?? fontRef[\"latin\"] ?? null;\n if (hangulId != null && doc) {\n result.fontFamily = doc.fontFaceName(hangulId) ?? hangulId;\n } else {\n result.fontFamily = hangulId;\n }\n }\n\n // Font size\n const sizeStr = style.attributes[\"height\"];\n if (sizeStr) {\n // Height is in hwp units (1/7200 inch), convert to pt: hwpUnit / 100\n const hwpVal = parseInt(sizeStr, 10);\n if (!isNaN(hwpVal)) result.fontSize = hwpVal / 100;\n }\n\n return result;\n}\n\n// ── Read paragraph formatting ──────────────────────────────────────────────\n\nexport function readParaFormat(\n doc: HwpxDocument,\n paragraph: HwpxOxmlParagraph,\n): ParaFormat {\n const result: ParaFormat = {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n };\n\n const paraPrIdRef = paragraph.paraPrIdRef;\n if (!paraPrIdRef) return result;\n\n const header = getParsedHeader(doc);\n if (!header) return result;\n\n // Look up the paragraph property\n const paraPr = findParaPr(header, paraPrIdRef);\n if (!paraPr) return result;\n\n // Alignment\n if (paraPr.align?.horizontal) {\n const h = paraPr.align.horizontal.toUpperCase();\n if (\n h === \"LEFT\" || h === \"CENTER\" || h === \"RIGHT\" ||\n h === \"JUSTIFY\" || h === \"DISTRIBUTE\"\n ) {\n result.alignment = h as AlignmentType;\n }\n }\n\n // Line spacing\n if (paraPr.lineSpacing?.value != null) {\n const spacingType = paraPr.lineSpacing.spacingType?.toUpperCase();\n if (spacingType === \"PERCENT\" || spacingType === \"PROPORTIONAL\") {\n // Value is in percent (e.g., 160 = 1.6x)\n result.lineSpacing = paraPr.lineSpacing.value / 100;\n } else {\n // Fixed value in hwp units\n result.lineSpacing = paraPr.lineSpacing.value / 100;\n }\n }\n\n // Margins / indentation\n if (paraPr.margin) {\n if (paraPr.margin.left) {\n result.indentLeft = parseInt(paraPr.margin.left, 10) || 0;\n }\n if (paraPr.margin.right) {\n result.indentRight = parseInt(paraPr.margin.right, 10) || 0;\n }\n if (paraPr.margin.intent) {\n result.firstLineIndent = parseInt(paraPr.margin.intent, 10) || 0;\n }\n if (paraPr.margin.prev) {\n result.spacingBefore = parseInt(paraPr.margin.prev, 10) || 0;\n }\n if (paraPr.margin.next) {\n result.spacingAfter = parseInt(paraPr.margin.next, 10) || 0;\n }\n }\n\n return result;\n}\n\n// ── Helper: find paragraph property by ID ──────────────────────────────────\n\nfunction findParaPr(header: Header, paraPrIdRef: string): ParagraphProperty | null {\n if (!header.refList?.paraProperties) return null;\n for (const prop of header.refList.paraProperties.properties) {\n if (prop.rawId === paraPrIdRef) return prop;\n if (prop.id != null && String(prop.id) === paraPrIdRef) return prop;\n }\n return null;\n}\n\n// ── Read style info ────────────────────────────────────────────────────────\n\nexport function readStyleInfo(\n doc: HwpxDocument,\n paragraph: HwpxOxmlParagraph,\n): { styleName: string | null; styleId: string | null } {\n const styleIdRef = paragraph.styleIdRef;\n if (!styleIdRef) return { styleName: null, styleId: null };\n\n const header = getParsedHeader(doc);\n if (!header?.refList?.styles) return { styleName: null, styleId: null };\n\n for (const style of header.refList.styles.styles) {\n if (style.rawId === styleIdRef || (style.id != null && String(style.id) === styleIdRef)) {\n return { styleName: style.name, styleId: styleIdRef };\n }\n }\n\n return { styleName: null, styleId: styleIdRef };\n}\n\n// ── Get available styles from document ─────────────────────────────────────\n\nexport function getDocumentStyles(doc: HwpxDocument): Style[] {\n const header = getParsedHeader(doc);\n if (!header?.refList?.styles) return [];\n return header.refList.styles.styles;\n}\n\n// ── Read format from current selection ─────────────────────────────────────\n\nexport function readFormatFromSelection(\n doc: HwpxDocument,\n sectionIndex: number,\n paragraphIndex: number,\n): { char: CharFormat; para: ParaFormat } {\n const section = doc.sections[sectionIndex];\n if (!section) {\n return {\n char: readCharFormat(null),\n para: {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n },\n };\n }\n\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) {\n return {\n char: readCharFormat(null),\n para: {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n },\n };\n }\n\n // Character format: use the first run's style or the paragraph's charPrIdRef\n const runs = para.runs;\n let charStyle: RunStyle | null = null;\n if (runs.length > 0) {\n charStyle = runs[0]!.style;\n } else {\n const charPrIdRef = para.charPrIdRef;\n if (charPrIdRef) {\n charStyle = doc.charProperty(charPrIdRef);\n }\n }\n\n return {\n char: readCharFormat(charStyle, doc),\n para: readParaFormat(doc, para),\n };\n}\n","/**\n * Browser-side Skeleton.hwpx loader.\n * Fetches from /Skeleton.hwpx and calls setSkeletonHwpx() to register it.\n */\n\nimport { setSkeletonHwpx, HwpxDocument } from \"@ubermensch1218/hwpxcore\";\n\nlet loaded = false;\n\n/** Fetch Skeleton.hwpx from the public folder and register it with @ubermensch1218/hwpxcore. */\nexport async function ensureSkeletonLoaded(): Promise<void> {\n if (loaded) return;\n const res = await fetch(\"/Skeleton.hwpx\");\n if (!res.ok) throw new Error(`Failed to fetch Skeleton.hwpx: ${res.status}`);\n const buf = await res.arrayBuffer();\n setSkeletonHwpx(new Uint8Array(buf));\n loaded = true;\n}\n\n/** Create a new empty HwpxDocument from the skeleton template. */\nexport async function createNewDocument(): Promise<HwpxDocument> {\n await ensureSkeletonLoaded();\n const res = await fetch(\"/Skeleton.hwpx\");\n const buf = await res.arrayBuffer();\n return HwpxDocument.open(buf);\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\n\nconst PX_TO_MM = 25.4 / 96;\n\nfunction getMediaType(file: File): \"image/png\" | \"image/jpeg\" | \"image/gif\" | \"image/bmp\" {\n const ext = file.name.split(\".\").pop()?.toLowerCase() ?? \"\";\n const typeMap: Record<string, \"image/png\" | \"image/jpeg\" | \"image/gif\" | \"image/bmp\"> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n return typeMap[ext] ?? \"image/png\";\n}\n\nasync function getImageDimensions(data: Uint8Array, mediaType: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve) => {\n const blob = new Blob([data], { type: mediaType });\n const url = URL.createObjectURL(blob);\n const img = new Image();\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n resolve({ width: 100, height: 100 });\n };\n img.src = url;\n });\n}\n\n// ── Menu data types ──────────────────────────────────────────────────────────\n\ninterface MenuItem {\n label: string;\n shortcut?: string;\n disabled?: boolean;\n dividerAfter?: boolean;\n action?: () => void;\n}\n\ninterface Menu {\n label: string;\n items: MenuItem[];\n}\n\n// ── MenuBar component ────────────────────────────────────────────────────────\n\nexport function MenuBar() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const [openMenu, setOpenMenu] = useState<number | null>(null);\n const barRef = useRef<HTMLDivElement>(null);\n const imageInputRef = useRef<HTMLInputElement>(null);\n\n const disabled = !doc;\n\n const handleImageSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n try {\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n const mediaType = getMediaType(file);\n const dims = await getImageDimensions(data, mediaType);\n const maxWidth = 150;\n const scale = dims.width * PX_TO_MM > maxWidth ? maxWidth / (dims.width * PX_TO_MM) : 1;\n const widthMm = dims.width * PX_TO_MM * scale;\n const heightMm = dims.height * PX_TO_MM * scale;\n useEditorStore.getState().insertImage(data, mediaType, widthMm, heightMm);\n } catch (err) {\n console.error(\"Failed to insert image:\", err);\n } finally {\n if (imageInputRef.current) imageInputRef.current.value = \"\";\n }\n };\n\n // Close menu on outside click\n useEffect(() => {\n if (openMenu === null) return;\n const handler = (e: MouseEvent) => {\n if (barRef.current && !barRef.current.contains(e.target as Node)) {\n setOpenMenu(null);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [openMenu]);\n\n // Close on Escape\n useEffect(() => {\n if (openMenu === null) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpenMenu(null);\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [openMenu]);\n\n const store = useEditorStore.getState;\n\n const menus: Menu[] = [\n {\n label: \"파일\",\n items: [\n { label: \"새 문서\", shortcut: \"Ctrl+N\", disabled: true },\n { label: \"불러오기...\", shortcut: \"Ctrl+O\", disabled: true },\n { label: \"템플릿 관리...\", action: () => store().openTemplateDialog(), dividerAfter: true },\n { label: \"저장\", shortcut: \"Ctrl+S\", disabled, action: () => store().openSaveDialog() },\n { label: \"다른 이름으로 저장...\", disabled, action: () => store().openSaveDialog(), dividerAfter: true },\n { label: \"문서 정보\", disabled: true },\n { label: \"인쇄...\", shortcut: \"Ctrl+P\", disabled: true },\n ],\n },\n {\n label: \"편집\",\n items: [\n { label: \"실행 취소\", shortcut: \"Ctrl+Z\", disabled, action: () => store().undo() },\n { label: \"다시 실행\", shortcut: \"Ctrl+Y\", disabled, action: () => store().redo(), dividerAfter: true },\n { label: \"오려두기\", shortcut: \"Ctrl+X\", action: () => document.execCommand(\"cut\") },\n { label: \"복사\", shortcut: \"Ctrl+C\", action: () => document.execCommand(\"copy\") },\n { label: \"붙이기\", shortcut: \"Ctrl+V\", action: () => document.execCommand(\"paste\"), dividerAfter: true },\n { label: \"모두 선택\", shortcut: \"Ctrl+A\", action: () => document.execCommand(\"selectAll\") },\n { label: \"찾기\", shortcut: \"Ctrl+F\", disabled, action: () => store().openFindReplaceDialog() },\n { label: \"찾아 바꾸기\", shortcut: \"Ctrl+H\", disabled, action: () => store().openFindReplaceDialog() },\n ],\n },\n {\n label: \"보기\",\n items: [\n { label: \"서식 사이드바\", action: () => store().toggleSidebar() },\n { label: \"눈금자\", disabled: true, dividerAfter: true },\n { label: \"확대\", shortcut: \"Ctrl++\", disabled: true },\n { label: \"축소\", shortcut: \"Ctrl+-\", disabled: true },\n { label: \"전체 화면\", shortcut: \"F11\", disabled: true },\n ],\n },\n {\n label: \"입력\",\n items: [\n { label: \"표...\", disabled: disabled || !selection, action: () => { /* handled via InsertGroup dialog */ } },\n { label: \"그림...\", disabled, action: () => imageInputRef.current?.click() },\n { label: \"도형\", disabled: true },\n { label: \"차트\", disabled: true, dividerAfter: true },\n { label: \"문자표...\", shortcut: \"⌃F10\", disabled, action: () => store().openCharMapDialog(), dividerAfter: true },\n { label: \"각주\", shortcut: \"Ctrl+N,N\", disabled, action: () => store().insertFootnote() },\n { label: \"미주\", shortcut: \"Ctrl+N,E\", disabled, action: () => store().insertEndnote(), dividerAfter: true },\n { label: \"머리말/꼬리말...\", disabled, action: () => store().openHeaderFooterDialog() },\n { label: \"쪽 번호...\", disabled: true, dividerAfter: true },\n { label: \"단 나누기\", disabled: disabled || !selection, action: () => store().insertColumnBreak() },\n { label: \"쪽 나누기\", disabled: disabled || !selection, action: () => store().insertPageBreak() },\n ],\n },\n {\n label: \"서식\",\n items: [\n { label: \"글자 모양...\", shortcut: \"⌘L\", disabled, action: () => store().openCharFormatDialog() },\n { label: \"문단 모양...\", shortcut: \"⌘T\", disabled, action: () => store().openParaFormatDialog(), dividerAfter: true },\n { label: \"문단 첫 글자 장식...\", disabled: true },\n { label: \"문단 번호 모양...\", disabled, action: () => store().openBulletNumberDialog() },\n { label: \"문단 번호 적용/해제\", disabled: true },\n { label: \"글머리표 적용/해제\", shortcut: \"⌃⇧⌫\", disabled, action: () => store().openBulletNumberDialog(), dividerAfter: true },\n { label: \"개요 번호 모양...\", disabled: true },\n { label: \"개요 적용/해제\", disabled: true },\n { label: \"한 수준 증가\", shortcut: \"⌃-\", disabled: true },\n { label: \"한 수준 감소\", shortcut: \"⌃+\", disabled: true, dividerAfter: true },\n { label: \"스타일...\", shortcut: \"F6\", disabled: true },\n ],\n },\n {\n label: \"쪽\",\n items: [\n { label: \"편집 용지...\", disabled, action: () => { store().setSidebarTab(\"page\"); if (!store().uiState.sidebarOpen) store().toggleSidebar(); } },\n { label: \"쪽 번호 매기기...\", disabled: true, dividerAfter: true },\n { label: \"머리말...\", disabled, action: () => store().openHeaderFooterDialog() },\n { label: \"꼬리말...\", disabled, action: () => store().openHeaderFooterDialog(), dividerAfter: true },\n { label: \"바탕쪽\", disabled: true },\n { label: \"워터마크...\", disabled, action: () => store().setWatermarkText(\"DRAFT\") },\n { label: \"워터마크 제거\", disabled, action: () => store().setWatermarkText(\"\") },\n ],\n },\n {\n label: \"도구\",\n items: [\n { label: \"맞춤법 검사...\", shortcut: \"F8\", disabled: true },\n { label: \"자동 고침...\", disabled: true, dividerAfter: true },\n { label: \"글자 수 세기\", disabled, action: () => store().openWordCountDialog() },\n { label: \"매크로...\", disabled: true },\n { label: \"환경 설정...\", disabled: true },\n ],\n },\n {\n label: \"표\",\n items: [\n { label: \"표 속성...\", disabled: disabled || selection?.tableIndex == null, action: () => { store().setSidebarTab(\"table\"); if (!store().uiState.sidebarOpen) store().toggleSidebar(); } },\n { label: \"셀 합치기\", disabled: disabled || selection?.type !== \"cell\", action: () => store().mergeSelectedCells() },\n { label: \"셀 나누기\", disabled: disabled || selection?.type !== \"cell\", action: () => store().unmergeSelectedCells(), dividerAfter: true },\n { label: \"줄 삽입 (위)\", disabled: true },\n { label: \"줄 삽입 (아래)\", disabled: true },\n { label: \"칸 삽입 (왼쪽)\", disabled: true },\n { label: \"칸 삽입 (오른쪽)\", disabled: true, dividerAfter: true },\n { label: \"줄 삭제\", disabled: true },\n { label: \"칸 삭제\", disabled: true },\n { label: \"표 삭제\", disabled: true },\n ],\n },\n ];\n\n const handleMenuClick = useCallback((menuIdx: number) => {\n setOpenMenu((prev) => (prev === menuIdx ? null : menuIdx));\n }, []);\n\n const handleItemClick = useCallback((item: MenuItem) => {\n if (item.disabled) return;\n item.action?.();\n setOpenMenu(null);\n }, []);\n\n return (\n <div ref={barRef} className=\"flex items-center bg-gray-50 border-b border-gray-200 text-xs select-none relative z-50\">\n <input\n ref={imageInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/bmp\"\n className=\"hidden\"\n onChange={handleImageSelect}\n />\n {menus.map((menu, mIdx) => (\n <div key={menu.label} className=\"relative\">\n <button\n onClick={() => handleMenuClick(mIdx)}\n onMouseEnter={() => { if (openMenu !== null) setOpenMenu(mIdx); }}\n className={`px-3 py-1.5 transition-colors ${\n openMenu === mIdx\n ? \"bg-blue-100 text-blue-700\"\n : \"text-gray-700 hover:bg-gray-100\"\n }`}\n >\n {menu.label}\n </button>\n {openMenu === mIdx && (\n <div className=\"absolute left-0 top-full bg-white border border-gray-200 shadow-lg rounded-b min-w-[220px] py-1 z-50\">\n {menu.items.map((item, iIdx) => (\n <div key={iIdx}>\n <button\n onClick={() => handleItemClick(item)}\n disabled={item.disabled}\n className={`w-full text-left px-4 py-1.5 flex items-center justify-between gap-4 ${\n item.disabled\n ? \"text-gray-300 cursor-default\"\n : \"text-gray-700 hover:bg-blue-50 hover:text-blue-700\"\n }`}\n >\n <span>{item.label}</span>\n {item.shortcut && (\n <span className=\"text-[10px] text-gray-400 ml-4 flex-shrink-0\">{item.shortcut}</span>\n )}\n </button>\n {item.dividerAfter && <div className=\"border-t border-gray-100 my-0.5\" />}\n </div>\n ))}\n </div>\n )}\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { Clipboard, Copy, ClipboardPaste, Paintbrush } from \"lucide-react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { RibbonGroup } from \"./RibbonGroup\";\n\nexport function ClipboardGroup() {\n return (\n <RibbonGroup label=\"클립보드\">\n <ToolbarButton\n icon={<Clipboard className=\"w-4 h-4\" />}\n label=\"잘라내기\"\n layout=\"vertical\"\n title=\"오려두기 (Ctrl+X)\"\n onClick={() => document.execCommand(\"cut\")}\n />\n <ToolbarButton\n icon={<Copy className=\"w-4 h-4\" />}\n label=\"복사\"\n layout=\"vertical\"\n title=\"복사 (Ctrl+C)\"\n onClick={() => document.execCommand(\"copy\")}\n />\n <ToolbarButton\n icon={<ClipboardPaste className=\"w-4 h-4\" />}\n label=\"붙이기\"\n layout=\"vertical\"\n title=\"붙이기 (Ctrl+V)\"\n onClick={() => document.execCommand(\"paste\")}\n />\n <ToolbarButton\n icon={<Paintbrush className=\"w-4 h-4\" />}\n label=\"모양복사\"\n layout=\"vertical\"\n title=\"모양 복사\"\n disabled\n />\n </RibbonGroup>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface ToolbarButtonProps {\n icon: ReactNode;\n label?: string;\n active?: boolean;\n disabled?: boolean;\n onClick?: () => void;\n title?: string;\n size?: \"sm\" | \"md\";\n layout?: \"horizontal\" | \"vertical\";\n className?: string;\n}\n\nexport function ToolbarButton({\n icon,\n label,\n active,\n disabled,\n onClick,\n title,\n size = \"sm\",\n layout = \"horizontal\",\n className = \"\",\n}: ToolbarButtonProps) {\n const sizeClass = size === \"md\" ? \"p-2\" : \"p-1.5\";\n const isVertical = layout === \"vertical\";\n return (\n <button\n disabled={disabled}\n onClick={onClick}\n title={title}\n className={`${sizeClass} rounded transition-colors flex ${\n isVertical ? \"flex-col items-center gap-0.5 px-2\" : \"items-center gap-1\"\n } ${\n active\n ? \"bg-blue-100 text-blue-700\"\n : \"text-gray-600 hover:bg-gray-100\"\n } disabled:opacity-40 disabled:cursor-not-allowed ${className}`}\n >\n {icon}\n {label && (\n <span className={isVertical ? \"text-[9px] leading-tight\" : \"text-xs\"}>\n {label}\n </span>\n )}\n </button>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface RibbonGroupProps {\n label: string;\n children: ReactNode;\n}\n\nexport function RibbonGroup({ label, children }: RibbonGroupProps) {\n return (\n <div className=\"flex flex-col items-center border-r border-gray-200 px-2 last:border-r-0\">\n <div className=\"flex items-center gap-0.5 py-1\">{children}</div>\n <span className=\"text-[10px] text-gray-400 pb-0.5\">{label}</span>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { Table, BarChart3, Shapes, ImageIcon, Save, Columns, FileDown } from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { RibbonGroup } from \"./RibbonGroup\";\n\nexport function InsertGroup() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const addTable = useEditorStore((s) => s.addTable);\n const insertImage = useEditorStore((s) => s.insertImage);\n const insertColumnBreak = useEditorStore((s) => s.insertColumnBreak);\n const insertPageBreak = useEditorStore((s) => s.insertPageBreak);\n const saveDocument = useEditorStore((s) => s.saveDocument);\n const loading = useEditorStore((s) => s.loading);\n\n const [showTableDialog, setShowTableDialog] = useState(false);\n const [tableRows, setTableRows] = useState(3);\n const [tableCols, setTableCols] = useState(3);\n const imageInputRef = useRef<HTMLInputElement>(null);\n\n const disabled = !doc;\n\n const handleAddTable = useCallback(() => {\n if (!selection) return;\n addTable(selection.sectionIndex, selection.paragraphIndex, tableRows, tableCols);\n setShowTableDialog(false);\n }, [selection, tableRows, tableCols, addTable]);\n\n const handleImageSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n const img = new window.Image();\n const url = URL.createObjectURL(file);\n img.onload = () => {\n const widthMm = (img.naturalWidth / 96) * 25.4;\n const heightMm = (img.naturalHeight / 96) * 25.4;\n insertImage(data, file.type, widthMm, heightMm);\n URL.revokeObjectURL(url);\n };\n img.src = url;\n e.target.value = \"\";\n },\n [insertImage],\n );\n\n return (\n <>\n <RibbonGroup label=\"삽입\">\n <ToolbarButton\n icon={<Table className=\"w-4 h-4\" />}\n label=\"표\"\n layout=\"vertical\"\n title=\"표 삽입\"\n disabled={disabled || !selection}\n onClick={() => setShowTableDialog(true)}\n />\n <ToolbarButton\n icon={<BarChart3 className=\"w-4 h-4\" />}\n label=\"차트\"\n layout=\"vertical\"\n title=\"차트 삽입\"\n disabled\n />\n <ToolbarButton\n icon={<Shapes className=\"w-4 h-4\" />}\n label=\"도형\"\n layout=\"vertical\"\n title=\"도형 삽입\"\n disabled\n />\n <ToolbarButton\n icon={<ImageIcon className=\"w-4 h-4\" />}\n label=\"그림\"\n layout=\"vertical\"\n title=\"그림 삽입\"\n disabled={disabled}\n onClick={() => imageInputRef.current?.click()}\n />\n <input\n ref={imageInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={handleImageSelect}\n />\n <ToolbarButton\n icon={<Columns className=\"w-4 h-4\" />}\n label=\"단\"\n layout=\"vertical\"\n title=\"단 나누기\"\n disabled={disabled || !selection}\n onClick={() => insertColumnBreak()}\n />\n <ToolbarButton\n icon={<FileDown className=\"w-4 h-4\" />}\n label=\"쪽\"\n layout=\"vertical\"\n title=\"쪽 나누기\"\n disabled={disabled || !selection}\n onClick={() => insertPageBreak()}\n />\n </RibbonGroup>\n\n <RibbonGroup label=\"파일\">\n <ToolbarButton\n icon={<Save className=\"w-4 h-4\" />}\n label=\"저장\"\n layout=\"vertical\"\n title=\"저장 (Ctrl+S)\"\n disabled={disabled || loading}\n onClick={() => saveDocument()}\n />\n </RibbonGroup>\n\n {/* Table dialog */}\n {showTableDialog && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/30\">\n <div className=\"bg-white rounded-lg shadow-xl p-6 min-w-[280px]\">\n <h3 className=\"font-semibold mb-4\">표 삽입</h3>\n <div className=\"flex gap-4 mb-4\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-gray-600\">행</span>\n <input\n type=\"number\"\n min={1}\n max={50}\n value={tableRows}\n onChange={(e) => setTableRows(Number(e.target.value))}\n className=\"border rounded px-2 py-1 w-20\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-gray-600\">열</span>\n <input\n type=\"number\"\n min={1}\n max={20}\n value={tableCols}\n onChange={(e) => setTableCols(Number(e.target.value))}\n className=\"border rounded px-2 py-1 w-20\"\n />\n </label>\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n onClick={() => setShowTableDialog(false)}\n className=\"px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded\"\n >\n 취소\n </button>\n <button\n onClick={handleAddTable}\n className=\"px-4 py-2 text-sm bg-blue-500 text-white rounded hover:bg-blue-600\"\n >\n 삽입\n </button>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { ClipboardGroup } from \"./ClipboardGroup\";\nimport { InsertGroup } from \"./InsertGroup\";\n\nexport function RibbonToolbar() {\n return (\n <div className=\"flex items-stretch bg-white border-b border-gray-200 px-1 min-h-[52px]\">\n <ClipboardGroup />\n <InsertGroup />\n </div>\n );\n}\n","/**\n * Constants for the HWPX editor UI — font lists, style presets, alignment/spacing options.\n */\n\n// ── Korean font families ───────────────────────────────────────────────────\n\nexport const FONT_FAMILIES = [\n \"맑은 고딕\",\n \"함초롬돋움\",\n \"함초롬바탕\",\n \"나눔고딕\",\n \"나눔명조\",\n \"나눔바른고딕\",\n \"Noto Sans KR\",\n \"Noto Serif KR\",\n \"교보손글씨 2024 박서우\",\n \"교보손글씨 2023 우선아\",\n \"학교안심 알림장\",\n \"바탕\",\n \"돋움\",\n \"굴림\",\n \"궁서\",\n \"Arial\",\n \"Times New Roman\",\n \"Courier New\",\n \"Verdana\",\n \"Georgia\",\n] as const;\n\nexport type FontFamily = (typeof FONT_FAMILIES)[number];\n\n// ── Font sizes ─────────────────────────────────────────────────────────────\n\nexport const FONT_SIZES = [\n 8, 9, 10, 10.5, 11, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 48, 72,\n] as const;\n\n// ── Paragraph styles ───────────────────────────────────────────────────────\n\nexport interface StylePreset {\n id: string;\n name: string;\n engName: string;\n}\n\nexport const STYLE_PRESETS: StylePreset[] = [\n { id: \"0\", name: \"바탕글\", engName: \"Normal\" },\n { id: \"1\", name: \"본문\", engName: \"Body\" },\n { id: \"2\", name: \"개요 1\", engName: \"Outline 1\" },\n { id: \"3\", name: \"개요 2\", engName: \"Outline 2\" },\n { id: \"4\", name: \"개요 3\", engName: \"Outline 3\" },\n { id: \"5\", name: \"쪽 번호\", engName: \"Page Number\" },\n { id: \"6\", name: \"머리말\", engName: \"Header\" },\n { id: \"7\", name: \"꼬리말\", engName: \"Footer\" },\n { id: \"8\", name: \"각주\", engName: \"Footnote\" },\n { id: \"9\", name: \"미주\", engName: \"Endnote\" },\n];\n\n// ── Alignment ──────────────────────────────────────────────────────────────\n\nexport type AlignmentType = \"LEFT\" | \"CENTER\" | \"RIGHT\" | \"JUSTIFY\" | \"DISTRIBUTE\";\n\nexport interface AlignmentOption {\n value: AlignmentType;\n label: string;\n shortcut?: string;\n}\n\nexport const ALIGNMENT_OPTIONS: AlignmentOption[] = [\n { value: \"LEFT\", label: \"왼쪽 정렬\", shortcut: \"Ctrl+L\" },\n { value: \"CENTER\", label: \"가운데 정렬\", shortcut: \"Ctrl+E\" },\n { value: \"RIGHT\", label: \"오른쪽 정렬\", shortcut: \"Ctrl+R\" },\n { value: \"JUSTIFY\", label: \"양쪽 정렬\", shortcut: \"Ctrl+J\" },\n { value: \"DISTRIBUTE\", label: \"배분 정렬\" },\n];\n\n// ── Line spacing ───────────────────────────────────────────────────────────\n\nexport interface LineSpacingOption {\n value: number;\n label: string;\n}\n\nexport const LINE_SPACING_OPTIONS: LineSpacingOption[] = [\n { value: 1.0, label: \"1.0\" },\n { value: 1.15, label: \"1.15\" },\n { value: 1.5, label: \"1.5\" },\n { value: 1.6, label: \"1.6\" },\n { value: 2.0, label: \"2.0\" },\n { value: 2.5, label: \"2.5\" },\n { value: 3.0, label: \"3.0\" },\n];\n\n// ── Underline types ────────────────────────────────────────────────────────\n\nexport const UNDERLINE_TYPES = [\n \"NONE\",\n \"SOLID\",\n \"DASH\",\n \"DOT\",\n \"DASH_DOT\",\n \"DASH_DOT_DOT\",\n \"LONG_DASH\",\n \"DOUBLE\",\n \"WAVE\",\n \"HEAVY_WAVE\",\n \"DOUBLE_WAVE\",\n] as const;\n\n// ── Color presets ──────────────────────────────────────────────────────────\n\nexport const COLOR_PRESETS = [\n // Row 1: Primary colors\n \"#000000\", \"#333333\", \"#555555\", \"#777777\", \"#999999\", \"#BBBBBB\", \"#DDDDDD\", \"#FFFFFF\",\n // Row 2: Vivid colors\n \"#FF0000\", \"#FF6600\", \"#FFCC00\", \"#33CC33\", \"#0099FF\", \"#3366FF\", \"#6633CC\", \"#CC33CC\",\n // Row 3: Pastel colors\n \"#FF9999\", \"#FFCC99\", \"#FFFF99\", \"#CCFFCC\", \"#99CCFF\", \"#9999FF\", \"#CC99FF\", \"#FF99CC\",\n // Row 4: Dark colors\n \"#CC0000\", \"#CC6600\", \"#CC9900\", \"#009900\", \"#006699\", \"#003399\", \"#330099\", \"#990066\",\n] as const;\n\n// ── Highlight colors ───────────────────────────────────────────────────────\n\nexport const HIGHLIGHT_COLORS = [\n { value: \"#FFFF00\", label: \"노랑\" },\n { value: \"#00FF00\", label: \"연두\" },\n { value: \"#00FFFF\", label: \"하늘\" },\n { value: \"#FF00FF\", label: \"분홍\" },\n { value: \"#0000FF\", label: \"파랑\" },\n { value: \"#FF0000\", label: \"빨강\" },\n { value: \"#008000\", label: \"초록\" },\n { value: \"#800080\", label: \"보라\" },\n { value: \"#808080\", label: \"회색\" },\n { value: \"none\", label: \"없음\" },\n] as const;\n\n// ── Page size presets ─────────────────────────────────────────────────────\n\nexport const PAGE_SIZE_PRESETS = [\n { name: \"A4(국배판) [210x297mm]\", width: 210, height: 297 },\n { name: \"A3 [297x420mm]\", width: 297, height: 420 },\n { name: \"B4 [257x364mm]\", width: 257, height: 364 },\n { name: \"B5(국판) [182x257mm]\", width: 182, height: 257 },\n { name: \"Letter [216x279mm]\", width: 216, height: 279 },\n { name: \"Legal [216x356mm]\", width: 216, height: 356 },\n] as const;\n\nexport type OrientationType = \"PORTRAIT\" | \"LANDSCAPE\";\nexport type BindingType = \"LEFT\" | \"FACING\" | \"TOP\";\n\n// ── Sidebar tabs ───────────────────────────────────────────────────────────\n\nexport type SidebarTab = \"char\" | \"para\" | \"page\" | \"img-layout\" | \"img-props\" | \"table\";\n","\"use client\";\n\nimport { useState, useRef, useEffect, type ReactNode } from \"react\";\n\ninterface ToolbarDropdownProps {\n value: string;\n options: { value: string; label: string }[];\n onChange: (value: string) => void;\n disabled?: boolean;\n title?: string;\n className?: string;\n width?: string;\n icon?: ReactNode;\n}\n\nexport function ToolbarDropdown({\n value,\n options,\n onChange,\n disabled,\n title,\n className = \"\",\n width = \"w-28\",\n icon,\n}: ToolbarDropdownProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n const selectedLabel = options.find((o) => o.value === value)?.label ?? value;\n\n return (\n <div ref={ref} className={`relative ${className}`} title={title}>\n <button\n disabled={disabled}\n onClick={() => setOpen(!open)}\n className={`flex items-center gap-1 ${width} h-7 px-2 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-left disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {icon}\n <span className=\"flex-1 truncate\">{selectedLabel}</span>\n <svg className=\"w-3 h-3 text-gray-400 flex-shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded shadow-lg max-h-64 overflow-auto min-w-full\">\n {options.map((opt) => (\n <button\n key={opt.value}\n onClick={() => {\n onChange(opt.value);\n setOpen(false);\n }}\n className={`block w-full text-left px-3 py-1.5 text-xs hover:bg-blue-50 ${\n opt.value === value ? \"bg-blue-50 text-blue-700 font-medium\" : \"text-gray-700\"\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { STYLE_PRESETS } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\ninterface StyleSelectorProps {\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\nexport function StyleSelector({ value, onChange, disabled }: StyleSelectorProps) {\n const options = STYLE_PRESETS.map((s) => ({\n value: s.id,\n label: s.name,\n }));\n\n return (\n <ToolbarDropdown\n value={value}\n options={options}\n onChange={onChange}\n disabled={disabled}\n title=\"스타일\"\n width=\"w-24\"\n />\n );\n}\n","\"use client\";\n\nimport { FONT_FAMILIES } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\ninterface FontSelectorProps {\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\nexport function FontSelector({ value, onChange, disabled }: FontSelectorProps) {\n const options = FONT_FAMILIES.map((f) => ({\n value: f,\n label: f,\n }));\n\n return (\n <ToolbarDropdown\n value={value}\n options={options}\n onChange={onChange}\n disabled={disabled}\n title=\"글꼴\"\n width=\"w-32\"\n />\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { FONT_SIZES } from \"@/lib/constants\";\n\ninterface FontSizeInputProps {\n value: number;\n onChange: (value: number) => void;\n disabled?: boolean;\n}\n\nexport function FontSizeInput({ value, onChange, disabled }: FontSizeInputProps) {\n const [editing, setEditing] = useState(false);\n const [inputValue, setInputValue] = useState(String(value));\n\n const handleBlur = useCallback(() => {\n setEditing(false);\n const num = parseFloat(inputValue);\n if (!isNaN(num) && num > 0 && num <= 200) {\n onChange(num);\n } else {\n setInputValue(String(value));\n }\n }, [inputValue, value, onChange]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLInputElement).blur();\n } else if (e.key === \"Escape\") {\n setInputValue(String(value));\n setEditing(false);\n }\n },\n [value],\n );\n\n if (editing) {\n return (\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n autoFocus\n className=\"w-14 h-7 px-2 text-xs border border-blue-400 rounded text-center focus:outline-none\"\n />\n );\n }\n\n return (\n <div className=\"relative\">\n <select\n value={String(value)}\n onChange={(e) => {\n const num = parseFloat(e.target.value);\n if (!isNaN(num)) onChange(num);\n }}\n disabled={disabled}\n className=\"w-14 h-7 px-1 text-xs border border-gray-300 rounded bg-white text-center appearance-none cursor-pointer disabled:opacity-40\"\n title=\"글자 크기\"\n onDoubleClick={() => {\n setInputValue(String(value));\n setEditing(true);\n }}\n >\n {FONT_SIZES.map((s) => (\n <option key={s} value={String(s)}>\n {s}\n </option>\n ))}\n {!FONT_SIZES.includes(value as any) && (\n <option value={String(value)}>{value}</option>\n )}\n </select>\n </div>\n );\n}\n","\"use client\";\n\nimport {\n Bold,\n Italic,\n Underline,\n Strikethrough,\n Highlighter,\n Type,\n} from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { ColorPicker } from \"./ColorPicker\";\n\nexport function CharFormatButtons() {\n const activeFormat = useEditorStore((s) => s.activeFormat);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const selection = useEditorStore((s) => s.selection);\n const doc = useEditorStore((s) => s.doc);\n const toggleBold = useEditorStore((s) => s.toggleBold);\n const toggleItalic = useEditorStore((s) => s.toggleItalic);\n const toggleUnderline = useEditorStore((s) => s.toggleUnderline);\n const toggleStrikethrough = useEditorStore((s) => s.toggleStrikethrough);\n const setTextColor = useEditorStore((s) => s.setTextColor);\n const setHighlightColor = useEditorStore((s) => s.setHighlightColor);\n\n const disabled = !doc || !selection;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <ColorPicker\n color={extendedFormat.char.textColor || \"#000000\"}\n onChange={(c) => setTextColor(c)}\n icon={<Type className=\"w-3.5 h-3.5\" />}\n title=\"글자색\"\n disabled={disabled}\n />\n <ColorPicker\n color={extendedFormat.char.highlightColor || \"#FFFF00\"}\n onChange={(c) => setHighlightColor(c)}\n icon={<Highlighter className=\"w-3.5 h-3.5\" />}\n title=\"형광펜\"\n disabled={disabled}\n />\n <ToolbarButton\n icon={<Bold className=\"w-3.5 h-3.5\" />}\n active={activeFormat.bold}\n disabled={disabled}\n onClick={toggleBold}\n title=\"굵게 (Ctrl+B)\"\n />\n <ToolbarButton\n icon={<Italic className=\"w-3.5 h-3.5\" />}\n active={activeFormat.italic}\n disabled={disabled}\n onClick={toggleItalic}\n title=\"기울임 (Ctrl+I)\"\n />\n <ToolbarButton\n icon={<Underline className=\"w-3.5 h-3.5\" />}\n active={activeFormat.underline}\n disabled={disabled}\n onClick={toggleUnderline}\n title=\"밑줄 (Ctrl+U)\"\n />\n <ToolbarButton\n icon={<Strikethrough className=\"w-3.5 h-3.5\" />}\n active={activeFormat.strikethrough}\n disabled={disabled}\n onClick={toggleStrikethrough}\n title=\"취소선 (Ctrl+D)\"\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type ReactNode } from \"react\";\nimport { COLOR_PRESETS } from \"@/lib/constants\";\n\ninterface ColorPickerProps {\n color: string;\n onChange: (color: string) => void;\n icon: ReactNode;\n title?: string;\n disabled?: boolean;\n}\n\nexport function ColorPicker({\n color,\n onChange,\n icon,\n title,\n disabled,\n}: ColorPickerProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n disabled={disabled}\n onClick={() => setOpen(!open)}\n title={title}\n className=\"p-1.5 rounded transition-colors text-gray-600 hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed flex flex-col items-center\"\n >\n {icon}\n <div\n className=\"w-4 h-0.5 mt-0.5 rounded-sm\"\n style={{ backgroundColor: color || \"#000000\" }}\n />\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-lg p-2\">\n <div className=\"grid grid-cols-8 gap-1\">\n {COLOR_PRESETS.map((c) => (\n <button\n key={c}\n onClick={() => {\n onChange(c);\n setOpen(false);\n }}\n className={`w-5 h-5 rounded border ${\n c === color ? \"border-blue-500 ring-1 ring-blue-300\" : \"border-gray-300\"\n } hover:scale-110 transition-transform`}\n style={{ backgroundColor: c }}\n title={c}\n />\n ))}\n </div>\n <div className=\"mt-2 pt-2 border-t border-gray-100 flex items-center gap-2\">\n <label className=\"text-xs text-gray-500\">커스텀:</label>\n <input\n type=\"color\"\n value={color && color !== \"none\" ? color : \"#000000\"}\n onChange={(e) => {\n onChange(e.target.value);\n setOpen(false);\n }}\n className=\"w-6 h-6 cursor-pointer border-0\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport {\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n Columns2,\n} from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport type { AlignmentType } from \"@/lib/constants\";\n\nconst ALIGNMENT_ICONS: Record<AlignmentType, React.ReactNode> = {\n LEFT: <AlignLeft className=\"w-3.5 h-3.5\" />,\n CENTER: <AlignCenter className=\"w-3.5 h-3.5\" />,\n RIGHT: <AlignRight className=\"w-3.5 h-3.5\" />,\n JUSTIFY: <AlignJustify className=\"w-3.5 h-3.5\" />,\n DISTRIBUTE: <Columns2 className=\"w-3.5 h-3.5\" />,\n};\n\nconst ALIGNMENT_LABELS: Record<AlignmentType, string> = {\n LEFT: \"왼쪽 정렬 (Ctrl+L)\",\n CENTER: \"가운데 정렬 (Ctrl+E)\",\n RIGHT: \"오른쪽 정렬 (Ctrl+R)\",\n JUSTIFY: \"양쪽 정렬 (Ctrl+J)\",\n DISTRIBUTE: \"배분 정렬\",\n};\n\nexport function AlignmentButtons() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setAlignment = useEditorStore((s) => s.setAlignment);\n\n const disabled = !doc || !selection;\n const currentAlignment = extendedFormat.para.alignment;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n {(Object.keys(ALIGNMENT_ICONS) as AlignmentType[]).map((align) => (\n <ToolbarButton\n key={align}\n icon={ALIGNMENT_ICONS[align]}\n active={currentAlignment === align}\n disabled={disabled}\n onClick={() => setAlignment(align)}\n title={ALIGNMENT_LABELS[align]}\n />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { LINE_SPACING_OPTIONS } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\nexport function LineSpacingControl() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setLineSpacing = useEditorStore((s) => s.setLineSpacing);\n\n const disabled = !doc || !selection;\n const currentSpacing = extendedFormat.para.lineSpacing;\n\n // Find closest matching option\n const closestValue = LINE_SPACING_OPTIONS.reduce((prev, curr) =>\n Math.abs(curr.value - currentSpacing) < Math.abs(prev.value - currentSpacing)\n ? curr\n : prev,\n ).value;\n\n const options = LINE_SPACING_OPTIONS.map((o) => ({\n value: String(o.value),\n label: o.label,\n }));\n\n return (\n <ToolbarDropdown\n value={String(closestValue)}\n options={options}\n onChange={(val) => setLineSpacing(Number(val))}\n disabled={disabled}\n title=\"줄 간격\"\n width=\"w-14\"\n />\n );\n}\n","\"use client\";\n\nexport function ToolbarDivider() {\n return <div className=\"h-6 w-px bg-gray-200 mx-1 self-center\" />;\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { StyleSelector } from \"./StyleSelector\";\nimport { FontSelector } from \"./FontSelector\";\nimport { FontSizeInput } from \"./FontSizeInput\";\nimport { CharFormatButtons } from \"./CharFormatButtons\";\nimport { AlignmentButtons } from \"./AlignmentButtons\";\nimport { LineSpacingControl } from \"./LineSpacingControl\";\nimport { ToolbarDivider } from \"./ToolbarDivider\";\nimport { Plus } from \"lucide-react\";\n\nexport function SecondaryToolbar() {\n const doc = useEditorStore((s) => s.doc);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const addParagraph = useEditorStore((s) => s.addParagraph);\n\n const disabled = !doc;\n\n return (\n <div className=\"flex items-center gap-1 bg-gray-50 border-b border-gray-200 px-3 py-1 flex-wrap min-h-[36px]\">\n {/* Style selector */}\n <StyleSelector\n value=\"0\"\n onChange={() => {\n // Style change — placeholder\n }}\n disabled={disabled}\n />\n\n <ToolbarDivider />\n\n {/* Font selector */}\n <FontSelector\n value={extendedFormat.char.fontFamily || \"맑은 고딕\"}\n onChange={() => {\n // Font change — placeholder\n }}\n disabled={disabled}\n />\n\n {/* Font size */}\n <FontSizeInput\n value={extendedFormat.char.fontSize || 10}\n onChange={() => {\n // Font size change — placeholder\n }}\n disabled={disabled}\n />\n\n <ToolbarDivider />\n\n {/* Character format buttons */}\n <CharFormatButtons />\n\n <ToolbarDivider />\n\n {/* Alignment buttons */}\n <AlignmentButtons />\n\n <ToolbarDivider />\n\n {/* Line spacing */}\n <LineSpacingControl />\n\n {/* Spacer */}\n <div className=\"flex-1\" />\n\n {/* Add paragraph */}\n <button\n disabled={disabled}\n onClick={() => addParagraph(\"\")}\n className=\"flex items-center gap-1 px-2.5 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n <Plus className=\"w-3 h-3\" />\n 문단 추가\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback, useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { pxToHwp } from \"@/lib/hwp-units\";\n\n// ── Indent drag handle components ─────────────────────────────────────────\n\ninterface HandleProps {\n /** Offset from left edge of content area in px */\n positionPx: number;\n onDrag: (deltaPx: number) => void;\n}\n\n/** ▽ First-line indent handle (top triangle) */\nfunction FirstLineHandle({ positionPx, onDrag }: HandleProps) {\n const startXRef = useRef(0);\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n const onMove = (me: MouseEvent) => {\n /* visual-only during drag; commit on up */\n };\n const onUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n const delta = me.clientX - startXRef.current;\n if (Math.abs(delta) >= 2) onDrag(delta);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"ew-resize\";\n },\n [onDrag],\n );\n\n return (\n <div\n className=\"absolute cursor-ew-resize select-none\"\n style={{ left: positionPx - 5, top: 0 }}\n onMouseDown={onMouseDown}\n title=\"첫줄 들여쓰기\"\n >\n <svg width=\"10\" height=\"8\" viewBox=\"0 0 10 8\">\n <polygon points=\"5,8 0,0 10,0\" fill=\"#4A90D9\" />\n </svg>\n </div>\n );\n}\n\n/** △ Left indent handle (bottom triangle) */\nfunction LeftIndentHandle({ positionPx, onDrag }: HandleProps) {\n const startXRef = useRef(0);\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n const onMove = (me: MouseEvent) => {};\n const onUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n const delta = me.clientX - startXRef.current;\n if (Math.abs(delta) >= 2) onDrag(delta);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"ew-resize\";\n },\n [onDrag],\n );\n\n return (\n <div\n className=\"absolute cursor-ew-resize select-none\"\n style={{ left: positionPx - 5, bottom: 0 }}\n onMouseDown={onMouseDown}\n title=\"둘째줄 시작 위치 (왼쪽 들여쓰기)\"\n >\n <svg width=\"10\" height=\"8\" viewBox=\"0 0 10 8\">\n <polygon points=\"5,0 10,8 0,8\" fill=\"#4A90D9\" />\n </svg>\n </div>\n );\n}\n\n/** □ Combined margin handle (bottom rectangle, moves both) */\nfunction CombinedHandle({ positionPx, onDrag }: HandleProps) {\n const startXRef = useRef(0);\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n const onMove = (me: MouseEvent) => {};\n const onUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n const delta = me.clientX - startXRef.current;\n if (Math.abs(delta) >= 2) onDrag(delta);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"ew-resize\";\n },\n [onDrag],\n );\n\n return (\n <div\n className=\"absolute cursor-ew-resize select-none\"\n style={{ left: positionPx - 4, bottom: 8 }}\n onMouseDown={onMouseDown}\n title=\"왼쪽 여백 전체 이동\"\n >\n <svg width=\"8\" height=\"6\" viewBox=\"0 0 8 6\">\n <rect x=\"0\" y=\"0\" width=\"8\" height=\"6\" fill=\"#4A90D9\" rx=\"1\" />\n </svg>\n </div>\n );\n}\n\n// ── Main ruler ────────────────────────────────────────────────────────────\n\nexport function HorizontalRuler() {\n const viewModel = useEditorStore((s) => s.viewModel);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const selection = useEditorStore((s) => s.selection);\n const setFirstLineIndent = useEditorStore((s) => s.setFirstLineIndent);\n const setLeftIndent = useEditorStore((s) => s.setLeftIndent);\n\n if (!viewModel || viewModel.sections.length === 0) return null;\n\n const section = viewModel.sections[0]!;\n const pageWidthPx = section.pageWidthPx;\n const marginLeftPx = section.marginLeftPx;\n const marginRightPx = section.marginRightPx;\n const contentWidthPx = pageWidthPx - marginLeftPx - marginRightPx;\n\n // Current indent values (hwpUnits) from extended format\n const firstLineIndentHwp = extendedFormat.para.firstLineIndent;\n const leftIndentHwp = extendedFormat.para.indentLeft;\n\n // Convert to px for handle positioning\n const firstLineIndentPx = (firstLineIndentHwp * 96) / 7200;\n const leftIndentPx = (leftIndentHwp * 96) / 7200;\n\n // Generate tick marks in mm (every 1mm tick, every 10mm major)\n const mmPerPx = 25.4 / 96; // px to mm\n const totalMm = contentWidthPx * mmPerPx;\n const ticks: { position: number; label: string; major: boolean; medium: boolean }[] = [];\n\n for (let mm = 0; mm <= totalMm + 0.5; mm += 1) {\n const px = mm / mmPerPx;\n const major = mm % 10 === 0;\n const medium = mm % 5 === 0 && !major;\n ticks.push({\n position: px,\n label: major ? String(Math.round(mm / 10)) : \"\",\n major,\n medium,\n });\n }\n\n const hasSelection = !!selection;\n\n const handleFirstLineDrag = useCallback(\n (deltaPx: number) => {\n const deltaHwp = pxToHwp(deltaPx);\n setFirstLineIndent(firstLineIndentHwp + deltaHwp);\n },\n [firstLineIndentHwp, setFirstLineIndent],\n );\n\n const handleLeftIndentDrag = useCallback(\n (deltaPx: number) => {\n const deltaHwp = pxToHwp(deltaPx);\n setLeftIndent(leftIndentHwp + deltaHwp);\n },\n [leftIndentHwp, setLeftIndent],\n );\n\n const handleCombinedDrag = useCallback(\n (deltaPx: number) => {\n const deltaHwp = pxToHwp(deltaPx);\n // Move both, keeping relative position\n setLeftIndent(leftIndentHwp + deltaHwp);\n // firstLineIndent moves with left indent (same delta)\n setTimeout(() => {\n setFirstLineIndent(firstLineIndentHwp + deltaHwp);\n }, 0);\n },\n [firstLineIndentHwp, leftIndentHwp, setFirstLineIndent, setLeftIndent],\n );\n\n return (\n <div className=\"bg-white border-b border-gray-200 overflow-hidden flex-shrink-0\">\n <div className=\"flex justify-center\">\n <div\n className=\"relative\"\n style={{ width: pageWidthPx, height: 28 }}\n >\n {/* Left margin area */}\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{ width: marginLeftPx }}\n />\n {/* Right margin area */}\n <div\n className=\"absolute top-0 right-0 h-full bg-gray-100\"\n style={{ width: marginRightPx }}\n />\n {/* Ruler content area with ticks */}\n <div\n className=\"absolute top-0 h-full\"\n style={{ left: marginLeftPx, width: contentWidthPx }}\n >\n {ticks.map((tick, i) => (\n <div\n key={i}\n className=\"absolute bottom-0\"\n style={{ left: tick.position }}\n >\n <div\n className={`w-px ${\n tick.major\n ? \"h-3 bg-gray-500\"\n : tick.medium\n ? \"h-2 bg-gray-400\"\n : \"h-1 bg-gray-300\"\n }`}\n />\n {tick.label && (\n <span className=\"absolute -top-0.5 left-1/2 -translate-x-1/2 text-[8px] text-gray-400 leading-none select-none\">\n {tick.label}\n </span>\n )}\n </div>\n ))}\n\n {/* Indent handles (only shown when a paragraph is selected) */}\n {hasSelection && (\n <>\n <FirstLineHandle\n positionPx={leftIndentPx + firstLineIndentPx}\n onDrag={handleFirstLineDrag}\n />\n <LeftIndentHandle\n positionPx={leftIndentPx}\n onDrag={handleLeftIndentDrag}\n />\n <CombinedHandle\n positionPx={leftIndentPx}\n onDrag={handleCombinedDrag}\n />\n </>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport type { SidebarTab } from \"@/lib/constants\";\nimport { CharFormatPanel } from \"./CharFormatPanel\";\nimport { ParaFormatPanel } from \"./ParaFormatPanel\";\nimport { PageSetupPanel } from \"./PageSetupPanel\";\nimport { ImageLayoutPanel } from \"./ImageLayoutPanel\";\nimport { ImagePropertiesPanel } from \"./ImagePropertiesPanel\";\nimport { TablePropertiesPanel } from \"./TablePropertiesPanel\";\nimport { PanelRightClose } from \"lucide-react\";\n\ntype SidebarContext = \"text\" | \"image\" | \"table\";\n\nfunction getContext(selection: { objectType?: string; type?: string } | null): SidebarContext {\n if (selection?.objectType === \"image\") return \"image\";\n if (selection?.objectType === \"table\" || selection?.type === \"cell\") return \"table\";\n return \"text\";\n}\n\nconst TEXT_TABS: { tab: SidebarTab; label: string }[] = [\n { tab: \"char\", label: \"글자 모양\" },\n { tab: \"para\", label: \"문단 모양\" },\n { tab: \"page\", label: \"편집 용지\" },\n];\n\nconst IMAGE_TABS: { tab: SidebarTab; label: string }[] = [\n { tab: \"img-layout\", label: \"배치\" },\n { tab: \"img-props\", label: \"그림\" },\n];\n\nconst TABLE_TABS: { tab: SidebarTab; label: string }[] = [\n { tab: \"table\", label: \"표\" },\n];\n\nexport function FormatSidebar() {\n const uiState = useEditorStore((s) => s.uiState);\n const selection = useEditorStore((s) => s.selection);\n const setSidebarTab = useEditorStore((s) => s.setSidebarTab);\n const toggleSidebar = useEditorStore((s) => s.toggleSidebar);\n\n const context = getContext(selection);\n\n const tabs =\n context === \"image\" ? IMAGE_TABS :\n context === \"table\" ? TABLE_TABS :\n TEXT_TABS;\n\n // Auto-switch to first tab of current context when context changes\n useEffect(() => {\n const validTabs = tabs.map((t) => t.tab);\n if (!validTabs.includes(uiState.sidebarTab)) {\n setSidebarTab(validTabs[0]!);\n }\n }, [context]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!uiState.sidebarOpen) return null;\n\n const activeTab = uiState.sidebarTab;\n\n return (\n <div className=\"w-72 border-l border-gray-200 bg-white flex flex-col overflow-hidden flex-shrink-0\">\n {/* Tab header */}\n <div className=\"flex items-center border-b border-gray-200\">\n {tabs.map(({ tab, label }) => (\n <button\n key={tab}\n onClick={() => setSidebarTab(tab)}\n className={`flex-1 py-2 text-xs font-medium text-center transition-colors ${\n activeTab === tab\n ? \"text-blue-600 border-b-2 border-blue-600 bg-blue-50/50\"\n : \"text-gray-500 hover:text-gray-700 hover:bg-gray-50\"\n }`}\n >\n {label}\n </button>\n ))}\n <button\n onClick={toggleSidebar}\n className=\"p-1.5 mr-1 rounded text-gray-400 hover:text-gray-600 hover:bg-gray-100\"\n title=\"사이드바 닫기\"\n >\n <PanelRightClose className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Tab content */}\n <div className=\"flex-1 overflow-auto\">\n {activeTab === \"char\" && <CharFormatPanel />}\n {activeTab === \"para\" && <ParaFormatPanel />}\n {activeTab === \"page\" && <PageSetupPanel />}\n {activeTab === \"img-layout\" && <ImageLayoutPanel />}\n {activeTab === \"img-props\" && <ImagePropertiesPanel />}\n {activeTab === \"table\" && <TablePropertiesPanel />}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, type ReactNode } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\n\ninterface SidebarSectionProps {\n title: string;\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\nexport function SidebarSection({\n title,\n children,\n defaultOpen = true,\n}: SidebarSectionProps) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <div className=\"border-b border-gray-100\">\n <button\n onClick={() => setOpen(!open)}\n className=\"flex items-center gap-1 w-full px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-50\"\n >\n {open ? (\n <ChevronDown className=\"w-3.5 h-3.5 text-gray-400\" />\n ) : (\n <ChevronRight className=\"w-3.5 h-3.5 text-gray-400\" />\n )}\n {title}\n </button>\n {open && <div className=\"px-3 pb-3\">{children}</div>}\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface SidebarFieldProps {\n label: string;\n children: ReactNode;\n}\n\nexport function SidebarField({ label, children }: SidebarFieldProps) {\n return (\n <div className=\"flex items-center gap-2 mb-2\">\n <span className=\"text-[11px] text-gray-500 w-14 flex-shrink-0\">{label}</span>\n <div className=\"flex-1\">{children}</div>\n </div>\n );\n}\n","\"use client\";\n\nimport { SidebarField } from \"./SidebarField\";\n\ninterface BorderSettingsProps {\n disabled?: boolean;\n}\n\nexport function BorderSettings({ disabled }: BorderSettingsProps) {\n return (\n <div className=\"space-y-1\">\n <SidebarField label=\"종류\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"none\">없음</option>\n <option value=\"solid\">실선</option>\n <option value=\"dashed\">점선</option>\n <option value=\"double\">이중선</option>\n </select>\n </SidebarField>\n <SidebarField label=\"두께\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"0.1mm\">0.1mm</option>\n <option value=\"0.12mm\">0.12mm</option>\n <option value=\"0.3mm\">0.3mm</option>\n <option value=\"0.4mm\">0.4mm</option>\n <option value=\"0.5mm\">0.5mm</option>\n <option value=\"1.0mm\">1.0mm</option>\n </select>\n </SidebarField>\n <SidebarField label=\"색\">\n <input\n type=\"color\"\n defaultValue=\"#000000\"\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n </div>\n );\n}\n","\"use client\";\n\nimport { SidebarField } from \"./SidebarField\";\n\ninterface BackgroundSettingsProps {\n disabled?: boolean;\n}\n\nexport function BackgroundSettings({ disabled }: BackgroundSettingsProps) {\n return (\n <div className=\"space-y-1\">\n <SidebarField label=\"채우기\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"none\">없음</option>\n <option value=\"color\">색 채우기</option>\n <option value=\"gradient\">그라데이션</option>\n <option value=\"pattern\">무늬</option>\n </select>\n </SidebarField>\n <SidebarField label=\"배경색\">\n <input\n type=\"color\"\n defaultValue=\"#ffffff\"\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { FONT_FAMILIES, FONT_SIZES } from \"@/lib/constants\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport { BorderSettings } from \"./BorderSettings\";\nimport { BackgroundSettings } from \"./BackgroundSettings\";\n\nexport function CharFormatPanel() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const activeFormat = useEditorStore((s) => s.activeFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setFontFamily = useEditorStore((s) => s.setFontFamily);\n const setFontSize = useEditorStore((s) => s.setFontSize);\n const setTextColor = useEditorStore((s) => s.setTextColor);\n const setHighlightColor = useEditorStore((s) => s.setHighlightColor);\n\n const disabled = !doc || !selection;\n const cf = extendedFormat.char;\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"기본\">\n <SidebarField label=\"스타일\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n defaultValue=\"0\"\n >\n <option value=\"0\">바탕글</option>\n <option value=\"1\">본문</option>\n <option value=\"2\">개요 1</option>\n <option value=\"3\">개요 2</option>\n </select>\n </SidebarField>\n <SidebarField label=\"글꼴\">\n <select\n disabled={disabled}\n value={cf.fontFamily || \"맑은 고딕\"}\n onChange={(e) => setFontFamily(e.target.value)}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {FONT_FAMILIES.map((f) => (\n <option key={f} value={f} style={{ fontFamily: fontFamilyCss(f) }}>\n {f}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"크기\">\n <select\n disabled={disabled}\n value={String(cf.fontSize || 10)}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {FONT_SIZES.map((s) => (\n <option key={s} value={String(s)}>\n {s}pt\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"색상\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"color\"\n value={cf.textColor && cf.textColor !== \"none\" ? cf.textColor : \"#000000\"}\n onChange={(e) => setTextColor(e.target.value)}\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n <span className=\"text-[10px] text-gray-400\">\n {cf.textColor && cf.textColor !== \"none\" ? cf.textColor : \"#000000\"}\n </span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"꾸밈\">\n <div className=\"flex flex-wrap gap-1 mb-2\">\n <FormatTag label=\"굵게\" active={activeFormat.bold} onClick={() => useEditorStore.getState().toggleBold()} disabled={disabled} />\n <FormatTag label=\"기울임\" active={activeFormat.italic} onClick={() => useEditorStore.getState().toggleItalic()} disabled={disabled} />\n <FormatTag label=\"밑줄\" active={activeFormat.underline} onClick={() => useEditorStore.getState().toggleUnderline()} disabled={disabled} />\n <FormatTag label=\"취소선\" active={activeFormat.strikethrough} onClick={() => useEditorStore.getState().toggleStrikethrough()} disabled={disabled} />\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"형광펜\">\n <SidebarField label=\"색상\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"color\"\n value={cf.highlightColor && cf.highlightColor !== \"none\" ? cf.highlightColor : \"#FFFF00\"}\n onChange={(e) => setHighlightColor(e.target.value)}\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n <span className=\"text-[10px] text-gray-400\">\n {cf.highlightColor || \"없음\"}\n </span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <BorderSettings disabled={disabled} />\n </SidebarSection>\n\n <SidebarSection title=\"배경\" defaultOpen={false}>\n <BackgroundSettings disabled={disabled} />\n </SidebarSection>\n </div>\n );\n}\n\nfunction fontFamilyCss(name: string): string {\n if (name === \"Noto Sans KR\") return \"var(--font-noto-sans-kr), sans-serif\";\n if (name === \"Noto Serif KR\") return \"var(--font-noto-serif-kr), serif\";\n return `\"${name}\", sans-serif`;\n}\n\nfunction FormatTag({ label, active, onClick, disabled }: { label: string; active: boolean; onClick?: () => void; disabled?: boolean }) {\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className={`px-2 py-0.5 rounded text-[10px] border transition-colors ${\n active\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-gray-50 border-gray-200 text-gray-400 hover:bg-gray-100\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {label}\n </button>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport {\n ALIGNMENT_OPTIONS,\n LINE_SPACING_OPTIONS,\n type AlignmentType,\n} from \"@/lib/constants\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport { BorderSettings } from \"./BorderSettings\";\nimport { BackgroundSettings } from \"./BackgroundSettings\";\n\nexport function ParaFormatPanel() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setAlignment = useEditorStore((s) => s.setAlignment);\n const setLineSpacing = useEditorStore((s) => s.setLineSpacing);\n\n const disabled = !doc || !selection;\n const pf = extendedFormat.para;\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"정렬\">\n <div className=\"flex gap-1 mb-2\">\n {ALIGNMENT_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n disabled={disabled}\n onClick={() => setAlignment(opt.value)}\n className={`flex-1 py-1 rounded text-[10px] border transition-colors ${\n pf.alignment === opt.value\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n title={opt.label}\n >\n {opt.value === \"LEFT\" && \"왼\"}\n {opt.value === \"CENTER\" && \"중\"}\n {opt.value === \"RIGHT\" && \"오\"}\n {opt.value === \"JUSTIFY\" && \"양\"}\n {opt.value === \"DISTRIBUTE\" && \"배\"}\n </button>\n ))}\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"여백\">\n <SidebarField label=\"왼쪽\">\n <input\n type=\"number\"\n value={pf.indentLeft}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <input\n type=\"number\"\n value={pf.indentRight}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"첫줄\">\n <input\n type=\"number\"\n value={pf.firstLineIndent}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"간격\">\n <SidebarField label=\"줄 간격\">\n <select\n disabled={disabled}\n value={String(\n LINE_SPACING_OPTIONS.reduce((prev, curr) =>\n Math.abs(curr.value - pf.lineSpacing) <\n Math.abs(prev.value - pf.lineSpacing)\n ? curr\n : prev,\n ).value,\n )}\n onChange={(e) => setLineSpacing(Number(e.target.value))}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {LINE_SPACING_OPTIONS.map((o) => (\n <option key={o.value} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"문단 앞\">\n <input\n type=\"number\"\n value={pf.spacingBefore}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"문단 뒤\">\n <input\n type=\"number\"\n value={pf.spacingAfter}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"줄 나눔\" defaultOpen={false}>\n <div className=\"space-y-1\">\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 한글 단어 잘림 허용\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 영어 단어 잘림 허용\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 외톨이줄 방지\n </label>\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <BorderSettings disabled={disabled} />\n </SidebarSection>\n\n <SidebarSection title=\"배경\" defaultOpen={false}>\n <BackgroundSettings disabled={disabled} />\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { PAGE_SIZE_PRESETS, type OrientationType } from \"@/lib/constants\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst PAGE_NUMBER_POSITIONS = [\n { value: \"none\", label: \"없음\" },\n { value: \"header-center\", label: \"머리말 가운데\" },\n { value: \"header-right\", label: \"머리말 오른쪽\" },\n { value: \"footer-center\", label: \"꼬리말 가운데\" },\n { value: \"footer-right\", label: \"꼬리말 오른쪽\" },\n] as const;\n\nexport function PageSetupPanel() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const updatePageSize = useEditorStore((s) => s.updatePageSize);\n const updatePageMargins = useEditorStore((s) => s.updatePageMargins);\n const updatePageOrientation = useEditorStore((s) => s.updatePageOrientation);\n const setPageNumbering = useEditorStore((s) => s.setPageNumbering);\n const viewModel = useEditorStore((s) => s.viewModel);\n\n const [pageNumPosition, setPageNumPosition] = useState(\"none\");\n const [pageNumStart, setPageNumStart] = useState(1);\n\n const disabled = !doc;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc?.sections[sIdx];\n\n const pageSize = section?.properties.pageSize;\n const pageMargins = section?.properties.pageMargins;\n\n const widthMm = pageSize ? parseFloat(hwpToMm(pageSize.width).toFixed(1)) : 210;\n const heightMm = pageSize ? parseFloat(hwpToMm(pageSize.height).toFixed(1)) : 297;\n const orientation: OrientationType =\n pageSize && pageSize.width > pageSize.height ? \"LANDSCAPE\" : \"PORTRAIT\";\n\n const leftMm = pageMargins ? parseFloat(hwpToMm(pageMargins.left).toFixed(1)) : 30;\n const rightMm = pageMargins ? parseFloat(hwpToMm(pageMargins.right).toFixed(1)) : 30;\n const topMm = pageMargins ? parseFloat(hwpToMm(pageMargins.top).toFixed(1)) : 20;\n const bottomMm = pageMargins ? parseFloat(hwpToMm(pageMargins.bottom).toFixed(1)) : 15;\n const headerMm = pageMargins ? parseFloat(hwpToMm(pageMargins.header).toFixed(1)) : 15;\n const footerMm = pageMargins ? parseFloat(hwpToMm(pageMargins.footer).toFixed(1)) : 15;\n const gutterMm = pageMargins ? parseFloat(hwpToMm(pageMargins.gutter).toFixed(1)) : 0;\n\n // Find matching preset\n const matchedPreset = PAGE_SIZE_PRESETS.find(\n (p) => p.width === Math.round(widthMm) && p.height === Math.round(heightMm),\n );\n // Also check landscape match\n const matchedPresetLandscape = PAGE_SIZE_PRESETS.find(\n (p) => p.height === Math.round(widthMm) && p.width === Math.round(heightMm),\n );\n const presetValue = matchedPreset?.name ?? matchedPresetLandscape?.name ?? \"custom\";\n\n const handlePresetChange = (name: string) => {\n const preset = PAGE_SIZE_PRESETS.find((p) => p.name === name);\n if (!preset) return;\n if (orientation === \"LANDSCAPE\") {\n updatePageSize(preset.height, preset.width);\n } else {\n updatePageSize(preset.width, preset.height);\n }\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"용지 크기\">\n <SidebarField label=\"종류\">\n <select\n disabled={disabled}\n value={presetValue}\n onChange={(e) => handlePresetChange(e.target.value)}\n className={inputClass}\n >\n {PAGE_SIZE_PRESETS.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n </option>\n ))}\n {presetValue === \"custom\" && (\n <option value=\"custom\">사용자 지정</option>\n )}\n </select>\n </SidebarField>\n <SidebarField label=\"폭\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={widthMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePageSize(v, heightMm);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"길이\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={heightMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePageSize(widthMm, v);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"용지 방향\">\n <div className=\"flex gap-2 mb-2\">\n <button\n disabled={disabled}\n onClick={() => updatePageOrientation(\"PORTRAIT\")}\n className={`flex-1 py-2 rounded border text-[10px] flex flex-col items-center gap-1 transition-colors ${\n orientation === \"PORTRAIT\"\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n <svg width=\"20\" height=\"26\" viewBox=\"0 0 20 26\" fill=\"none\" className=\"mx-auto\">\n <rect x=\"1\" y=\"1\" width=\"18\" height=\"24\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.5\" fill=\"none\" />\n <line x1=\"4\" y1=\"6\" x2=\"16\" y2=\"6\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"10\" x2=\"16\" y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"14\" x2=\"12\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </svg>\n 세로\n </button>\n <button\n disabled={disabled}\n onClick={() => updatePageOrientation(\"LANDSCAPE\")}\n className={`flex-1 py-2 rounded border text-[10px] flex flex-col items-center gap-1 transition-colors ${\n orientation === \"LANDSCAPE\"\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n <svg width=\"26\" height=\"20\" viewBox=\"0 0 26 20\" fill=\"none\" className=\"mx-auto\">\n <rect x=\"1\" y=\"1\" width=\"24\" height=\"18\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.5\" fill=\"none\" />\n <line x1=\"4\" y1=\"5\" x2=\"22\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"9\" x2=\"22\" y2=\"9\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"13\" x2=\"16\" y2=\"13\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </svg>\n 가로\n </button>\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"제본\">\n <div className=\"flex gap-1 mb-2\">\n {([\"LEFT\", \"FACING\", \"TOP\"] as const).map((type) => (\n <button\n key={type}\n disabled={disabled}\n className={`flex-1 py-1 rounded text-[10px] border transition-colors ${\n \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {type === \"LEFT\" && \"한쪽\"}\n {type === \"FACING\" && \"맞쪽\"}\n {type === \"TOP\" && \"위로\"}\n </button>\n ))}\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"용지 여백\">\n <SidebarField label=\"왼쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={leftMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ left: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={rightMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ right: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"위쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={topMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ top: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"아래쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={bottomMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ bottom: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"머리말\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={headerMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ header: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"꼬리말\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={footerMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ footer: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"제본\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={gutterMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ gutter: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"쪽 번호\">\n <SidebarField label=\"위치\">\n <select\n disabled={disabled}\n value={pageNumPosition}\n onChange={(e) => {\n setPageNumPosition(e.target.value);\n setPageNumbering({ position: e.target.value, startNumber: pageNumStart });\n }}\n className={inputClass}\n >\n {PAGE_NUMBER_POSITIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"시작 번호\">\n <input\n type=\"number\"\n value={pageNumStart}\n disabled={disabled}\n min={1}\n step={1}\n onChange={(e) => {\n const v = parseInt(e.target.value, 10);\n if (!isNaN(v) && v >= 1) {\n setPageNumStart(v);\n }\n }}\n onBlur={() => {\n if (!disabled && pageNumPosition !== \"none\") {\n setPageNumbering({ position: pageNumPosition, startNumber: pageNumStart });\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !disabled && pageNumPosition !== \"none\") {\n setPageNumbering({ position: pageNumPosition, startNumber: pageNumStart });\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst PX_TO_MM = 25.4 / 96;\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\nexport function ImageLayoutPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const updatePictureSize = useEditorStore((s) => s.updatePictureSize);\n const setImageOutMargin = useEditorStore((s) => s.setImageOutMargin);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const imgIdx = selection?.imageIndex ?? 0;\n\n const image = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.images[imgIdx];\n const hasImage = !!image;\n\n const widthMm = image ? parseFloat((image.widthPx * PX_TO_MM).toFixed(2)) : 0;\n const heightMm = image ? parseFloat((image.heightPx * PX_TO_MM).toFixed(2)) : 0;\n\n const [omTop, setOmTop] = useState(image ? roundMm(image.outMargin.top) : 0);\n const [omBottom, setOmBottom] = useState(image ? roundMm(image.outMargin.bottom) : 0);\n const [omLeft, setOmLeft] = useState(image ? roundMm(image.outMargin.left) : 0);\n const [omRight, setOmRight] = useState(image ? roundMm(image.outMargin.right) : 0);\n\n useEffect(() => {\n if (!image) return;\n setOmTop(roundMm(image.outMargin.top));\n setOmBottom(roundMm(image.outMargin.bottom));\n setOmLeft(roundMm(image.outMargin.left));\n setOmRight(roundMm(image.outMargin.right));\n }, [image?.outMargin.top, image?.outMargin.bottom, image?.outMargin.left, image?.outMargin.right]);\n\n const applyOutMargin = () => {\n if (hasImage) setImageOutMargin({ top: omTop, bottom: omBottom, left: omLeft, right: omRight });\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"크기\">\n <SidebarField label=\"너비\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-20 flex-shrink-0\">\n <option>고정 값</option>\n </select>\n <input\n type=\"number\"\n step=\"0.01\"\n value={widthMm}\n disabled={!image}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePictureSize(v, heightMm);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"높이\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-20 flex-shrink-0\">\n <option>고정 값</option>\n </select>\n <input\n type=\"number\"\n step=\"0.01\"\n value={heightMm}\n disabled={!image}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePictureSize(widthMm, v);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mt-1\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 크기 고정\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"위치\">\n <div className=\"mb-2\">\n <span className=\"text-[11px] text-gray-600 block mb-1.5\">본문과의 배치</span>\n <div className=\"flex gap-1\">\n {[\"어울림\", \"자리차지\", \"글 뒤로\", \"글 앞으로\"].map((label, i) => (\n <button\n key={label}\n disabled\n className={`flex-1 py-1.5 rounded border text-[9px] transition-colors flex flex-col items-center gap-0.5 ${\n i === 0\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500\"\n } disabled:opacity-60 disabled:cursor-not-allowed`}\n >\n <svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" className=\"mx-auto\">\n <line x1=\"2\" y1=\"2\" x2=\"18\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"5\" x2=\"18\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <rect x=\"6\" y=\"7\" width=\"8\" height=\"6\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"currentColor\" fillOpacity=\"0.15\" />\n {i === 0 && (\n <>\n <line x1=\"2\" y1=\"8\" x2=\"5\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"15\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"11\" x2=\"5\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"15\" y1=\"11\" x2=\"18\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"14\" x2=\"18\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </>\n )}\n {i === 1 && (\n <line x1=\"2\" y1=\"14\" x2=\"18\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n )}\n {i >= 2 && (\n <>\n <line x1=\"2\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"11\" x2=\"18\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"14\" x2=\"18\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </>\n )}\n </svg>\n {label}\n </button>\n ))}\n </div>\n </div>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mb-3\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 글자처럼 취급\n </label>\n <SidebarField label=\"가로\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-16 flex-shrink-0\">\n <option>문단</option>\n </select>\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"세로\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-16 flex-shrink-0\">\n <option>문단</option>\n </select>\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"개체 회전/기울이기\" defaultOpen={false}>\n <SidebarField label=\"회전각\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n </SidebarField>\n <SidebarField label=\"가로 기울이기\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n </SidebarField>\n <SidebarField label=\"세로 기울이기\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"기타\" defaultOpen={false}>\n <SidebarField label=\"번호 종류\">\n <select disabled className={inputClass}>\n <option>그림</option>\n </select>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 개체 보호\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"바깥 여백\" defaultOpen={false}>\n <SidebarField label=\"위쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omTop}\n onChange={(e) => setOmTop(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"아래쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omBottom}\n onChange={(e) => setOmBottom(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"왼쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omLeft}\n onChange={(e) => setOmLeft(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omRight}\n onChange={(e) => setOmRight(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst PX_TO_MM = 25.4 / 96;\n\nfunction getMediaType(file: File): \"image/png\" | \"image/jpeg\" | \"image/gif\" | \"image/bmp\" {\n const ext = file.name.split(\".\").pop()?.toLowerCase() ?? \"\";\n const typeMap: Record<string, \"image/png\" | \"image/jpeg\" | \"image/gif\" | \"image/bmp\"> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n return typeMap[ext] ?? \"image/png\";\n}\n\nasync function getImageDimensions(data: Uint8Array, mediaType: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve) => {\n const blob = new Blob([data], { type: mediaType });\n const url = URL.createObjectURL(blob);\n const img = new Image();\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n resolve({ width: 100, height: 100 }); // fallback\n };\n img.src = url;\n });\n}\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\nexport function ImagePropertiesPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const doc = useEditorStore((s) => s.doc);\n const setImageOutMargin = useEditorStore((s) => s.setImageOutMargin);\n const insertImage = useEditorStore((s) => s.insertImage);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isInserting, setIsInserting] = useState(false);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const imgIdx = selection?.imageIndex ?? 0;\n\n const image = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.images[imgIdx];\n const hasImage = !!image;\n\n const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setIsInserting(true);\n try {\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n const mediaType = getMediaType(file);\n const dims = await getImageDimensions(data, mediaType);\n // Scale to fit max 150mm width while maintaining aspect ratio\n const maxWidth = 150;\n const scale = dims.width * PX_TO_MM > maxWidth ? maxWidth / (dims.width * PX_TO_MM) : 1;\n const widthMm = dims.width * PX_TO_MM * scale;\n const heightMm = dims.height * PX_TO_MM * scale;\n insertImage(data, mediaType, widthMm, heightMm);\n } catch (err) {\n console.error(\"Failed to insert image:\", err);\n } finally {\n setIsInserting(false);\n if (fileInputRef.current) fileInputRef.current.value = \"\";\n }\n };\n\n const widthMm = image ? parseFloat((image.widthPx * PX_TO_MM).toFixed(2)) : 0;\n const heightMm = image ? parseFloat((image.heightPx * PX_TO_MM).toFixed(2)) : 0;\n\n const [omTop, setOmTop] = useState(image ? roundMm(image.outMargin.top) : 0);\n const [omBottom, setOmBottom] = useState(image ? roundMm(image.outMargin.bottom) : 0);\n const [omLeft, setOmLeft] = useState(image ? roundMm(image.outMargin.left) : 0);\n const [omRight, setOmRight] = useState(image ? roundMm(image.outMargin.right) : 0);\n\n useEffect(() => {\n if (!image) return;\n setOmTop(roundMm(image.outMargin.top));\n setOmBottom(roundMm(image.outMargin.bottom));\n setOmLeft(roundMm(image.outMargin.left));\n setOmRight(roundMm(image.outMargin.right));\n }, [image?.outMargin.top, image?.outMargin.bottom, image?.outMargin.left, image?.outMargin.right]);\n\n const applyOutMargin = () => {\n if (hasImage) setImageOutMargin({ top: omTop, bottom: omBottom, left: omLeft, right: omRight });\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/bmp\"\n className=\"hidden\"\n onChange={handleFileSelect}\n />\n <SidebarSection title=\"그림\">\n <SidebarField label=\"파일 이름\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[11px] text-gray-600 truncate flex-1\">\n {image?.binaryItemIdRef ?? \"-\"}\n </span>\n <button\n disabled={!doc || isInserting}\n onClick={() => fileInputRef.current?.click()}\n className=\"h-6 px-2 text-[10px] border border-gray-300 rounded bg-white text-gray-600 hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed flex-shrink-0\"\n >\n {isInserting ? \"삽입 중...\" : \"그림 삽입\"}\n </button>\n </div>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mt-1\">\n <input type=\"checkbox\" checked disabled className=\"w-3 h-3\" />\n 문서에 포함\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"확대/축소 비율\">\n <SidebarField label=\"가로\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.01\"\n value={100}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <SidebarField label=\"세로\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.01\"\n value={100}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mt-1\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 가로 세로 같은 비율 유지\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"자르기\" defaultOpen={false}>\n {[\"왼쪽\", \"오른쪽\", \"위쪽\", \"아래쪽\"].map((label) => (\n <SidebarField key={label} label={label}>\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n ))}\n </SidebarSection>\n\n <SidebarSection title=\"바깥 여백\" defaultOpen={false}>\n <SidebarField label=\"위쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omTop}\n onChange={(e) => setOmTop(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"아래쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omBottom}\n onChange={(e) => setOmBottom(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"왼쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omLeft}\n onChange={(e) => setOmLeft(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omRight}\n onChange={(e) => setOmRight(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"색 조절\" defaultOpen={false}>\n <SidebarField label=\"색조\">\n <select disabled className={inputClass}>\n <option>효과 없음</option>\n </select>\n </SidebarField>\n <SidebarField label=\"밝기\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <SidebarField label=\"대비\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <div className=\"mt-2 space-y-1\">\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 워터마크 효과\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 그림 반전\n </label>\n </div>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore, type SelectionState } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\n/** Cell merge controls for selected cells */\nfunction CellMergeSection({\n selection,\n hasTable,\n}: {\n selection: SelectionState | null;\n hasTable: boolean;\n}) {\n const mergeSelectedCells = useEditorStore((s) => s.mergeSelectedCells);\n const unmergeSelectedCells = useEditorStore((s) => s.unmergeSelectedCells);\n\n const isCellSelected = selection?.type === \"cell\" && hasTable;\n const hasMultipleCells =\n isCellSelected &&\n selection &&\n selection.row != null &&\n selection.col != null &&\n (selection.endRow !== selection.row || selection.endCol !== selection.col);\n\n const btnClass =\n \"flex-1 py-1.5 px-2 rounded border text-[10px] transition-colors disabled:opacity-40 disabled:cursor-not-allowed\";\n const activeBtnClass = \"bg-white border-gray-300 text-gray-700 hover:bg-gray-50\";\n\n return (\n <SidebarSection title=\"셀 병합\" defaultOpen={true}>\n <div className=\"flex gap-2\">\n <button\n disabled={!isCellSelected || !hasMultipleCells}\n onClick={() => mergeSelectedCells()}\n className={`${btnClass} ${activeBtnClass}`}\n title=\"선택한 셀들을 하나로 병합합니다\"\n >\n 병합\n </button>\n <button\n disabled={!isCellSelected}\n onClick={() => unmergeSelectedCells()}\n className={`${btnClass} ${activeBtnClass}`}\n title=\"병합된 셀을 분리합니다\"\n >\n 병합 해제\n </button>\n </div>\n <div className=\"text-[9px] text-gray-400 mt-1.5\">\n {hasMultipleCells\n ? \"여러 셀 선택됨 - 병합 가능\"\n : isCellSelected\n ? \"Shift+클릭으로 범위 선택 후 병합\"\n : \"셀을 선택하세요\"}\n </div>\n </SidebarSection>\n );\n}\n\n/** Cell size adjustment for selected cells */\nfunction CellSizeSection({\n selection,\n hasTable,\n inputClass,\n}: {\n selection: SelectionState | null;\n hasTable: boolean;\n inputClass: string;\n}) {\n const setSelectedCellsSize = useEditorStore((s) => s.setSelectedCellsSize);\n const [cellWidth, setCellWidth] = useState<number>(30);\n const [cellHeight, setCellHeight] = useState<number>(10);\n\n const isCellSelected = selection?.type === \"cell\" && hasTable;\n const hasMultipleCells =\n isCellSelected &&\n (selection.endRow != null || selection.endCol != null) &&\n (selection.endRow !== selection.row || selection.endCol !== selection.col);\n\n const startRow = Math.min(selection?.row ?? 0, selection?.endRow ?? selection?.row ?? 0);\n const endRow = Math.max(selection?.row ?? 0, selection?.endRow ?? selection?.row ?? 0);\n const startCol = Math.min(selection?.col ?? 0, selection?.endCol ?? selection?.col ?? 0);\n const endCol = Math.max(selection?.col ?? 0, selection?.endCol ?? selection?.col ?? 0);\n\n const selectedRowCount = endRow - startRow + 1;\n const selectedColCount = endCol - startCol + 1;\n\n return (\n <SidebarSection title=\"셀 크기\" defaultOpen={true}>\n <div className=\"text-[10px] text-gray-500 mb-2\">\n {isCellSelected ? (\n hasMultipleCells ? (\n `선택: ${selectedRowCount}행 × ${selectedColCount}열`\n ) : (\n `셀 (${(selection?.row ?? 0) + 1}, ${(selection?.col ?? 0) + 1})`\n )\n ) : (\n \"셀을 선택하세요 (Shift+클릭으로 범위 선택)\"\n )}\n </div>\n <SidebarField label=\"너비 (mm)\">\n <input\n type=\"number\"\n value={cellWidth}\n disabled={!isCellSelected}\n step={1}\n min={5}\n onChange={(e) => setCellWidth(Number(e.target.value))}\n onBlur={() => isCellSelected && cellWidth > 0 && setSelectedCellsSize(cellWidth, undefined)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && isCellSelected && cellWidth > 0) {\n setSelectedCellsSize(cellWidth, undefined);\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"높이 (mm)\">\n <input\n type=\"number\"\n value={cellHeight}\n disabled={!isCellSelected}\n step={1}\n min={3}\n onChange={(e) => setCellHeight(Number(e.target.value))}\n onBlur={() => isCellSelected && cellHeight > 0 && setSelectedCellsSize(undefined, cellHeight)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && isCellSelected && cellHeight > 0) {\n setSelectedCellsSize(undefined, cellHeight);\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n );\n}\n\nexport function TablePropertiesPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const setTablePageBreak = useEditorStore((s) => s.setTablePageBreak);\n const setTableRepeatHeader = useEditorStore((s) => s.setTableRepeatHeader);\n const setTableSize = useEditorStore((s) => s.setTableSize);\n const setTableOutMargin = useEditorStore((s) => s.setTableOutMargin);\n const setTableInMargin = useEditorStore((s) => s.setTableInMargin);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const tIdx = selection?.tableIndex ?? 0;\n\n const table = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.tables[tIdx];\n const hasTable = !!table;\n\n const widthMm = table ? roundMm(table.widthHwp) : 0;\n const heightMm = table ? roundMm(table.heightHwp) : 0;\n\n const [editWidth, setEditWidth] = useState(widthMm);\n const [editHeight, setEditHeight] = useState(heightMm);\n\n // Outer margin state\n const [outTop, setOutTop] = useState(table ? roundMm(table.outMargin.top) : 0);\n const [outBottom, setOutBottom] = useState(table ? roundMm(table.outMargin.bottom) : 0);\n const [outLeft, setOutLeft] = useState(table ? roundMm(table.outMargin.left) : 0);\n const [outRight, setOutRight] = useState(table ? roundMm(table.outMargin.right) : 0);\n\n // Inner margin state\n const [inTop, setInTop] = useState(table ? roundMm(table.inMargin.top) : 0);\n const [inBottom, setInBottom] = useState(table ? roundMm(table.inMargin.bottom) : 0);\n const [inLeft, setInLeft] = useState(table ? roundMm(table.inMargin.left) : 0);\n const [inRight, setInRight] = useState(table ? roundMm(table.inMargin.right) : 0);\n\n useEffect(() => {\n setEditWidth(widthMm);\n setEditHeight(heightMm);\n }, [widthMm, heightMm]);\n\n useEffect(() => {\n if (!table) return;\n setOutTop(roundMm(table.outMargin.top));\n setOutBottom(roundMm(table.outMargin.bottom));\n setOutLeft(roundMm(table.outMargin.left));\n setOutRight(roundMm(table.outMargin.right));\n setInTop(roundMm(table.inMargin.top));\n setInBottom(roundMm(table.inMargin.bottom));\n setInLeft(roundMm(table.inMargin.left));\n setInRight(roundMm(table.inMargin.right));\n }, [table?.outMargin.top, table?.outMargin.bottom, table?.outMargin.left, table?.outMargin.right,\n table?.inMargin.top, table?.inMargin.bottom, table?.inMargin.left, table?.inMargin.right]);\n\n const pageBreak = table?.pageBreak ?? \"CELL\";\n const repeatHeader = table?.repeatHeader ?? false;\n\n const PAGE_BREAK_OPTIONS = [\n { value: \"CELL\" as const, label: \"나눔\", desc: \"쪽 경계에서 표를 나눕니다\" },\n { value: \"CELL\" as const, label: \"셀 단위로 나눔\", desc: \"셀 단위로 나눕니다\" },\n { value: \"NONE\" as const, label: \"나누지 않음\", desc: \"표를 나누지 않습니다\" },\n ];\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"여러 쪽 지원\">\n <div className=\"mb-2\">\n <span className=\"text-[11px] text-gray-600 block mb-1.5\">쪽 경계에서</span>\n <div className=\"flex gap-1\">\n {PAGE_BREAK_OPTIONS.map((opt, i) => {\n const isActive =\n (i <= 1 && pageBreak === \"CELL\") ||\n (i === 2 && pageBreak === \"NONE\");\n return (\n <button\n key={opt.label}\n disabled={!hasTable}\n onClick={() => setTablePageBreak(opt.value)}\n className={`flex-1 py-2 rounded border text-[9px] flex flex-col items-center gap-1 transition-colors ${\n isActive\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-60 disabled:cursor-not-allowed`}\n title={opt.desc}\n >\n <svg width=\"22\" height=\"18\" viewBox=\"0 0 22 18\" fill=\"none\" className=\"mx-auto\">\n <rect x=\"1\" y=\"1\" width=\"20\" height=\"7\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"8\" y1=\"1\" x2=\"8\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n {i === 0 && (\n <>\n <line x1=\"1\" y1=\"4.5\" x2=\"21\" y2=\"4.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" strokeDasharray=\"2 1\" />\n <rect x=\"1\" y=\"10\" width=\"20\" height=\"7\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"8\" y1=\"10\" x2=\"8\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n </>\n )}\n {i === 1 && (\n <>\n <line x1=\"1\" y1=\"4.5\" x2=\"21\" y2=\"4.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" strokeDasharray=\"2 1\" />\n <rect x=\"1\" y=\"10\" width=\"20\" height=\"7\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"8\" y1=\"10\" x2=\"8\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"1\" y1=\"13.5\" x2=\"21\" y2=\"13.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n </>\n )}\n {i === 2 && (\n <line x1=\"1\" y1=\"4.5\" x2=\"21\" y2=\"4.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n )}\n </svg>\n {opt.label}\n </button>\n );\n })}\n </div>\n </div>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mb-2\">\n <input\n type=\"checkbox\"\n checked={repeatHeader}\n disabled={!hasTable}\n onChange={(e) => setTableRepeatHeader(e.target.checked)}\n className=\"w-3 h-3\"\n />\n 제목 줄 자동 반복\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 자동으로 나뉜 표의 경계선 설정\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"표 크기\">\n <SidebarField label=\"너비 (mm)\">\n <input\n type=\"number\"\n value={editWidth}\n disabled={!hasTable}\n step={1}\n min={10}\n onChange={(e) => setEditWidth(Number(e.target.value))}\n onBlur={() => {\n if (hasTable && editWidth > 0) setTableSize(editWidth, editHeight);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && hasTable && editWidth > 0) {\n setTableSize(editWidth, editHeight);\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"높이 (mm)\">\n <input\n type=\"number\"\n value={editHeight}\n disabled={!hasTable}\n step={1}\n min={10}\n onChange={(e) => setEditHeight(Number(e.target.value))}\n onBlur={() => {\n if (hasTable && editHeight > 0) setTableSize(editWidth, editHeight);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && hasTable && editHeight > 0) {\n setTableSize(editWidth, editHeight);\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"표 정보\">\n <SidebarField label=\"행\">\n <input\n type=\"number\"\n value={table?.rowCount ?? 0}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"열\">\n <input\n type=\"number\"\n value={table?.colCount ?? 0}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n\n <CellSizeSection selection={selection} hasTable={hasTable} inputClass={inputClass} />\n\n <CellMergeSection selection={selection} hasTable={hasTable} />\n\n <SidebarSection title=\"바깥 여백\" defaultOpen={false}>\n <SidebarField label=\"위 (mm)\">\n <input type=\"number\" value={outTop} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutTop(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"아래 (mm)\">\n <input type=\"number\" value={outBottom} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutBottom(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"왼쪽 (mm)\">\n <input type=\"number\" value={outLeft} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutLeft(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"오른쪽 (mm)\">\n <input type=\"number\" value={outRight} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutRight(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"안쪽 여백\" defaultOpen={false}>\n <SidebarField label=\"위 (mm)\">\n <input type=\"number\" value={inTop} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInTop(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"아래 (mm)\">\n <input type=\"number\" value={inBottom} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInBottom(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"왼쪽 (mm)\">\n <input type=\"number\" value={inLeft} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInLeft(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"오른쪽 (mm)\">\n <input type=\"number\" value={inRight} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInRight(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <SidebarField label=\"색\">\n <select disabled className={inputClass}>\n <option>검정</option>\n </select>\n </SidebarField>\n <SidebarField label=\"종류\">\n <select disabled className={inputClass}>\n <option>실선</option>\n </select>\n </SidebarField>\n <SidebarField label=\"굵기\">\n <select disabled className={inputClass}>\n <option>0.1 mm</option>\n <option>0.12 mm</option>\n <option>0.15 mm</option>\n <option>0.2 mm</option>\n <option>0.25 mm</option>\n <option>0.3 mm</option>\n <option>0.4 mm</option>\n <option>0.5 mm</option>\n <option>0.6 mm</option>\n <option>0.7 mm</option>\n <option>1.0 mm</option>\n </select>\n </SidebarField>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback, useEffect } from \"react\";\nimport type { ParagraphVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { RunSpan } from \"./RunSpan\";\nimport { TableBlock } from \"./TableBlock\";\nimport { ImageBlock } from \"./ImageBlock\";\nimport { TextBoxBlock } from \"./TextBoxBlock\";\nimport { EquationBlock } from \"./EquationBlock\";\n\ninterface ParagraphBlockProps {\n paragraph: ParagraphVM;\n sectionIndex: number;\n /** Index of this paragraph within the section's paragraphs array */\n localIndex: number;\n /** Total number of paragraphs in this section (for merge/delete bounds) */\n paragraphCount: number;\n}\n\nfunction alignmentToCSS(alignment: string): React.CSSProperties[\"textAlign\"] {\n switch (alignment.toUpperCase()) {\n case \"CENTER\":\n return \"center\";\n case \"RIGHT\":\n return \"right\";\n case \"JUSTIFY\":\n case \"DISTRIBUTE\":\n return \"justify\";\n default:\n return \"left\";\n }\n}\n\nexport function ParagraphBlock({\n paragraph,\n sectionIndex,\n localIndex,\n paragraphCount,\n}: ParagraphBlockProps) {\n const updateParagraphText = useEditorStore((s) => s.updateParagraphText);\n const setSelection = useEditorStore((s) => s.setSelection);\n const selection = useEditorStore((s) => s.selection);\n const splitParagraph = useEditorStore((s) => s.splitParagraph);\n const mergeParagraphWithPrevious = useEditorStore((s) => s.mergeParagraphWithPrevious);\n const deleteBlock = useEditorStore((s) => s.deleteBlock);\n const ref = useRef<HTMLDivElement>(null);\n\n const hasTables = paragraph.tables.length > 0;\n const hasImages = paragraph.images.length > 0;\n const hasTextBoxes = paragraph.textBoxes.length > 0;\n const hasEquations = paragraph.equations.length > 0;\n const hasText = paragraph.runs.length > 0;\n\n const handleBlur = useCallback(() => {\n if (!ref.current) return;\n const newText = ref.current.textContent ?? \"\";\n // Only sync text paragraphs (no tables/images)\n if (!hasTables && !hasImages) {\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (newText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, newText);\n }\n }\n }, [paragraph, sectionIndex, localIndex, hasTables, hasImages, updateParagraphText]);\n\n const handleFocus = useCallback(() => {\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n });\n }, [sectionIndex, localIndex, setSelection]);\n\n // Track text selection changes within this paragraph\n const updateTextSelection = useCallback(() => {\n if (!ref.current) return;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n\n // Check if selection is within this paragraph\n const range = sel.getRangeAt(0);\n if (!ref.current.contains(range.commonAncestorContainer)) return;\n\n // Calculate start and end offsets relative to the entire paragraph text\n const preRangeStart = document.createRange();\n preRangeStart.selectNodeContents(ref.current);\n preRangeStart.setEnd(range.startContainer, range.startOffset);\n const startOffset = preRangeStart.toString().length;\n\n const preRangeEnd = document.createRange();\n preRangeEnd.selectNodeContents(ref.current);\n preRangeEnd.setEnd(range.endContainer, range.endOffset);\n const endOffset = preRangeEnd.toString().length;\n\n // Only update if there's an actual selection (not just cursor)\n if (startOffset !== endOffset) {\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n textStartOffset: startOffset,\n textEndOffset: endOffset,\n });\n } else {\n // Clear text range when selection is collapsed (cursor only)\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n });\n }\n }, [sectionIndex, localIndex, setSelection]);\n\n // Listen for selection changes\n useEffect(() => {\n const handleSelectionChange = () => {\n if (document.activeElement === ref.current) {\n updateTextSelection();\n }\n };\n\n document.addEventListener(\"selectionchange\", handleSelectionChange);\n return () => {\n document.removeEventListener(\"selectionchange\", handleSelectionChange);\n };\n }, [updateTextSelection]);\n\n const insertTab = useEditorStore((s) => s.insertTab);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (hasTables || hasImages || hasTextBoxes || hasEquations) return;\n\n // Tab key: insert tab character\n if (e.key === \"Tab\" && !e.shiftKey && !e.ctrlKey && !e.metaKey) {\n e.preventDefault();\n insertTab();\n return;\n }\n\n // Block Shift+Enter (no soft line break)\n if (e.key === \"Enter\" && e.shiftKey) {\n e.preventDefault();\n return;\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n // Flush current text before split\n const currentText = ref.current?.textContent ?? \"\";\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (currentText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, currentText);\n }\n\n // Get cursor offset within the text\n const sel = window.getSelection();\n let offset = currentText.length;\n if (sel && sel.rangeCount > 0 && ref.current) {\n const range = sel.getRangeAt(0);\n const preRange = document.createRange();\n preRange.selectNodeContents(ref.current);\n preRange.setEnd(range.startContainer, range.startOffset);\n offset = preRange.toString().length;\n }\n\n splitParagraph(sectionIndex, localIndex, offset);\n return;\n }\n\n if (e.key === \"Backspace\") {\n const sel = window.getSelection();\n if (sel && sel.isCollapsed && sel.rangeCount > 0 && ref.current) {\n const range = sel.getRangeAt(0);\n const preRange = document.createRange();\n preRange.selectNodeContents(ref.current);\n preRange.setEnd(range.startContainer, range.startOffset);\n const offset = preRange.toString().length;\n\n if (offset === 0 && localIndex > 0) {\n e.preventDefault();\n // Flush current text\n const currentText = ref.current.textContent ?? \"\";\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (currentText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, currentText);\n }\n mergeParagraphWithPrevious(sectionIndex, localIndex);\n return;\n }\n }\n }\n\n if (e.key === \"Delete\") {\n const sel = window.getSelection();\n if (sel && sel.isCollapsed && sel.rangeCount > 0 && ref.current) {\n const fullText = ref.current.textContent ?? \"\";\n const range = sel.getRangeAt(0);\n const preRange = document.createRange();\n preRange.selectNodeContents(ref.current);\n preRange.setEnd(range.startContainer, range.startOffset);\n const offset = preRange.toString().length;\n\n // At end of paragraph: merge with next\n if (offset >= fullText.length && localIndex < paragraphCount - 1) {\n e.preventDefault();\n // Flush current text\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (fullText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, fullText);\n }\n // Merge next paragraph into this one (implemented as merging next with \"previous\" = current)\n const store = useEditorStore.getState();\n const doc = store.doc;\n if (!doc) return;\n store.pushUndo();\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const nextPara = section.paragraphs[localIndex + 1];\n const currPara = section.paragraphs[localIndex];\n if (!nextPara || !currPara) return;\n const currText = currPara.text;\n const nextText = nextPara.text;\n currPara.text = currText + nextText;\n doc.removeParagraph(sectionIndex, localIndex + 1);\n store.rebuild();\n return;\n }\n }\n }\n // Arrow key navigation between paragraphs\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n const sel = window.getSelection();\n if (!sel || !sel.isCollapsed || !sel.rangeCount || !ref.current) return;\n\n const range = sel.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n const containerRect = ref.current.getBoundingClientRect();\n\n const atTop = rect.top <= containerRect.top + 2;\n const atBottom = rect.bottom >= containerRect.bottom - 2;\n\n if (e.key === \"ArrowUp\" && atTop && localIndex > 0) {\n e.preventDefault();\n const prev = ref.current.parentElement\n ? ref.current.previousElementSibling as HTMLElement | null\n : null;\n // Find previous contenteditable sibling within the page\n const page = ref.current.closest(\"[data-page]\") ?? ref.current.parentElement;\n if (page) {\n const editables = page.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const arr = Array.from(editables);\n const idx = arr.indexOf(ref.current);\n if (idx > 0) {\n const target = arr[idx - 1]!;\n target.focus();\n // Place cursor at end\n const s = window.getSelection();\n if (s) { s.selectAllChildren(target); s.collapseToEnd(); }\n }\n }\n return;\n }\n\n if (e.key === \"ArrowDown\" && atBottom && localIndex < paragraphCount - 1) {\n e.preventDefault();\n const page = ref.current.closest(\"[data-page]\") ?? ref.current.parentElement;\n if (page) {\n const editables = page.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const arr = Array.from(editables);\n const idx = arr.indexOf(ref.current);\n if (idx >= 0 && idx < arr.length - 1) {\n const target = arr[idx + 1]!;\n target.focus();\n // Place cursor at start\n const s = window.getSelection();\n if (s) { s.selectAllChildren(target); s.collapseToStart(); }\n }\n }\n return;\n }\n }\n },\n [sectionIndex, localIndex, paragraph, hasTables, hasImages, hasTextBoxes, hasEquations, paragraphCount, splitParagraph, mergeParagraphWithPrevious, deleteBlock, updateParagraphText, insertTab],\n );\n\n // Common paragraph styles (includes base font for contentEditable typing)\n const paraStyle: React.CSSProperties = {\n textAlign: alignmentToCSS(paragraph.alignment),\n lineHeight: paragraph.lineSpacing,\n marginLeft: paragraph.marginLeftPx || undefined,\n marginRight: paragraph.marginRightPx || undefined,\n textIndent: paragraph.firstLineIndent || undefined,\n paddingTop: paragraph.spacingBefore || undefined,\n paddingBottom: paragraph.spacingAfter || undefined,\n fontSize: paragraph.defaultFontSize ? `${paragraph.defaultFontSize}pt` : undefined,\n fontFamily: paragraph.defaultFontFamily || undefined,\n };\n\n // If paragraph has tables, render them\n if (hasTables) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.tables.map((table) => (\n <TableBlock\n key={table.tableIndex}\n table={table}\n sectionIndex={sectionIndex}\n paragraphIndex={localIndex}\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has images, render them (possibly alongside text)\n if (hasImages) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.images.map((img, i) => (\n <ImageBlock\n key={i}\n image={img}\n selected={\n selection?.sectionIndex === sectionIndex &&\n selection?.paragraphIndex === localIndex &&\n selection?.objectType === \"image\" &&\n selection?.imageIndex === i\n }\n onClick={() =>\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n objectType: \"image\",\n imageIndex: i,\n })\n }\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has text boxes, render them\n if (hasTextBoxes) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.textBoxes.map((tb, i) => (\n <TextBoxBlock\n key={i}\n textBox={tb}\n selected={\n selection?.sectionIndex === sectionIndex &&\n selection?.paragraphIndex === localIndex &&\n selection?.objectType === \"textBox\" &&\n selection?.textBoxIndex === i\n }\n onClick={() =>\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n objectType: \"textBox\",\n textBoxIndex: i,\n })\n }\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has equations, render them\n if (hasEquations) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <span>\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </span>\n )}\n {paragraph.equations.map((eq, i) => (\n <EquationBlock key={i} equation={eq} />\n ))}\n </div>\n );\n }\n\n // Normal text paragraph\n return (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n className=\"outline-none min-h-[1.5em]\"\n style={paraStyle}\n >\n {paragraph.runs.length > 0 ? (\n paragraph.runs.map((run, i) => <RunSpan key={i} run={run} />)\n ) : (\n <br />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport type { RunVM } from \"@/lib/view-model\";\n\ninterface RunSpanProps {\n run: RunVM;\n tabWidth?: number; // Tab width in pixels, default 40\n}\n\nexport function RunSpan({ run, tabWidth = 40 }: RunSpanProps) {\n const style: React.CSSProperties = {};\n\n if (run.bold) style.fontWeight = \"bold\";\n if (run.italic) style.fontStyle = \"italic\";\n\n // Text decoration (underline + strikethrough)\n const decorations: string[] = [];\n if (run.underline) decorations.push(\"underline\");\n if (run.strikethrough) decorations.push(\"line-through\");\n if (decorations.length > 0) style.textDecoration = decorations.join(\" \");\n\n if (run.color && run.color !== \"#000000\") style.color = run.color;\n if (run.fontFamily) {\n if (run.fontFamily === \"Noto Sans KR\") {\n style.fontFamily = \"var(--font-noto-sans-kr), sans-serif\";\n } else if (run.fontFamily === \"Noto Serif KR\") {\n style.fontFamily = \"var(--font-noto-serif-kr), serif\";\n } else {\n style.fontFamily = run.fontFamily;\n }\n }\n if (run.fontSize) style.fontSize = `${run.fontSize}pt`;\n if (run.highlightColor) style.backgroundColor = run.highlightColor;\n if (run.letterSpacing) {\n // hwp letter spacing units -> px approximation\n style.letterSpacing = `${run.letterSpacing / 100}px`;\n }\n\n // Render tab as fixed-width space\n if (run.hasTab) {\n return (\n <span\n style={{ display: \"inline-block\", width: tabWidth, ...style }}\n data-tab=\"true\"\n />\n );\n }\n\n // Render full-width space\n if (run.hasFwSpace) {\n return (\n <span style={style} data-fwspace=\"true\">\n {\"\\u3000\"}\n </span>\n );\n }\n\n // Render line break\n if (run.hasLineBreak) {\n return <br data-linebreak=\"true\" />;\n }\n\n // Render hyperlink\n if (run.hyperlink) {\n return (\n <a\n href={run.hyperlink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ ...style, color: style.color || \"#0066cc\", textDecoration: \"underline\" }}\n onClick={(e) => e.stopPropagation()}\n >\n {run.text}\n </a>\n );\n }\n\n return <span style={style}>{run.text}</span>;\n}\n","\"use client\";\n\nimport { useRef, useCallback } from \"react\";\nimport type { TableVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { pxToHwp, hwpToPx } from \"@/lib/hwp-units\";\nimport { TableCell } from \"./TableCell\";\n\ninterface TableBlockProps {\n table: TableVM;\n sectionIndex: number;\n paragraphIndex: number;\n}\n\n/** Invisible drag handle for column boundary. */\nfunction ColumnResizeHandle({\n colIdx,\n tableHeight,\n sectionIndex,\n paragraphIndex,\n tableIndex,\n}: {\n colIdx: number;\n tableHeight: number;\n sectionIndex: number;\n paragraphIndex: number;\n tableIndex: number;\n}) {\n const resizeTableColumn = useEditorStore((s) => s.resizeTableColumn);\n const startXRef = useRef(0);\n\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n\n const onMouseMove = (me: MouseEvent) => {\n // visual feedback is handled by cursor; actual resize on mouseup\n };\n\n const onMouseUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"\";\n const deltaX = me.clientX - startXRef.current;\n if (Math.abs(deltaX) < 2) return;\n const deltaHwp = pxToHwp(deltaX);\n resizeTableColumn(sectionIndex, paragraphIndex, tableIndex, colIdx, deltaHwp);\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"col-resize\";\n },\n [colIdx, sectionIndex, paragraphIndex, tableIndex, resizeTableColumn],\n );\n\n return (\n <div\n onMouseDown={onMouseDown}\n className=\"absolute top-0 z-10\"\n style={{\n width: 6,\n height: tableHeight || \"100%\",\n cursor: \"col-resize\",\n marginLeft: -3,\n }}\n />\n );\n}\n\nexport function TableBlock({ table, sectionIndex, paragraphIndex }: TableBlockProps) {\n const tableRef = useRef<HTMLDivElement>(null);\n const setSelection = useEditorStore((s) => s.setSelection);\n const selection = useEditorStore((s) => s.selection);\n\n // Check if this table is selected\n const isTableSelected =\n selection?.type === \"table\" &&\n selection.sectionIndex === sectionIndex &&\n selection.paragraphIndex === paragraphIndex &&\n selection.tableIndex === table.tableIndex;\n\n // Compute cumulative column positions for handle placement using columnWidths\n const colPositions: number[] = [];\n let cumX = 0;\n for (let c = 0; c < table.colCount; c++) {\n const widthHwp = table.columnWidths[c] ?? 0;\n cumX += hwpToPx(widthHwp);\n colPositions.push(cumX);\n }\n\n const tableHeightPx = tableRef.current?.offsetHeight ?? 0;\n\n const handleTableClick = useCallback(\n (e: React.MouseEvent) => {\n // Only select table if clicking on the table border area (not inside cells)\n const target = e.target as HTMLElement;\n if (target.tagName === \"TABLE\" || target.closest(\".table-select-area\")) {\n e.stopPropagation();\n setSelection({\n sectionIndex,\n paragraphIndex,\n type: \"table\",\n tableIndex: table.tableIndex,\n objectType: \"table\",\n });\n }\n },\n [sectionIndex, paragraphIndex, table.tableIndex, setSelection],\n );\n\n // Apply outMargin as margin around the table\n const marginTop = hwpToPx(table.outMargin.top) || 8;\n const marginBottom = hwpToPx(table.outMargin.bottom) || 8;\n const marginLeft = hwpToPx(table.outMargin.left) || 0;\n const marginRight = hwpToPx(table.outMargin.right) || 0;\n\n return (\n <div\n className=\"overflow-x-auto relative\"\n ref={tableRef}\n style={{ marginTop, marginBottom, marginLeft, marginRight }}\n >\n {/* Table selection handle - click to select entire table */}\n <div\n className=\"table-select-area absolute -left-6 top-0 w-5 h-5 cursor-pointer flex items-center justify-center hover:bg-blue-100 rounded\"\n onClick={handleTableClick}\n title=\"표 전체 선택\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" stroke=\"#666\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"1\" y1=\"4\" x2=\"11\" y2=\"4\" stroke=\"#666\" strokeWidth=\"0.5\" />\n <line x1=\"1\" y1=\"8\" x2=\"11\" y2=\"8\" stroke=\"#666\" strokeWidth=\"0.5\" />\n <line x1=\"4\" y1=\"1\" x2=\"4\" y2=\"11\" stroke=\"#666\" strokeWidth=\"0.5\" />\n <line x1=\"8\" y1=\"1\" x2=\"8\" y2=\"11\" stroke=\"#666\" strokeWidth=\"0.5\" />\n </svg>\n </div>\n <table\n className={`border-collapse border border-gray-400 ${isTableSelected ? \"outline outline-2 outline-blue-500\" : \"\"}`}\n onClick={handleTableClick}\n >\n <tbody>\n {table.cells.map((row, rIdx) => (\n <tr key={rIdx}>\n {row.map((cell) =>\n cell.isAnchor ? (\n <TableCell\n key={`${cell.row}-${cell.col}`}\n cell={cell}\n sectionIndex={sectionIndex}\n paragraphIndex={paragraphIndex}\n tableIndex={table.tableIndex}\n inMargin={table.inMargin}\n />\n ) : null,\n )}\n </tr>\n ))}\n </tbody>\n </table>\n {/* Column resize handles at each column boundary */}\n {colPositions.map((pos, idx) => (\n <div\n key={idx}\n className=\"absolute top-0\"\n style={{ left: pos }}\n >\n <ColumnResizeHandle\n colIdx={idx}\n tableHeight={tableHeightPx}\n sectionIndex={sectionIndex}\n paragraphIndex={paragraphIndex}\n tableIndex={table.tableIndex}\n />\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback } from \"react\";\nimport type { TableCellVM, MarginVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToPx } from \"@/lib/hwp-units\";\n\ninterface TableCellProps {\n cell: TableCellVM;\n sectionIndex: number;\n paragraphIndex: number;\n tableIndex: number;\n inMargin?: MarginVM;\n}\n\nexport function TableCell({\n cell,\n sectionIndex,\n paragraphIndex,\n tableIndex,\n inMargin,\n}: TableCellProps) {\n const updateCellText = useEditorStore((s) => s.updateCellText);\n const setSelection = useEditorStore((s) => s.setSelection);\n const selection = useEditorStore((s) => s.selection);\n const ref = useRef<HTMLTableCellElement>(null);\n\n const handleBlur = useCallback(() => {\n if (!ref.current) return;\n const newText = ref.current.textContent ?? \"\";\n if (newText !== cell.text) {\n updateCellText(\n sectionIndex,\n paragraphIndex,\n tableIndex,\n cell.row,\n cell.col,\n newText,\n );\n }\n }, [cell, sectionIndex, paragraphIndex, tableIndex, updateCellText]);\n\n const handleFocus = useCallback(() => {\n setSelection({\n sectionIndex,\n paragraphIndex,\n type: \"cell\",\n tableIndex,\n row: cell.row,\n col: cell.col,\n objectType: \"table\",\n });\n }, [sectionIndex, paragraphIndex, tableIndex, cell.row, cell.col, setSelection]);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (e.shiftKey && selection?.type === \"cell\" && selection.tableIndex === tableIndex) {\n // Extend selection to this cell\n e.preventDefault();\n setSelection({\n ...selection,\n endRow: cell.row,\n endCol: cell.col,\n });\n }\n },\n [selection, tableIndex, cell.row, cell.col, setSelection],\n );\n\n // Check if this cell is within the selected range\n const isInSelectedRange = useCallback(() => {\n if (!selection || selection.type !== \"cell\" || selection.tableIndex !== tableIndex) {\n return false;\n }\n const startRow = Math.min(selection.row ?? 0, selection.endRow ?? selection.row ?? 0);\n const endRow = Math.max(selection.row ?? 0, selection.endRow ?? selection.row ?? 0);\n const startCol = Math.min(selection.col ?? 0, selection.endCol ?? selection.col ?? 0);\n const endCol = Math.max(selection.col ?? 0, selection.endCol ?? selection.col ?? 0);\n\n return cell.row >= startRow && cell.row <= endRow && cell.col >= startCol && cell.col <= endCol;\n }, [selection, tableIndex, cell.row, cell.col]);\n\n const isSelected = isInSelectedRange();\n\n if (!cell.isAnchor) return null;\n\n // Apply inMargin as padding (convert from hwpUnits to px)\n const paddingTop = inMargin ? hwpToPx(inMargin.top) : 4;\n const paddingBottom = inMargin ? hwpToPx(inMargin.bottom) : 4;\n const paddingLeft = inMargin ? hwpToPx(inMargin.left) : 8;\n const paddingRight = inMargin ? hwpToPx(inMargin.right) : 8;\n\n return (\n <td\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n colSpan={cell.colSpan > 1 ? cell.colSpan : undefined}\n rowSpan={cell.rowSpan > 1 ? cell.rowSpan : undefined}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onMouseDown={handleMouseDown}\n className={`border border-gray-300 text-sm outline-none ${isSelected ? \"bg-blue-100\" : \"focus:bg-blue-50\"}`}\n style={{\n minWidth: cell.widthPx > 0 ? cell.widthPx : 40,\n minHeight: cell.heightPx > 0 ? cell.heightPx : 24,\n paddingTop,\n paddingBottom,\n paddingLeft,\n paddingRight,\n }}\n >\n {cell.text}\n </td>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback, useState } from \"react\";\nimport type { ImageVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { pxToHwp } from \"@/lib/hwp-units\";\n\ninterface ImageBlockProps {\n image: ImageVM;\n selected?: boolean;\n onClick?: () => void;\n}\n\ntype HandlePosition = \"nw\" | \"n\" | \"ne\" | \"e\" | \"se\" | \"s\" | \"sw\" | \"w\";\n\nconst HANDLE_CURSORS: Record<HandlePosition, string> = {\n nw: \"nwse-resize\",\n n: \"ns-resize\",\n ne: \"nesw-resize\",\n e: \"ew-resize\",\n se: \"nwse-resize\",\n s: \"ns-resize\",\n sw: \"nesw-resize\",\n w: \"ew-resize\",\n};\n\nfunction ResizeHandle({\n position,\n onResize,\n}: {\n position: HandlePosition;\n onResize: (deltaW: number, deltaH: number) => void;\n}) {\n const startRef = useRef({ x: 0, y: 0 });\n\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startRef.current = { x: e.clientX, y: e.clientY };\n\n const onMouseUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"\";\n\n let dx = me.clientX - startRef.current.x;\n let dy = me.clientY - startRef.current.y;\n\n // Map handle position to delta\n let dw = 0;\n let dh = 0;\n if (position.includes(\"e\")) dw = dx;\n if (position.includes(\"w\")) dw = -dx;\n if (position.includes(\"s\")) dh = dy;\n if (position.includes(\"n\")) dh = -dy;\n\n // Corner handles: maintain aspect ratio\n if (position === \"nw\" || position === \"ne\" || position === \"sw\" || position === \"se\") {\n // Use the larger delta as driver\n if (Math.abs(dw) > Math.abs(dh)) {\n dh = dw; // rough 1:1 aspect\n } else {\n dw = dh;\n }\n }\n\n if (Math.abs(dw) >= 2 || Math.abs(dh) >= 2) {\n onResize(pxToHwp(dw), pxToHwp(dh));\n }\n };\n\n const onMouseMove = (_me: MouseEvent) => {\n // visual feedback via cursor only\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = HANDLE_CURSORS[position];\n },\n [position, onResize],\n );\n\n // Position styles for each handle\n const posStyles: React.CSSProperties = { position: \"absolute\" };\n const SIZE = 8;\n const HALF = -SIZE / 2;\n\n switch (position) {\n case \"nw\": posStyles.top = HALF; posStyles.left = HALF; break;\n case \"n\": posStyles.top = HALF; posStyles.left = \"50%\"; posStyles.marginLeft = HALF; break;\n case \"ne\": posStyles.top = HALF; posStyles.right = HALF; break;\n case \"e\": posStyles.top = \"50%\"; posStyles.marginTop = HALF; posStyles.right = HALF; break;\n case \"se\": posStyles.bottom = HALF; posStyles.right = HALF; break;\n case \"s\": posStyles.bottom = HALF; posStyles.left = \"50%\"; posStyles.marginLeft = HALF; break;\n case \"sw\": posStyles.bottom = HALF; posStyles.left = HALF; break;\n case \"w\": posStyles.top = \"50%\"; posStyles.marginTop = HALF; posStyles.left = HALF; break;\n }\n\n return (\n <div\n onMouseDown={onMouseDown}\n className=\"bg-white border border-blue-500 z-20\"\n style={{\n ...posStyles,\n width: SIZE,\n height: SIZE,\n cursor: HANDLE_CURSORS[position],\n }}\n />\n );\n}\n\nconst HANDLES: HandlePosition[] = [\"nw\", \"n\", \"ne\", \"e\", \"se\", \"s\", \"sw\", \"w\"];\n\nexport function ImageBlock({ image, selected, onClick }: ImageBlockProps) {\n const resizeImage = useEditorStore((s) => s.resizeImage);\n\n const handleResize = useCallback(\n (dw: number, dh: number) => {\n resizeImage(dw, dh);\n },\n [resizeImage],\n );\n\n return (\n <div\n className=\"my-2 flex justify-center cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation();\n onClick?.();\n }}\n >\n <div className=\"relative inline-block\">\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={image.dataUrl}\n alt=\"\"\n draggable={false}\n className={selected ? \"ring-2 ring-blue-500\" : \"\"}\n style={{\n width: image.widthPx > 0 ? image.widthPx : undefined,\n height: image.heightPx > 0 ? image.heightPx : undefined,\n maxWidth: \"100%\",\n display: \"block\",\n }}\n />\n {selected && HANDLES.map((pos) => (\n <ResizeHandle key={pos} position={pos} onResize={handleResize} />\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { TextBoxVM } from \"@/lib/view-model\";\n\ninterface TextBoxBlockProps {\n textBox: TextBoxVM;\n selected?: boolean;\n onClick?: () => void;\n}\n\nexport function TextBoxBlock({ textBox, selected, onClick }: TextBoxBlockProps) {\n return (\n <div\n className={`inline-block relative cursor-pointer ${selected ? \"ring-2 ring-blue-500\" : \"\"}`}\n style={{\n width: textBox.widthPx,\n minHeight: textBox.heightPx,\n backgroundColor: textBox.fillColor,\n border: `1px solid ${textBox.borderColor}`,\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n }}\n onClick={onClick}\n >\n <div className=\"whitespace-pre-wrap break-words text-sm\">\n {textBox.text || \"\\u00A0\"}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { EquationVM } from \"@/lib/view-model\";\n\ninterface EquationBlockProps {\n equation: EquationVM;\n}\n\n/**\n * Parse HWP equation script and convert to displayable text.\n * HWP equation language uses special syntax:\n * - _{x} for subscript\n * - ^{x} for superscript\n * - {A} over {B} for fraction\n * - root {n} of {x} for nth root\n * - int _{a} ^{b} for integral\n * - sum _{a} ^{b} for summation\n * - Special symbols: ALPHA, alpha, ohm, INF, etc.\n */\nfunction parseEquationScript(script: string): string {\n if (!script) return \"\";\n\n // Symbol replacements\n const symbols: Record<string, string> = {\n \"ALPHA\": \"\\u0391\", // Greek Alpha\n \"alpha\": \"\\u03B1\", // Greek alpha\n \"BETA\": \"\\u0392\",\n \"beta\": \"\\u03B2\",\n \"GAMMA\": \"\\u0393\",\n \"gamma\": \"\\u03B3\",\n \"DELTA\": \"\\u0394\",\n \"delta\": \"\\u03B4\",\n \"ohm\": \"\\u03A9\",\n \"INF\": \"\\u221E\",\n \"+-\": \"\\u00B1\",\n \"rarrow\": \"\\u2192\",\n \"larrow\": \"\\u2190\",\n \"LRARROW\": \"\\u2194\",\n \"CDOTS\": \"\\u22EF\",\n \"BOT\": \"\\u22A5\",\n \"RTANGLE\": \"\\u221F\",\n \"MSANGLE\": \"\\u2220\",\n \"SMALLSUM\": \"\\u2211\",\n \"vec\": \"\\u20D7\", // combining vector\n \"bar\": \"\\u0305\", // combining overline\n };\n\n let result = script;\n\n // Replace special symbols\n for (const [key, value] of Object.entries(symbols)) {\n result = result.replace(new RegExp(`\\\\b${key}\\\\b`, \"g\"), value);\n }\n\n // Handle subscripts: _{x} -> _x (simplified display)\n result = result.replace(/\\s*_\\s*\\{([^}]*)\\}/g, \"\\u2080$1\"); // Approximation\n\n // Handle superscripts: ^{x} -> ^x\n result = result.replace(/\\s*\\^\\s*\\{([^}]*)\\}/g, \"\\u00B2\"); // Approximation\n\n // Handle fractions: {A} over {B} -> A/B\n result = result.replace(/\\{([^}]*)\\}\\s*over\\s*\\{([^}]*)\\}/g, \"($1)/($2)\");\n\n // Handle roots: root {n} of {x} -> n√x\n result = result.replace(/root\\s*\\{([^}]*)\\}\\s*of\\s*\\{([^}]*)\\}/g, \"$1\\u221A$2\");\n\n // Handle integrals: int _{a} ^{b} -> ∫\n result = result.replace(/\\bint\\b/g, \"\\u222B\");\n result = result.replace(/\\bdint\\b/g, \"\\u222C\"); // double integral\n result = result.replace(/\\boint\\b/g, \"\\u222E\"); // contour integral\n\n // Handle sum\n result = result.replace(/\\bsum\\b/g, \"\\u2211\");\n\n // Handle lim\n result = result.replace(/\\blim\\b/g, \"lim\");\n\n // Remove remaining braces\n result = result.replace(/\\{([^}]*)\\}/g, \"$1\");\n\n // Handle line breaks in equation (# is line break in HWP equations)\n result = result.replace(/#/g, \"\\n\");\n\n // Clean up whitespace\n result = result.replace(/\\s+/g, \" \").trim();\n\n return result;\n}\n\nexport function EquationBlock({ equation }: EquationBlockProps) {\n const displayText = parseEquationScript(equation.script);\n\n return (\n <span\n className=\"inline-block font-serif italic\"\n style={{\n color: equation.textColor,\n minWidth: equation.widthPx,\n minHeight: equation.heightPx,\n verticalAlign: \"middle\",\n whiteSpace: \"pre-wrap\",\n }}\n title={equation.script}\n >\n {displayText || equation.script}\n </span>\n );\n}\n","\"use client\";\n\nimport type { SectionVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ParagraphBlock } from \"./ParagraphBlock\";\n\ninterface PageProps {\n section: SectionVM;\n}\n\nexport function Page({ section }: PageProps) {\n const addParagraph = useEditorStore((s) => s.addParagraph);\n const revision = useEditorStore((s) => s.revision);\n const watermarkText = useEditorStore((s) => s.viewModel?.watermarkText ?? \"\");\n\n /** Clicking empty area of the page focuses or creates a paragraph */\n const handlePageClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Only react to clicks directly on the page container (not on child elements)\n if (e.target !== e.currentTarget) return;\n // If no paragraphs exist, create one\n if (section.paragraphs.length === 0) {\n addParagraph(\"\");\n return;\n }\n // Otherwise, focus the last paragraph's contenteditable\n const container = e.currentTarget;\n const editables = container.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const last = editables[editables.length - 1];\n if (last) {\n last.focus();\n // Place cursor at end\n const sel = window.getSelection();\n if (sel) {\n sel.selectAllChildren(last);\n sel.collapseToEnd();\n }\n }\n };\n\n const hasHeader = section.headerText.length > 0;\n const hasFooter = section.footerText.length > 0;\n const hasFootnotes = section.footnotes.length > 0;\n const hasEndnotes = section.endnotes.length > 0;\n const hasMultiColumn = section.columnLayout.colCount > 1;\n const pageNum = section.pageNum;\n\n // Format page number based on pageNum settings\n const formatPageNum = (num: number): string => {\n if (!pageNum) return String(num);\n let formatted = String(num);\n if (pageNum.formatType === \"ROMAN\") {\n // Convert to Roman numerals (simplified)\n const romanNumerals = [\"\", \"I\", \"II\", \"III\", \"IV\", \"V\", \"VI\", \"VII\", \"VIII\", \"IX\", \"X\"];\n formatted = romanNumerals[num] ?? String(num);\n }\n if (pageNum.sideChar) {\n formatted = `${pageNum.sideChar} ${formatted} ${pageNum.sideChar}`;\n }\n return formatted;\n };\n\n // Determine page number position\n const pageNumAtTop = pageNum?.pos?.startsWith(\"TOP\");\n const pageNumAtBottom = pageNum?.pos?.startsWith(\"BOTTOM\") || (pageNum && !pageNumAtTop);\n\n // Page border styling\n const hasPageBorder = section.pageBorderFill !== null;\n const pageBorderStyle: React.CSSProperties = hasPageBorder ? {\n border: \"1px solid #cccccc\",\n } : {};\n\n return (\n <div\n className=\"bg-white shadow-lg mx-auto mb-8 cursor-text relative overflow-hidden\"\n data-page\n onClick={handlePageClick}\n style={{\n width: section.pageWidthPx,\n minHeight: section.pageHeightPx,\n ...pageBorderStyle,\n }}\n >\n {/* Watermark overlay */}\n {watermarkText && (\n <div\n className=\"absolute inset-0 flex items-center justify-center pointer-events-none select-none z-0\"\n aria-hidden=\"true\"\n >\n <span\n className=\"text-gray-200 font-bold whitespace-nowrap\"\n style={{\n fontSize: Math.min(section.pageWidthPx * 0.12, 120),\n transform: \"rotate(-35deg)\",\n letterSpacing: \"0.15em\",\n opacity: 0.35,\n }}\n >\n {watermarkText}\n </span>\n </div>\n )}\n\n {/* Header area */}\n {(hasHeader || pageNumAtTop) && (\n <div\n className=\"text-center text-[10px] text-gray-400 border-b border-gray-100 relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingTop: Math.max(section.headerHeightPx, 8),\n paddingBottom: 4,\n }}\n >\n {hasHeader ? section.headerText.replace(\"{{page}}\", \"1\") : null}\n {pageNumAtTop && !hasHeader && formatPageNum(1)}\n </div>\n )}\n\n {/* Main content area */}\n <div\n className=\"relative z-10\"\n style={{\n paddingTop: hasHeader ? 4 : section.marginTopPx,\n paddingBottom: hasFooter || hasFootnotes || hasEndnotes ? 4 : section.marginBottomPx,\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n minHeight: section.pageHeightPx - section.marginTopPx - section.marginBottomPx,\n // Multi-column CSS\n ...(hasMultiColumn ? {\n columnCount: section.columnLayout.colCount,\n columnGap: section.columnLayout.sameGap || 20,\n columnRule: \"1px solid #e5e7eb\",\n } : {}),\n }}\n >\n {section.paragraphs.map((para, idx) => (\n <ParagraphBlock\n key={`${section.sectionIndex}-${idx}-r${revision}`}\n paragraph={para}\n sectionIndex={section.sectionIndex}\n localIndex={idx}\n paragraphCount={section.paragraphs.length}\n />\n ))}\n </div>\n\n {/* Footnotes area */}\n {hasFootnotes && (\n <div\n className=\"relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingBottom: 4,\n }}\n >\n <div className=\"border-t border-gray-300 pt-2 mt-2\" style={{ width: \"40%\" }}>\n {section.footnotes.map((fn) => (\n <div key={fn.marker} className=\"text-[9px] text-gray-500 leading-relaxed mb-0.5\">\n <sup className=\"text-[8px] font-medium mr-0.5\">{fn.marker}</sup>\n {fn.text}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Endnotes area (rendered at section end) */}\n {hasEndnotes && (\n <div\n className=\"relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingBottom: 4,\n }}\n >\n <div className=\"border-t-2 border-gray-300 pt-2 mt-4\">\n <div className=\"text-[9px] text-gray-400 font-medium mb-1\">미주</div>\n {section.endnotes.map((en) => (\n <div key={en.marker} className=\"text-[9px] text-gray-500 leading-relaxed mb-0.5\">\n <sup className=\"text-[8px] font-medium mr-0.5\">{en.marker}</sup>\n {en.text}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Footer area */}\n {(hasFooter || pageNumAtBottom) && (\n <div\n className=\"text-center text-[10px] text-gray-400 border-t border-gray-100 relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingTop: 4,\n paddingBottom: Math.max(section.footerHeightPx, 8),\n }}\n >\n {hasFooter ? section.footerText.replace(\"{{page}}\", \"1\") : null}\n {pageNumAtBottom && !hasFooter && formatPageNum(1)}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { Page } from \"./Page\";\n\nexport function PageView() {\n const viewModel = useEditorStore((s) => s.viewModel);\n // Subscribe to revision to trigger re-render\n useEditorStore((s) => s.revision);\n\n if (!viewModel) {\n return (\n <div className=\"flex-1 flex items-center justify-center text-gray-400\">\n 문서를 열거나 새 문서를 만드세요.\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-auto bg-gray-200 py-8\">\n {viewModel.sections.map((section) => (\n <Page key={section.sectionIndex} section={section} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\n\nexport function SaveDialog() {\n const saveDialogOpen = useEditorStore((s) => s.uiState.saveDialogOpen);\n const closeSaveDialog = useEditorStore((s) => s.closeSaveDialog);\n const saveDocumentAs = useEditorStore((s) => s.saveDocumentAs);\n const [filename, setFilename] = useState(\"document\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (saveDialogOpen) {\n setFilename(\"document\");\n // Focus and select text after modal opens\n setTimeout(() => {\n inputRef.current?.focus();\n inputRef.current?.select();\n }, 0);\n }\n }, [saveDialogOpen]);\n\n if (!saveDialogOpen) return null;\n\n const handleSave = () => {\n const name = filename.trim();\n if (!name) return;\n saveDocumentAs(name);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleSave();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n closeSaveDialog();\n }\n };\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40\"\n onClick={(e) => {\n if (e.target === e.currentTarget) closeSaveDialog();\n }}\n >\n <div className=\"bg-white rounded-lg shadow-xl w-96 p-5\">\n <h2 className=\"text-sm font-semibold text-gray-800 mb-4\">\n 다른 이름으로 저장\n </h2>\n\n <label className=\"block text-xs text-gray-600 mb-1.5\">파일 이름</label>\n <div className=\"flex items-center gap-0 mb-5\">\n <input\n ref={inputRef}\n type=\"text\"\n value={filename}\n onChange={(e) => setFilename(e.target.value)}\n onKeyDown={handleKeyDown}\n className=\"flex-1 h-8 px-2 text-sm border border-gray-300 rounded-l focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500\"\n placeholder=\"파일 이름 입력\"\n />\n <span className=\"h-8 px-2 flex items-center text-sm text-gray-500 bg-gray-100 border border-l-0 border-gray-300 rounded-r\">\n .hwpx\n </span>\n </div>\n\n <div className=\"flex justify-end gap-2\">\n <button\n onClick={closeSaveDialog}\n className=\"px-4 py-1.5 text-xs rounded border border-gray-300 text-gray-600 hover:bg-gray-50\"\n >\n 취소\n </button>\n <button\n onClick={handleSave}\n disabled={!filename.trim()}\n className=\"px-4 py-1.5 text-xs rounded bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n 저장\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useState, useRef } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { useEditorStore } from \"@/lib/store\";\n\nexport function FileUpload() {\n const setDocument = useEditorStore((s) => s.setDocument);\n const setLoading = useEditorStore((s) => s.setLoading);\n const setError = useEditorStore((s) => s.setError);\n\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const openFile = useCallback(\n async (file: File) => {\n setLoading(true);\n setError(null);\n try {\n const buffer = await file.arrayBuffer();\n const doc = await HwpxDocument.open(buffer);\n setDocument(doc);\n } catch (e) {\n console.error(\"Failed to open file:\", e);\n setError(\"파일을 열 수 없습니다. HWPX 파일인지 확인하세요.\");\n } finally {\n setLoading(false);\n }\n },\n [setDocument, setLoading, setError],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const file = e.dataTransfer.files[0];\n if (file) openFile(file);\n },\n [openFile],\n );\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setDragging(true);\n }, []);\n\n const handleDragLeave = useCallback(() => {\n setDragging(false);\n }, []);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) openFile(file);\n e.target.value = \"\";\n },\n [openFile],\n );\n\n return (\n <div\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onClick={() => inputRef.current?.click()}\n className={`cursor-pointer border-2 border-dashed rounded-lg p-8 text-center transition-colors ${\n dragging\n ? \"border-blue-400 bg-blue-50\"\n : \"border-gray-300 hover:border-gray-400\"\n }`}\n >\n <Upload className=\"w-10 h-10 mx-auto mb-3 text-gray-400\" />\n <p className=\"text-gray-600 font-medium\">\n HWPX 파일을 드래그하거나 클릭하여 선택\n </p>\n <p className=\"text-sm text-gray-400 mt-1\">.hwpx 파일만 지원</p>\n <input\n ref={inputRef}\n type=\"file\"\n accept=\".hwpx\"\n className=\"hidden\"\n onChange={handleChange}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { FilePlus } from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { createNewDocument } from \"@/lib/skeleton-loader\";\n\nexport function NewDocumentButton() {\n const setDocument = useEditorStore((s) => s.setDocument);\n const setLoading = useEditorStore((s) => s.setLoading);\n const setError = useEditorStore((s) => s.setError);\n\n const handleClick = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const doc = await createNewDocument();\n setDocument(doc);\n } catch (e) {\n console.error(\"Failed to create new document:\", e);\n setError(\"새 문서를 만들 수 없습니다.\");\n } finally {\n setLoading(false);\n }\n }, [setDocument, setLoading, setError]);\n\n return (\n <button\n onClick={handleClick}\n className=\"flex items-center gap-2 px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors\"\n >\n <FilePlus className=\"w-5 h-5\" />\n 새 문서\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { FONT_FAMILIES, COLOR_PRESETS } from \"@/lib/constants\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TABS = [\"기본\", \"확장\", \"테두리/배경\"];\n\n// ── Tab 1: 기본 (Basic) ──────────────────────────────────────────────────────\n\nfunction BasicTab() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const cf = extendedFormat.char;\n\n const [fontSize, setFontSize] = useState(cf.fontSize ?? 10);\n const [fontFamily, setFontFamily] = useState(cf.fontFamily ?? \"함초롬바탕\");\n const [relativeSize, setRelativeSize] = useState(100);\n const [charWidth, setCharWidth] = useState(100);\n const [charPosition, setCharPosition] = useState(0);\n const [letterSpacing, setLetterSpacing] = useState(cf.letterSpacing ?? 0);\n const [textColor, setTextColor] = useState(cf.textColor ?? \"#000000\");\n const [highlightColor, setHighlightColor] = useState(cf.highlightColor ?? \"\");\n\n const [bold, setBold] = useState(cf.bold);\n const [italic, setItalic] = useState(cf.italic);\n const [underline, setUnderline] = useState(cf.underline);\n const [strikethrough, setStrikethrough] = useState(cf.strikethrough);\n\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 기준 크기 */}\n <div className=\"flex items-center gap-2 mb-4\">\n <span className=\"text-xs text-gray-700 w-16\">기준 크기</span>\n <input\n type=\"number\"\n step=\"0.5\"\n min={1}\n max={200}\n value={fontSize}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className={`${inputClass} w-20`}\n />\n <select className={`${selectClass} w-14`} defaultValue=\"pt\">\n <option value=\"pt\">pt</option>\n </select>\n </div>\n\n {/* 언어별 설정 */}\n <DialogSection title=\"언어별 설정\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-14\">언어</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"대표\">\n <option>대표</option>\n <option>한글</option>\n <option>영어</option>\n <option>한자</option>\n <option>일어</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">글꼴</span>\n <select\n className={`${selectClass} flex-1`}\n value={fontFamily}\n onChange={(e) => setFontFamily(e.target.value)}\n >\n {FONT_FAMILIES.map((f) => (\n <option key={f} value={f}>{f}</option>\n ))}\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-14\">상대 크기</span>\n <input type=\"number\" value={relativeSize} onChange={(e) => setRelativeSize(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">장평</span>\n <input type=\"number\" value={charWidth} onChange={(e) => setCharWidth(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-14\">글자 위치</span>\n <input type=\"number\" value={charPosition} onChange={(e) => setCharPosition(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">자간</span>\n <input type=\"number\" value={letterSpacing} onChange={(e) => setLetterSpacing(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n </div>\n </DialogSection>\n\n {/* 속성 */}\n <DialogSection title=\"속성\">\n {/* Attribute buttons - styled A buttons */}\n <div className=\"flex gap-1.5 mb-3 flex-wrap\">\n {[\n { label: \"A\", style: \"font-bold\", title: \"굵게\", active: bold, toggle: () => setBold(!bold) },\n { label: \"A\", style: \"italic\", title: \"기울임\", active: italic, toggle: () => setItalic(!italic) },\n { label: \"A\", style: \"underline\", title: \"밑줄\", active: underline, toggle: () => setUnderline(!underline) },\n { label: \"A\", style: \"line-through\", title: \"취소선\", active: strikethrough, toggle: () => setStrikethrough(!strikethrough) },\n { label: \"A\", style: \"font-outline\", title: \"외곽선\", active: false, toggle: () => {} },\n { label: \"A\", style: \"text-shadow\", title: \"그림자\", active: false, toggle: () => {} },\n { label: \"A\", style: \"tracking-wider\", title: \"양각\", active: false, toggle: () => {} },\n { label: \"A\", style: \"tracking-tighter\", title: \"음각\", active: false, toggle: () => {} },\n ].map((attr, i) => (\n <button\n key={i}\n onClick={attr.toggle}\n title={attr.title}\n className={`w-10 h-10 rounded border text-lg flex items-center justify-center transition-colors ${\n attr.active\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-300 text-gray-700 hover:bg-gray-50\"\n }`}\n >\n <span className={attr.active ? attr.style : \"\"}>{attr.label}</span>\n </button>\n ))}\n {/* Spacer */}\n <div className=\"w-2\" />\n {/* Additional attribute buttons (위 첨자, 아래 첨자, etc.) */}\n {[\"위첨자\", \"아래첨자\", \"보통\"].map((title, i) => (\n <button\n key={`extra-${i}`}\n title={title}\n className=\"w-10 h-10 rounded border bg-white border-gray-300 text-gray-700 hover:bg-gray-50 flex items-center justify-center\"\n >\n <span className=\"text-[9px]\">{title.slice(0, 2)}</span>\n </button>\n ))}\n </div>\n\n {/* Color pickers */}\n <div className=\"flex items-center gap-6\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">글자 색</span>\n <div className=\"relative\">\n <input\n type=\"color\"\n value={textColor}\n onChange={(e) => setTextColor(e.target.value)}\n className=\"w-24 h-7 rounded border border-gray-300 cursor-pointer\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">음영 색</span>\n <select\n className={`${selectClass} w-28`}\n value={highlightColor}\n onChange={(e) => setHighlightColor(e.target.value)}\n >\n <option value=\"\">색 없음</option>\n {COLOR_PRESETS.map((c) => (\n <option key={c} value={c}>{c}</option>\n ))}\n </select>\n </div>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 2: 확장 (Extended) ────────────────────────────────────────────────────\n\nfunction ExtendedTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 그림자 */}\n <DialogSection title=\"그림자\">\n <div className=\"flex items-center gap-6 mb-2\">\n {[\"없음\", \"비연속\", \"연속\"].map((label, i) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"shadow\" defaultChecked={i === 0} className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-12\">X 방향</span>\n <input type=\"number\" disabled className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-12\">Y 방향</span>\n <input type=\"number\" disabled className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n </div>\n <div className=\"flex items-center gap-2 mt-2\">\n <span className=\"text-xs text-gray-400 w-12\">색</span>\n <select disabled className={`${selectClass} flex-1`}>\n <option>검정</option>\n </select>\n </div>\n </DialogSection>\n\n {/* 밑줄 */}\n <DialogSection title=\"밑줄\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">위치</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"없음\">\n <option>없음</option>\n <option>글자 아래</option>\n <option>글자 가운데</option>\n <option>글자 위</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-10\">색</span>\n <select disabled className={`${selectClass} flex-1`}>\n <option>검정</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-10\">종류</span>\n <select disabled className={`${selectClass} flex-1`}>\n <option>실선</option>\n </select>\n </div>\n </div>\n </DialogSection>\n\n {/* 취소선 */}\n <DialogSection title=\"취소선\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">모양</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>실선</option>\n <option>이중선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">색</span>\n <input type=\"color\" defaultValue=\"#000000\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n </div>\n </DialogSection>\n\n {/* 기타 */}\n <DialogSection title=\"기타\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">외곽선</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"없음\">\n <option>없음</option>\n <option>실선</option>\n <option>이중선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">강조점</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"없음\">\n <option>없음</option>\n <option>점</option>\n <option>원</option>\n </select>\n </div>\n </div>\n <div className=\"flex items-center gap-6 mt-2\">\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 글꼴에 어울리는 빈 칸\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 커닝\n </label>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 3: 테두리/배경 (Border/Background) ────────────────────────────────────\n\nfunction BorderBackgroundTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 테두리 */}\n <DialogSection title=\"테두리\">\n <div className=\"flex gap-4\">\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">종류</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>실선</option>\n <option>점선</option>\n <option>파선</option>\n <option>이중선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">굵기</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"0.1 mm\">\n <option>0.1 mm</option>\n <option>0.12 mm</option>\n <option>0.15 mm</option>\n <option>0.2 mm</option>\n <option>0.3 mm</option>\n <option>0.4 mm</option>\n <option>0.5 mm</option>\n <option>1.0 mm</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">색</span>\n <input type=\"color\" defaultValue=\"#000000\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n </div>\n {/* Preview */}\n <div className=\"w-44 h-28 border border-gray-300 rounded bg-white flex items-center justify-center\">\n <span className=\"text-[10px] text-gray-300\">미리보기</span>\n </div>\n </div>\n </DialogSection>\n\n {/* 배경 */}\n <DialogSection title=\"배경\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">면 색</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"색 없음\">\n <option>색 없음</option>\n <option>흰색</option>\n <option>검정</option>\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2 mt-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 색</span>\n <input type=\"color\" defaultValue=\"#c0c0c0\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 모양</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"\">\n <option value=\"\">없음</option>\n </select>\n </div>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Main Dialog ───────────────────────────────────────────────────────────────\n\nexport function CharFormatDialog() {\n const open = useEditorStore((s) => s.uiState.charFormatDialogOpen);\n const closeCharFormatDialog = useEditorStore((s) => s.closeCharFormatDialog);\n const [activeTab, setActiveTab] = useState(0);\n\n const handleApply = useCallback(() => {\n // Apply changes from the dialog\n // For now, close the dialog (values are already applied via sidebar)\n closeCharFormatDialog();\n }, [closeCharFormatDialog]);\n\n return (\n <Dialog title=\"글자 모양\" open={open} onClose={closeCharFormatDialog} onApply={handleApply} width={580}>\n <DialogTabs tabs={TABS} activeTab={activeTab} onTabChange={setActiveTab} />\n {activeTab === 0 && <BasicTab />}\n {activeTab === 1 && <ExtendedTab />}\n {activeTab === 2 && <BorderBackgroundTab />}\n\n {/* 미리보기 */}\n <div className=\"mt-4\">\n <div className=\"text-xs font-bold text-gray-800 mb-1.5\">미리보기</div>\n <div className=\"bg-white border border-gray-200 rounded-md p-4 min-h-[60px] flex items-end\">\n <span className=\"text-sm text-gray-600\">한글Eng123漢字あいう※☉</span>\n </div>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, type ReactNode } from \"react\";\n\ninterface DialogProps {\n title: string;\n open: boolean;\n onClose: () => void;\n onApply?: () => void;\n children: ReactNode;\n width?: number;\n}\n\nexport function Dialog({ title, open, onClose, onApply, children, width = 560 }: DialogProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-[100] flex items-center justify-center bg-black/30\">\n <div\n ref={dialogRef}\n className=\"bg-[#f0f0f0] rounded-lg shadow-2xl flex flex-col max-h-[90vh]\"\n style={{ width }}\n >\n {/* Title bar */}\n <div className=\"text-center py-2.5 text-sm font-medium text-gray-800 border-b border-gray-300/50\">\n {title}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto px-5 py-3\">\n {children}\n </div>\n\n {/* Footer with buttons */}\n <div className=\"flex justify-end gap-2 px-5 py-3 border-t border-gray-300/50\">\n <button\n onClick={onClose}\n className=\"px-6 py-1.5 text-sm bg-white border border-gray-300 rounded hover:bg-gray-50 text-gray-700\"\n >\n 취소\n </button>\n {onApply && (\n <button\n onClick={onApply}\n className=\"px-6 py-1.5 text-sm bg-blue-500 border border-blue-600 rounded hover:bg-blue-600 text-white font-medium\"\n >\n 설정\n </button>\n )}\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\ninterface DialogTabsProps {\n tabs: string[];\n activeTab: number;\n onTabChange: (index: number) => void;\n}\n\nexport function DialogTabs({ tabs, activeTab, onTabChange }: DialogTabsProps) {\n return (\n <div className=\"flex justify-center gap-0 mb-4\">\n {tabs.map((label, idx) => (\n <button\n key={label}\n onClick={() => onTabChange(idx)}\n className={`px-4 py-1.5 text-xs border transition-colors ${\n activeTab === idx\n ? \"bg-white border-gray-300 font-semibold text-gray-900 shadow-sm\"\n : \"bg-transparent border-transparent text-gray-500 hover:text-gray-700\"\n } ${idx === 0 ? \"rounded-l\" : \"\"} ${idx === tabs.length - 1 ? \"rounded-r\" : \"\"}`}\n >\n {label}\n </button>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface DialogSectionProps {\n title: string;\n children: ReactNode;\n}\n\nexport function DialogSection({ title, children }: DialogSectionProps) {\n return (\n <div className=\"mb-4\">\n <div className=\"text-xs font-bold text-gray-800 mb-1.5\">{title}</div>\n <div className=\"bg-gray-100 border border-gray-200 rounded-md p-3\">\n {children}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TABS = [\"기본\", \"확장\", \"탭 설정\", \"테두리/배경\"];\n\n// ── Tab 1: 기본 (Basic) ──────────────────────────────────────────────────────\n\nfunction BasicTab() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const pf = extendedFormat.para;\n\n const [alignment, setAlignment] = useState<string>(pf.alignment);\n const [marginLeft, setMarginLeft] = useState(pf.indentLeft);\n const [marginRight, setMarginRight] = useState(pf.indentRight);\n const [firstLineMode, setFirstLineMode] = useState<\"보통\" | \"들여쓰기\" | \"내어쓰기\">(\"보통\");\n const [firstLineValue, setFirstLineValue] = useState(pf.firstLineIndent);\n const [lineSpacingType] = useState(\"글자에 따라\");\n const [lineSpacingValue, setLineSpacingValue] = useState(Math.round(pf.lineSpacing * 100));\n const [spacingBefore, setSpacingBefore] = useState(pf.spacingBefore);\n const [spacingAfter, setSpacingAfter] = useState(pf.spacingAfter);\n\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n const alignments: { value: string; label: string }[] = [\n { value: \"LEFT\", label: \"왼쪽 정렬\" },\n { value: \"CENTER\", label: \"가운데 정렬\" },\n { value: \"RIGHT\", label: \"오른쪽 정렬\" },\n { value: \"JUSTIFY\", label: \"양쪽 정렬\" },\n { value: \"DISTRIBUTE\", label: \"배분 정렬\" },\n { value: \"BOTH\", label: \"나눠쓰기\" },\n ];\n\n return (\n <>\n {/* 정렬 방식 */}\n <DialogSection title=\"정렬 방식\">\n <div className=\"flex gap-1.5\">\n {alignments.map((a) => (\n <button\n key={a.value}\n onClick={() => setAlignment(a.value)}\n title={a.label}\n className={`w-12 h-9 rounded border flex items-center justify-center transition-colors ${\n alignment === a.value\n ? \"bg-blue-50 border-blue-300\"\n : \"bg-white border-gray-300 hover:bg-gray-50\"\n }`}\n >\n <svg width=\"20\" height=\"14\" viewBox=\"0 0 20 14\" fill=\"none\">\n {a.value === \"LEFT\" && (\n <>\n <line x1=\"2\" y1=\"2\" x2=\"16\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"5\" x2=\"12\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"11\" x2=\"10\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n {a.value === \"CENTER\" && (\n <>\n <line x1=\"3\" y1=\"2\" x2=\"17\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"5\" y1=\"5\" x2=\"15\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"4\" y1=\"8\" x2=\"16\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"6\" y1=\"11\" x2=\"14\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n {a.value === \"RIGHT\" && (\n <>\n <line x1=\"4\" y1=\"2\" x2=\"18\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"8\" y1=\"5\" x2=\"18\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"6\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"10\" y1=\"11\" x2=\"18\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n {(a.value === \"JUSTIFY\" || a.value === \"DISTRIBUTE\" || a.value === \"BOTH\") && (\n <>\n <line x1=\"2\" y1=\"2\" x2=\"18\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"5\" x2=\"18\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"11\" x2={a.value === \"JUSTIFY\" ? \"14\" : \"18\"} y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n </svg>\n </button>\n ))}\n </div>\n </DialogSection>\n\n {/* 여백 + 첫 줄 */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <DialogSection title=\"여백\">\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">왼쪽</span>\n <input type=\"number\" step=\"0.1\" value={marginLeft} onChange={(e) => setMarginLeft(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">오른쪽</span>\n <input type=\"number\" step=\"0.1\" value={marginRight} onChange={(e) => setMarginRight(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n </div>\n </DialogSection>\n </div>\n <div className=\"flex-1\">\n <DialogSection title=\"첫 줄\">\n <div className=\"space-y-1.5\">\n {[\"보통\", \"들여쓰기\", \"내어쓰기\"].map((label) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input\n type=\"radio\"\n name=\"firstLine\"\n checked={firstLineMode === label}\n onChange={() => setFirstLineMode(label as typeof firstLineMode)}\n className=\"w-3.5 h-3.5\"\n />\n {label}\n </label>\n ))}\n <div className=\"flex items-center gap-1 mt-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={firstLineValue}\n onChange={(e) => setFirstLineValue(Number(e.target.value))}\n disabled={firstLineMode === \"보통\"}\n className={`${inputClass} w-24 disabled:opacity-40`}\n />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n </div>\n </DialogSection>\n </div>\n </div>\n\n {/* 간격 */}\n <DialogSection title=\"간격\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">줄 간격</span>\n <select className={`${selectClass} flex-1`} defaultValue={lineSpacingType}>\n <option>글자에 따라</option>\n <option>고정 값</option>\n <option>최소</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">문단 위</span>\n <input type=\"number\" step=\"0.1\" value={spacingBefore} onChange={(e) => setSpacingBefore(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\" />\n <input type=\"number\" value={lineSpacingValue} onChange={(e) => setLineSpacingValue(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">문단 아래</span>\n <input type=\"number\" step=\"0.1\" value={spacingAfter} onChange={(e) => setSpacingAfter(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600 mt-2\">\n <input type=\"checkbox\" defaultChecked className=\"w-3.5 h-3.5\" />\n 편집 용지의 줄 격자 사용\n </label>\n </DialogSection>\n\n {/* 줄 나눔 기준 */}\n <DialogSection title=\"줄 나눔 기준\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">한글 단위</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"글자\">\n <option>글자</option>\n <option>어절</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">최소 공백</span>\n <input type=\"number\" defaultValue={100} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">영어 단위</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"단어\">\n <option>단어</option>\n <option>하이픈</option>\n </select>\n </div>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 2: 확장 (Extended) ────────────────────────────────────────────────────\n\nfunction ExtendedTab() {\n return (\n <>\n {/* 문단 종류 */}\n <DialogSection title=\"문단 종류\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-1.5\">\n {[\"없음\", \"글머리표 문단\", \"개요 문단\", \"번호 문단\"].map((label, i) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"paraType\" defaultChecked={i === 0} className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"flex items-center gap-2 mt-2\">\n <span className=\"text-xs text-gray-400 w-10\">수준</span>\n <select disabled className=\"h-7 px-2 text-xs border border-gray-300 rounded bg-white flex-1 disabled:opacity-40\">\n <option>1 수준</option>\n </select>\n </div>\n </DialogSection>\n\n {/* 기타 */}\n <DialogSection title=\"기타\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-1.5\">\n {[\n \"외톨이줄 보호\", \"다음 문단과 함께\",\n \"문단 보호\", \"문단 앞에서 항상 쪽 나눔\",\n \"글꼴에 어울리는 줄 높이\", \"한 줄로 입력\",\n \"한글과 영어 간격을 자동 조절\", \"한글과 숫자 간격을 자동 조절\",\n ].map((label) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"flex items-center gap-2 mt-3 pt-2 border-t border-gray-200\">\n <span className=\"text-xs text-gray-600 w-14\">세로 정렬</span>\n <select className=\"h-7 px-2 text-xs border border-gray-300 rounded bg-white flex-1\" defaultValue=\"글꼴 기준\">\n <option>글꼴 기준</option>\n <option>위쪽</option>\n <option>가운데</option>\n <option>아래쪽</option>\n </select>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 3: 탭 설정 (Tab Settings) ─────────────────────────────────────────────\n\nfunction TabSettingsTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 탭 종류 */}\n <DialogSection title=\"탭 종류\">\n <div className=\"flex items-center gap-4 mb-2\">\n {[\"왼쪽\", \"오른쪽\", \"가운데\", \"소수점\"].map((label, i) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"tabType\" defaultChecked={i === 0} className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">채울 모양</span>\n <select className={`${selectClass} w-28`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>점선</option>\n <option>실선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">탭 위치</span>\n <input type=\"number\" step=\"0.1\" defaultValue={5.0} className={`${inputClass} w-20`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n <button className=\"h-7 px-3 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50\">\n 추가\n </button>\n </div>\n </div>\n </DialogSection>\n\n {/* 탭 목록 + 지운 탭 목록 */}\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <DialogSection title=\"탭 목록\">\n <div className=\"border border-gray-200 rounded bg-white min-h-[100px]\">\n <div className=\"grid grid-cols-2 text-[10px] text-gray-500 border-b border-gray-200 px-2 py-1\">\n <span>위치</span>\n <span>종류</span>\n </div>\n <div className=\"px-2 py-1 text-[10px] text-gray-400\">\n (없음)\n </div>\n </div>\n </DialogSection>\n </div>\n <div className=\"flex flex-col justify-center gap-1 pt-6\">\n <button className=\"w-7 h-7 rounded border border-gray-300 bg-white text-red-500 hover:bg-red-50 flex items-center justify-center text-sm\">\n ×\n </button>\n <button className=\"w-7 h-7 rounded border border-gray-300 bg-white text-red-500 hover:bg-red-50 flex items-center justify-center text-sm\">\n ×\n </button>\n </div>\n <div className=\"flex-1\">\n <DialogSection title=\"지운 탭 목록\">\n <div className=\"border border-gray-200 rounded bg-white min-h-[100px]\">\n <div className=\"px-2 py-1 text-[10px] text-gray-400\">\n (없음)\n </div>\n </div>\n </DialogSection>\n </div>\n </div>\n\n {/* 편집 + 기본 탭 */}\n <DialogSection title=\"편집\">\n <div className=\"flex items-center gap-6\">\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 내어쓰기용 자동 탭\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 문단 오른쪽 끝 자동 탭\n </label>\n </div>\n </DialogSection>\n <DialogSection title=\"기본 탭\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">구역 기본 탭 간격 :</span>\n <span className=\"text-xs text-gray-800 font-medium\">40.0 pt</span>\n <button className=\"h-7 px-3 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 ml-2\">\n 변경\n </button>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 4: 테두리/배경 ─────────────────────────────────────────────────────────\n\nfunction ParaBorderBackgroundTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 테두리 */}\n <DialogSection title=\"테두리\">\n <div className=\"flex gap-4\">\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">종류</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>실선</option>\n <option>점선</option>\n <option>파선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">굵기</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"0.1 mm\">\n <option>0.1 mm</option>\n <option>0.3 mm</option>\n <option>0.5 mm</option>\n <option>1.0 mm</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">색</span>\n <input type=\"color\" defaultValue=\"#000000\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600 mt-1\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 문단 테두리 연결\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" defaultChecked className=\"w-3.5 h-3.5\" />\n 선 모양 바로 적용\n </label>\n </div>\n <div className=\"w-44 h-28 border border-gray-300 rounded bg-white flex items-center justify-center\">\n <span className=\"text-[10px] text-gray-300\">미리보기</span>\n </div>\n </div>\n </DialogSection>\n\n {/* 배경 */}\n <DialogSection title=\"배경\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">면 색</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"색 없음\">\n <option>색 없음</option>\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2 mt-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 색</span>\n <input type=\"color\" defaultValue=\"#c0c0c0\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 모양</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"\">\n <option value=\"\">없음</option>\n </select>\n </div>\n </div>\n </DialogSection>\n\n {/* 간격 */}\n <DialogSection title=\"간격\">\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">왼쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">오른쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">위쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">아래쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600 mt-2\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 문단 여백 무시\n </label>\n </DialogSection>\n </>\n );\n}\n\n// ── Main Dialog ───────────────────────────────────────────────────────────────\n\nexport function ParaFormatDialog() {\n const open = useEditorStore((s) => s.uiState.paraFormatDialogOpen);\n const closeParaFormatDialog = useEditorStore((s) => s.closeParaFormatDialog);\n const [activeTab, setActiveTab] = useState(0);\n\n const handleApply = useCallback(() => {\n closeParaFormatDialog();\n }, [closeParaFormatDialog]);\n\n return (\n <Dialog title=\"문단 모양\" open={open} onClose={closeParaFormatDialog} onApply={handleApply} width={580}>\n <DialogTabs tabs={TABS} activeTab={activeTab} onTabChange={setActiveTab} />\n {activeTab === 0 && <BasicTab />}\n {activeTab === 1 && <ExtendedTab />}\n {activeTab === 2 && <TabSettingsTab />}\n {activeTab === 3 && <ParaBorderBackgroundTab />}\n\n {/* 미리보기 (only for basic tab) */}\n {activeTab === 0 && (\n <div className=\"mt-4\">\n <div className=\"text-xs font-bold text-gray-800 mb-1.5\">미리보기</div>\n <div className=\"bg-white border border-gray-200 rounded-md p-3 min-h-[70px]\">\n <div className=\"text-[9px] text-gray-500 leading-relaxed\">\n 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단\n </div>\n <div className=\"text-[9px] text-gray-700 leading-relaxed mt-1\">\n 가나다라AaBbCc12345 가나다라AaBbCc12345 가나다라AaBbCc12345\n </div>\n </div>\n </div>\n )}\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TABS = [\"문단 번호\", \"글머리표\", \"그림 글머리표\"];\n\n// Numbering style definitions\nconst NUMBERING_STYLES = [\n { id: \"none\", lines: [\"\", \"\", \"\", \"\"], label: \"없음\" },\n { id: \"1a\", lines: [\"1.\", \"가.\", \"1)\", \"가)\"], label: \"1.가.1)가)\" },\n { id: \"1b\", lines: [\"(1)\", \"(가)\", \"(a)\", \"1)\"], label: \"(1)(가)(a)1)\" },\n { id: \"1c\", lines: [\"1)\", \"가)\", \"a)\", \"(1)\"], label: \"1)가)a)(1)\" },\n { id: \"1d\", lines: [\"①\", \"(ㄱ)\", \"(a)\", \"1)\"], label: \"①(ㄱ)(a)1)\" },\n { id: \"1e\", lines: [\"가)\", \"a)\", \"(1)\", \"(가)\"], label: \"가)a)(1)(가)\" },\n { id: \"1f\", lines: [\"(ㄱ)\", \"(1)\", \"(a)\", \"1)\"], label: \"(ㄱ)(1)(a)1)\" },\n { id: \"1g\", lines: [\"I.\", \"A.\", \"1.\", \"i)\"], label: \"I.A.1.i)\" },\n];\n\nconst BULLET_STYLES = [\n \"●\", \"•\", \"■\", \"▪\", \"◆\", \"◇\", \"▶\", \"▷\",\n \"○\", \"□\", \"◇\", \"▷\", \"◎\", \"☑\", \"✓\", \"★\",\n];\n\n// ── Tab 1: 문단 번호 ─────────────────────────────────────────────────────────\n\nfunction NumberingTab() {\n const [selected, setSelected] = useState(0);\n\n return (\n <>\n <DialogSection title=\"각주 내용 번호 속성\">\n <div className=\"flex items-center gap-4 mb-2\">\n {[\"앞 번호 목록에 이어\", \"이전 번호 목록에 이어\"].map((label) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-400\">\n <input type=\"radio\" name=\"numCont\" disabled className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"numCont\" defaultChecked className=\"w-3.5 h-3.5\" />\n 새 번호 목록 시작\n </label>\n <div className=\"flex items-center gap-2 mt-1.5 ml-5\">\n <span className=\"text-xs text-gray-600\">1 수준 시작 번호</span>\n <input type=\"number\" defaultValue={1} className=\"h-7 px-2 text-xs border border-gray-300 rounded bg-white w-28\" />\n </div>\n </DialogSection>\n\n <DialogSection title=\"문단 번호 모양\">\n <div className=\"grid grid-cols-4 gap-2\">\n {NUMBERING_STYLES.map((style, idx) => (\n <button\n key={style.id}\n onClick={() => setSelected(idx)}\n className={`p-2 rounded border text-left min-h-[80px] transition-colors ${\n selected === idx\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n {idx === 0 ? (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"w-8 h-8 border border-gray-300 rounded flex items-center justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">\n <line x1=\"2\" y1=\"14\" x2=\"14\" y2=\"2\" stroke=\"#dc2626\" strokeWidth=\"1.5\" />\n </svg>\n </div>\n </div>\n ) : (\n <div className=\"space-y-0.5\">\n {style.lines.map((line, li) => (\n <div key={li} className=\"flex items-center gap-1\">\n <span className=\"text-[9px] text-gray-700 w-6\">{line}</span>\n <div className=\"flex-1 h-[1px] bg-gray-300\" />\n </div>\n ))}\n </div>\n )}\n </button>\n ))}\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 2: 글머리표 ──────────────────────────────────────────────────────────\n\nfunction BulletTab() {\n const [selected, setSelected] = useState(0);\n\n return (\n <DialogSection title=\"글머리표 모양\">\n <div className=\"grid grid-cols-4 gap-2\">\n {/* \"None\" option */}\n <button\n onClick={() => setSelected(0)}\n className={`p-3 rounded border min-h-[80px] flex items-center justify-center transition-colors ${\n selected === 0\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"w-8 h-8 border border-gray-300 rounded flex items-center justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">\n <line x1=\"2\" y1=\"14\" x2=\"14\" y2=\"2\" stroke=\"#dc2626\" strokeWidth=\"1.5\" />\n </svg>\n </div>\n </button>\n {/* Bullet styles */}\n {BULLET_STYLES.map((bullet, idx) => (\n <button\n key={idx}\n onClick={() => setSelected(idx + 1)}\n className={`p-2 rounded border min-h-[80px] transition-colors ${\n selected === idx + 1\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm\">{bullet}</span>\n <div className=\"flex-1 h-[1px] bg-gray-300\" />\n </div>\n <div className=\"flex items-center gap-1 ml-3\">\n <div className=\"flex-1 h-[1px] bg-gray-200\" />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm\">{bullet}</span>\n <div className=\"flex-1 h-[1px] bg-gray-300\" />\n </div>\n <div className=\"flex items-center gap-1 ml-3\">\n <div className=\"flex-1 h-[1px] bg-gray-200\" />\n </div>\n </div>\n </button>\n ))}\n </div>\n </DialogSection>\n );\n}\n\n// ── Tab 3: 그림 글머리표 ──────────────────────────────────────────────────────\n\nfunction PictureBulletTab() {\n return (\n <DialogSection title=\"그림 글머리표\">\n <div className=\"text-xs text-gray-400 text-center py-8\">\n 그림 글머리표를 선택하세요. (미지원)\n </div>\n </DialogSection>\n );\n}\n\n// ── Main Dialog ───────────────────────────────────────────────────────────────\n\nexport function BulletNumberDialog() {\n const open = useEditorStore((s) => s.uiState.bulletNumberDialogOpen);\n const closeBulletNumberDialog = useEditorStore((s) => s.closeBulletNumberDialog);\n const [activeTab, setActiveTab] = useState(0);\n\n const handleApply = useCallback(() => {\n closeBulletNumberDialog();\n }, [closeBulletNumberDialog]);\n\n return (\n <Dialog title=\"문단 번호/글머리표\" open={open} onClose={closeBulletNumberDialog} onApply={handleApply} width={620}>\n <DialogTabs tabs={TABS} activeTab={activeTab} onTabChange={setActiveTab} />\n {activeTab === 0 && <NumberingTab />}\n {activeTab === 1 && <BulletTab />}\n {activeTab === 2 && <PictureBulletTab />}\n\n <div className=\"flex items-center gap-2 mt-3\">\n <button disabled className=\"h-7 px-3 text-xs border border-gray-300 rounded bg-white text-gray-400\">\n 사용자 정의...\n </button>\n <button disabled className=\"w-7 h-7 rounded border border-gray-300 bg-white text-red-400 flex items-center justify-center text-sm\">\n ×\n </button>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback, useMemo } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\n\n// ── Character categories ─────────────────────────────────────────────────────\n\ninterface CharCategory {\n label: string;\n chars: string[];\n}\n\nconst CATEGORIES: CharCategory[] = [\n {\n label: \"특수 문자\",\n chars: [\n \"※\", \"☆\", \"★\", \"○\", \"●\", \"◎\", \"◇\", \"◆\", \"□\", \"■\", \"△\", \"▲\", \"▽\", \"▼\", \"◁\", \"◀\", \"▷\", \"▶\",\n \"♤\", \"♠\", \"♡\", \"♥\", \"♧\", \"♣\", \"♢\", \"♦\", \"☎\", \"☏\", \"☜\", \"☞\", \"♨\", \"☀\", \"☁\", \"☂\",\n \"♬\", \"♪\", \"♩\", \"♭\", \"♯\", \"†\", \"‡\", \"¶\", \"§\", \"©\", \"®\", \"™\", \"℃\", \"℉\", \"㎜\", \"㎝\",\n \"㎞\", \"㎡\", \"㎥\", \"㏄\", \"㎏\", \"㎎\", \"㎍\", \"㎖\", \"㎗\", \"ℓ\", \"㎐\", \"㎑\", \"㎒\", \"㎓\", \"㎔\", \"㏊\",\n \"㏘\", \"㏗\", \"㎴\", \"㎵\", \"㎶\", \"㎷\", \"㎸\", \"㎹\", \"㎺\", \"㎻\", \"㎼\", \"㎽\", \"㎾\", \"㎿\", \"㎀\", \"㎁\",\n \"㎂\", \"㎃\", \"㎄\", \"㎈\", \"㎉\", \"㎊\", \"㎋\", \"㎌\", \"㎕\", \"㎙\", \"㎚\", \"㎛\", \"㎟\", \"㎠\", \"㎢\", \"㎣\",\n ],\n },\n {\n label: \"원/괄호 문자\",\n chars: [\n \"①\", \"②\", \"③\", \"④\", \"⑤\", \"⑥\", \"⑦\", \"⑧\", \"⑨\", \"⑩\", \"⑪\", \"⑫\", \"⑬\", \"⑭\", \"⑮\",\n \"⑴\", \"⑵\", \"⑶\", \"⑷\", \"⑸\", \"⑹\", \"⑺\", \"⑻\", \"⑼\", \"⑽\", \"⑾\", \"⑿\", \"⒀\", \"⒁\", \"⒂\",\n \"Ⓐ\", \"Ⓑ\", \"Ⓒ\", \"Ⓓ\", \"Ⓔ\", \"Ⓕ\", \"Ⓖ\", \"Ⓗ\", \"Ⓘ\", \"Ⓙ\", \"Ⓚ\", \"Ⓛ\", \"Ⓜ\", \"Ⓝ\", \"Ⓞ\",\n \"Ⓟ\", \"Ⓠ\", \"Ⓡ\", \"Ⓢ\", \"Ⓣ\", \"Ⓤ\", \"Ⓥ\", \"Ⓦ\", \"Ⓧ\", \"Ⓨ\", \"Ⓩ\",\n \"ⓐ\", \"ⓑ\", \"ⓒ\", \"ⓓ\", \"ⓔ\", \"ⓕ\", \"ⓖ\", \"ⓗ\", \"ⓘ\", \"ⓙ\", \"ⓚ\", \"ⓛ\", \"ⓜ\", \"ⓝ\", \"ⓞ\",\n \"ⓟ\", \"ⓠ\", \"ⓡ\", \"ⓢ\", \"ⓣ\", \"ⓤ\", \"ⓥ\", \"ⓦ\", \"ⓧ\", \"ⓨ\", \"ⓩ\",\n \"㉠\", \"㉡\", \"㉢\", \"㉣\", \"㉤\", \"㉥\", \"㉦\", \"㉧\", \"㉨\", \"㉩\", \"㉪\", \"㉫\", \"㉬\", \"㉭\",\n \"㈀\", \"㈁\", \"㈂\", \"㈃\", \"㈄\", \"㈅\", \"㈆\", \"㈇\", \"㈈\", \"㈉\", \"㈊\", \"㈋\", \"㈌\", \"㈍\",\n ],\n },\n {\n label: \"수학 기호\",\n chars: [\n \"±\", \"×\", \"÷\", \"≠\", \"≤\", \"≥\", \"∞\", \"∴\", \"∵\", \"∈\", \"∋\", \"⊂\", \"⊃\", \"⊆\", \"⊇\", \"∪\",\n \"∩\", \"∧\", \"∨\", \"¬\", \"⇒\", \"⇔\", \"∀\", \"∃\", \"∅\", \"∇\", \"∂\", \"∫\", \"∬\", \"∮\", \"√\", \"∑\",\n \"∏\", \"≡\", \"≒\", \"≪\", \"≫\", \"∝\", \"∠\", \"⊥\", \"⌒\", \"∥\", \"∼\", \"≈\", \"⊙\", \"∘\", \"⊕\", \"⊗\",\n \"⁰\", \"¹\", \"²\", \"³\", \"⁴\", \"⁵\", \"⁶\", \"⁷\", \"⁸\", \"⁹\", \"⁺\", \"⁻\", \"⁼\", \"⁽\", \"⁾\", \"ⁿ\",\n \"₀\", \"₁\", \"₂\", \"₃\", \"₄\", \"₅\", \"₆\", \"₇\", \"₈\", \"₉\", \"₊\", \"₋\", \"₌\", \"₍\", \"₎\",\n \"¼\", \"½\", \"¾\", \"⅓\", \"⅔\", \"⅕\", \"⅖\", \"⅗\", \"⅘\", \"⅙\", \"⅚\", \"⅛\", \"⅜\", \"⅝\", \"⅞\",\n ],\n },\n {\n label: \"화살표\",\n chars: [\n \"←\", \"→\", \"↑\", \"↓\", \"↔\", \"↕\", \"↖\", \"↗\", \"↘\", \"↙\", \"⇐\", \"⇒\", \"⇑\", \"⇓\", \"⇔\", \"⇕\",\n \"↠\", \"↣\", \"↦\", \"↩\", \"↪\", \"↰\", \"↱\", \"↲\", \"↳\", \"↴\", \"↵\", \"↶\", \"↷\", \"↺\", \"↻\",\n \"⟵\", \"⟶\", \"⟷\", \"⟸\", \"⟹\", \"⟺\",\n \"➔\", \"➘\", \"➙\", \"➚\", \"➛\", \"➜\", \"➝\", \"➞\", \"➟\", \"➠\", \"➡\", \"➢\", \"➣\", \"➤\", \"➥\", \"➦\",\n ],\n },\n {\n label: \"도형\",\n chars: [\n \"■\", \"□\", \"▢\", \"▣\", \"▤\", \"▥\", \"▦\", \"▧\", \"▨\", \"▩\", \"▪\", \"▫\", \"▬\", \"▭\", \"▮\", \"▯\",\n \"▰\", \"▱\", \"▲\", \"△\", \"▴\", \"▵\", \"▶\", \"▷\", \"▸\", \"▹\", \"►\", \"▻\", \"▼\", \"▽\", \"▾\", \"▿\",\n \"◀\", \"◁\", \"◂\", \"◃\", \"◄\", \"◅\", \"◆\", \"◇\", \"◈\", \"◉\", \"◊\", \"○\", \"◌\", \"◍\", \"◎\", \"●\",\n \"◐\", \"◑\", \"◒\", \"◓\", \"◔\", \"◕\", \"◖\", \"◗\", \"◘\", \"◙\", \"◚\", \"◛\", \"◜\", \"◝\", \"◞\", \"◟\",\n \"◠\", \"◡\", \"◢\", \"◣\", \"◤\", \"◥\", \"◦\", \"◧\", \"◨\", \"◩\", \"◪\", \"◫\", \"◬\", \"◭\", \"◮\", \"◯\",\n ],\n },\n {\n label: \"선 그리기\",\n chars: [\n \"─\", \"━\", \"│\", \"┃\", \"┄\", \"┅\", \"┆\", \"┇\", \"┈\", \"┉\", \"┊\", \"┋\",\n \"┌\", \"┍\", \"┎\", \"┏\", \"┐\", \"┑\", \"┒\", \"┓\", \"└\", \"┕\", \"┖\", \"┗\",\n \"┘\", \"┙\", \"┚\", \"┛\", \"├\", \"┝\", \"┞\", \"┟\", \"┠\", \"┡\", \"┢\", \"┣\",\n \"┤\", \"┥\", \"┦\", \"┧\", \"┨\", \"┩\", \"┪\", \"┫\", \"┬\", \"┭\", \"┮\", \"┯\",\n \"┰\", \"┱\", \"┲\", \"┳\", \"┴\", \"┵\", \"┶\", \"┷\", \"┸\", \"┹\", \"┺\", \"┻\",\n \"┼\", \"┽\", \"┾\", \"┿\", \"╀\", \"╁\", \"╂\", \"╃\", \"╄\", \"╅\", \"╆\", \"╇\",\n \"╈\", \"╉\", \"╊\", \"╋\", \"╌\", \"╍\", \"╎\", \"╏\",\n \"═\", \"║\", \"╒\", \"╓\", \"╔\", \"╕\", \"╖\", \"╗\", \"╘\", \"╙\", \"╚\", \"╛\",\n \"╜\", \"╝\", \"╞\", \"╟\", \"╠\", \"╡\", \"╢\", \"╣\", \"╤\", \"╥\", \"╦\", \"╧\",\n \"╨\", \"╩\", \"╪\", \"╫\", \"╬\",\n ],\n },\n {\n label: \"그리스/라틴\",\n chars: [\n \"Α\", \"Β\", \"Γ\", \"Δ\", \"Ε\", \"Ζ\", \"Η\", \"Θ\", \"Ι\", \"Κ\", \"Λ\", \"Μ\", \"Ν\", \"Ξ\", \"Ο\", \"Π\",\n \"Ρ\", \"Σ\", \"Τ\", \"Υ\", \"Φ\", \"Χ\", \"Ψ\", \"Ω\",\n \"α\", \"β\", \"γ\", \"δ\", \"ε\", \"ζ\", \"η\", \"θ\", \"ι\", \"κ\", \"λ\", \"μ\", \"ν\", \"ξ\", \"ο\", \"π\",\n \"ρ\", \"σ\", \"τ\", \"υ\", \"φ\", \"χ\", \"ψ\", \"ω\",\n \"À\", \"Á\", \"Â\", \"Ã\", \"Ä\", \"Å\", \"Æ\", \"Ç\", \"È\", \"É\", \"Ê\", \"Ë\", \"Ì\", \"Í\", \"Î\", \"Ï\",\n \"Ð\", \"Ñ\", \"Ò\", \"Ó\", \"Ô\", \"Õ\", \"Ö\", \"Ø\", \"Ù\", \"Ú\", \"Û\", \"Ü\", \"Ý\", \"Þ\", \"ß\",\n \"à\", \"á\", \"â\", \"ã\", \"ä\", \"å\", \"æ\", \"ç\", \"è\", \"é\", \"ê\", \"ë\", \"ì\", \"í\", \"î\", \"ï\",\n \"ð\", \"ñ\", \"ò\", \"ó\", \"ô\", \"õ\", \"ö\", \"ø\", \"ù\", \"ú\", \"û\", \"ü\", \"ý\", \"þ\", \"ÿ\",\n ],\n },\n {\n label: \"한글 자모\",\n chars: [\n \"ㄱ\", \"ㄲ\", \"ㄳ\", \"ㄴ\", \"ㄵ\", \"ㄶ\", \"ㄷ\", \"ㄸ\", \"ㄹ\", \"ㄺ\", \"ㄻ\", \"ㄼ\", \"ㄽ\", \"ㄾ\", \"ㄿ\", \"ㅀ\",\n \"ㅁ\", \"ㅂ\", \"ㅃ\", \"ㅄ\", \"ㅅ\", \"ㅆ\", \"ㅇ\", \"ㅈ\", \"ㅉ\", \"ㅊ\", \"ㅋ\", \"ㅌ\", \"ㅍ\", \"ㅎ\",\n \"ㅏ\", \"ㅐ\", \"ㅑ\", \"ㅒ\", \"ㅓ\", \"ㅔ\", \"ㅕ\", \"ㅖ\", \"ㅗ\", \"ㅘ\", \"ㅙ\", \"ㅚ\", \"ㅛ\", \"ㅜ\", \"ㅝ\", \"ㅞ\",\n \"ㅟ\", \"ㅠ\", \"ㅡ\", \"ㅢ\", \"ㅣ\",\n \"ㆍ\", \"ㆎ\",\n ],\n },\n {\n label: \"일본어\",\n chars: [\n \"ぁ\", \"あ\", \"ぃ\", \"い\", \"ぅ\", \"う\", \"ぇ\", \"え\", \"ぉ\", \"お\", \"か\", \"が\", \"き\", \"ぎ\", \"く\", \"ぐ\",\n \"け\", \"げ\", \"こ\", \"ご\", \"さ\", \"ざ\", \"し\", \"じ\", \"す\", \"ず\", \"せ\", \"ぜ\", \"そ\", \"ぞ\", \"た\", \"だ\",\n \"ち\", \"ぢ\", \"っ\", \"つ\", \"づ\", \"て\", \"で\", \"と\", \"ど\", \"な\", \"に\", \"ぬ\", \"ね\", \"の\", \"は\", \"ば\",\n \"ァ\", \"ア\", \"ィ\", \"イ\", \"ゥ\", \"ウ\", \"ェ\", \"エ\", \"ォ\", \"オ\", \"カ\", \"ガ\", \"キ\", \"ギ\", \"ク\", \"グ\",\n \"ケ\", \"ゲ\", \"コ\", \"ゴ\", \"サ\", \"ザ\", \"シ\", \"ジ\", \"ス\", \"ズ\", \"セ\", \"ゼ\", \"ソ\", \"ゾ\", \"タ\", \"ダ\",\n \"チ\", \"ヂ\", \"ッ\", \"ツ\", \"ヅ\", \"テ\", \"デ\", \"ト\", \"ド\", \"ナ\", \"ニ\", \"ヌ\", \"ネ\", \"ノ\", \"ハ\", \"バ\",\n ],\n },\n {\n label: \"기타 기호\",\n chars: [\n \"、\", \"。\", \"〃\", \"〈\", \"〉\", \"《\", \"》\", \"「\", \"」\", \"『\", \"』\", \"【\", \"】\", \"〔\", \"〕\", \"〖\",\n \"〗\", \"〘\", \"〙\", \"〚\", \"〛\", \"〜\", \"〝\", \"〞\", \"〟\", \"〰\",\n \"✁\", \"✂\", \"✃\", \"✄\", \"✆\", \"✇\", \"✈\", \"✉\", \"✌\", \"✍\", \"✎\", \"✏\", \"✐\", \"✑\", \"✒\", \"✓\",\n \"✔\", \"✕\", \"✖\", \"✗\", \"✘\", \"✙\", \"✚\", \"✛\", \"✜\", \"✝\", \"✞\", \"✟\", \"✠\", \"✡\", \"✢\", \"✣\",\n \"✤\", \"✥\", \"✦\", \"✧\", \"✩\", \"✪\", \"✫\", \"✬\", \"✭\", \"✮\", \"✯\", \"✰\", \"✱\", \"✲\", \"✳\", \"✴\",\n \"✵\", \"✶\", \"✷\", \"✸\", \"✹\", \"✺\", \"✻\", \"✼\", \"✽\", \"✾\", \"✿\", \"❀\", \"❁\", \"❂\", \"❃\", \"❄\",\n ],\n },\n];\n\nconst TAB_LABELS = CATEGORIES.map((c) => c.label);\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction charCodeInfo(ch: string): string {\n const cp = ch.codePointAt(0);\n if (cp === undefined) return \"\";\n return `U+${cp.toString(16).toUpperCase().padStart(4, \"0\")}`;\n}\n\n// ── Main Dialog ──────────────────────────────────────────────────────────────\n\nexport function CharMapDialog() {\n const open = useEditorStore((s) => s.uiState.charMapDialogOpen);\n const closeCharMapDialog = useEditorStore((s) => s.closeCharMapDialog);\n const insertTextAtCursor = useEditorStore((s) => s.insertTextAtCursor);\n\n const [activeTab, setActiveTab] = useState(0);\n const [selected, setSelected] = useState<string | null>(null);\n const [recentChars, setRecentChars] = useState<string[]>([]);\n\n const category = CATEGORIES[activeTab]!;\n\n const handleCharClick = useCallback((ch: string) => {\n setSelected(ch);\n }, []);\n\n const handleCharDoubleClick = useCallback((ch: string) => {\n insertTextAtCursor(ch);\n setRecentChars((prev) => {\n const next = [ch, ...prev.filter((c) => c !== ch)];\n return next.slice(0, 32);\n });\n }, [insertTextAtCursor]);\n\n const handleInsert = useCallback(() => {\n if (!selected) return;\n insertTextAtCursor(selected);\n setRecentChars((prev) => {\n const next = [selected, ...prev.filter((c) => c !== selected)];\n return next.slice(0, 32);\n });\n }, [selected, insertTextAtCursor]);\n\n const selectedInfo = useMemo(() => {\n if (!selected) return \"\";\n return charCodeInfo(selected);\n }, [selected]);\n\n return (\n <Dialog title=\"문자표\" open={open} onClose={closeCharMapDialog} onApply={handleInsert} width={640}>\n {/* Category tabs — use a compact horizontal scroll instead of DialogTabs for many categories */}\n <div className=\"flex gap-0 mb-3 overflow-x-auto border-b border-gray-200 pb-0\">\n {TAB_LABELS.map((label, idx) => (\n <button\n key={label}\n onClick={() => { setActiveTab(idx); setSelected(null); }}\n className={`px-3 py-1.5 text-xs whitespace-nowrap border-b-2 transition-colors ${\n activeTab === idx\n ? \"border-blue-500 text-blue-700 font-semibold\"\n : \"border-transparent text-gray-500 hover:text-gray-700\"\n }`}\n >\n {label}\n </button>\n ))}\n </div>\n\n {/* Character grid */}\n <div className=\"grid gap-0 border border-gray-300 rounded bg-white overflow-hidden\"\n style={{ gridTemplateColumns: \"repeat(16, 1fr)\" }}\n >\n {category.chars.map((ch, idx) => (\n <button\n key={`${ch}-${idx}`}\n onClick={() => handleCharClick(ch)}\n onDoubleClick={() => handleCharDoubleClick(ch)}\n className={`aspect-square flex items-center justify-center text-sm border border-gray-100 hover:bg-blue-50 transition-colors ${\n selected === ch\n ? \"bg-blue-100 ring-2 ring-blue-400 ring-inset font-bold\"\n : \"bg-white\"\n }`}\n title={`${ch} (${charCodeInfo(ch)})`}\n >\n {ch}\n </button>\n ))}\n </div>\n\n {/* Info bar */}\n <div className=\"flex items-center justify-between mt-3\">\n <div className=\"flex items-center gap-3\">\n {selected && (\n <>\n <span className=\"text-2xl\">{selected}</span>\n <span className=\"text-xs text-gray-500\">{selectedInfo}</span>\n </>\n )}\n {!selected && (\n <span className=\"text-xs text-gray-400\">문자를 선택하세요. 더블 클릭으로 바로 입력합니다.</span>\n )}\n </div>\n <button\n onClick={handleInsert}\n disabled={!selected}\n className={`px-4 py-1.5 text-xs rounded border ${\n selected\n ? \"bg-blue-500 text-white border-blue-600 hover:bg-blue-600\"\n : \"bg-gray-100 text-gray-400 border-gray-200 cursor-default\"\n }`}\n >\n 넣기\n </button>\n </div>\n\n {/* Recent characters */}\n {recentChars.length > 0 && (\n <div className=\"mt-3\">\n <div className=\"text-xs font-bold text-gray-700 mb-1\">최근 사용</div>\n <div className=\"flex flex-wrap gap-0.5\">\n {recentChars.map((ch, idx) => (\n <button\n key={`recent-${idx}`}\n onClick={() => handleCharClick(ch)}\n onDoubleClick={() => handleCharDoubleClick(ch)}\n className=\"w-7 h-7 flex items-center justify-center text-sm border border-gray-200 rounded hover:bg-blue-50 bg-white\"\n title={`${ch} (${charCodeInfo(ch)})`}\n >\n {ch}\n </button>\n ))}\n </div>\n </div>\n )}\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { X, Plus, Trash2, FileText } from \"lucide-react\";\n\nexport function TemplateDialog() {\n const isOpen = useEditorStore((s) => s.uiState.templateDialogOpen);\n const closeDialog = useEditorStore((s) => s.closeTemplateDialog);\n const templates = useEditorStore((s) => s.templates);\n const addTemplate = useEditorStore((s) => s.addTemplate);\n const removeTemplate = useEditorStore((s) => s.removeTemplate);\n const loadTemplates = useEditorStore((s) => s.loadTemplates);\n\n const [newName, setNewName] = useState(\"\");\n const [newPath, setNewPath] = useState(\"\");\n const [newDesc, setNewDesc] = useState(\"\");\n const [showAddForm, setShowAddForm] = useState(false);\n\n useEffect(() => {\n loadTemplates();\n }, [loadTemplates]);\n\n const handleAdd = useCallback(() => {\n if (newName.trim() && newPath.trim()) {\n addTemplate(newName.trim(), newPath.trim(), newDesc.trim() || undefined);\n setNewName(\"\");\n setNewPath(\"\");\n setNewDesc(\"\");\n setShowAddForm(false);\n }\n }, [newName, newPath, newDesc, addTemplate]);\n\n const handleFileSelect = useCallback(async () => {\n // Use file input for path selection\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \".hwp,.hwpx\";\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) {\n // For web, we store the file name. In Electron, this would be the full path.\n setNewPath(file.name);\n if (!newName) {\n setNewName(file.name.replace(/\\.(hwpx?|hwp)$/i, \"\"));\n }\n }\n };\n input.click();\n }, [newName]);\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\n <div className=\"bg-white rounded-lg shadow-xl w-[500px] max-h-[80vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b\">\n <h2 className=\"text-sm font-semibold\">문서 템플릿</h2>\n <button\n onClick={closeDialog}\n className=\"p-1 hover:bg-gray-100 rounded\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto p-4\">\n {/* Template List */}\n <div className=\"space-y-2 mb-4\">\n {templates.length === 0 ? (\n <div className=\"text-center py-8 text-gray-500 text-sm\">\n 저장된 템플릿이 없습니다.\n <br />\n 자주 사용하는 문서를 템플릿으로 추가하세요.\n </div>\n ) : (\n templates.map((tpl) => (\n <div\n key={tpl.id}\n className=\"flex items-center gap-3 p-3 border rounded hover:bg-gray-50 group\"\n >\n <FileText className=\"w-5 h-5 text-blue-500 flex-shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-sm truncate\">{tpl.name}</div>\n <div className=\"text-xs text-gray-500 truncate\">{tpl.path}</div>\n {tpl.description && (\n <div className=\"text-xs text-gray-400 truncate\">{tpl.description}</div>\n )}\n </div>\n <button\n onClick={() => removeTemplate(tpl.id)}\n className=\"p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded opacity-0 group-hover:opacity-100 transition-opacity\"\n title=\"삭제\"\n >\n <Trash2 className=\"w-4 h-4\" />\n </button>\n </div>\n ))\n )}\n </div>\n\n {/* Add Form */}\n {showAddForm ? (\n <div className=\"border rounded p-3 space-y-2 bg-gray-50\">\n <div className=\"text-xs font-medium text-gray-600 mb-2\">새 템플릿 추가</div>\n <div>\n <label className=\"text-xs text-gray-500\">이름</label>\n <input\n type=\"text\"\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n placeholder=\"예: 외주용역계약서\"\n className=\"w-full px-2 py-1.5 text-sm border rounded mt-0.5\"\n />\n </div>\n <div>\n <label className=\"text-xs text-gray-500\">파일 경로</label>\n <div className=\"flex gap-2 mt-0.5\">\n <input\n type=\"text\"\n value={newPath}\n onChange={(e) => setNewPath(e.target.value)}\n placeholder=\"/path/to/template.hwp\"\n className=\"flex-1 px-2 py-1.5 text-sm border rounded\"\n />\n <button\n onClick={handleFileSelect}\n className=\"px-3 py-1.5 text-sm bg-gray-100 hover:bg-gray-200 rounded\"\n >\n 찾기\n </button>\n </div>\n </div>\n <div>\n <label className=\"text-xs text-gray-500\">설명 (선택)</label>\n <input\n type=\"text\"\n value={newDesc}\n onChange={(e) => setNewDesc(e.target.value)}\n placeholder=\"간단한 설명\"\n className=\"w-full px-2 py-1.5 text-sm border rounded mt-0.5\"\n />\n </div>\n <div className=\"flex justify-end gap-2 pt-2\">\n <button\n onClick={() => setShowAddForm(false)}\n className=\"px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 rounded\"\n >\n 취소\n </button>\n <button\n onClick={handleAdd}\n disabled={!newName.trim() || !newPath.trim()}\n className=\"px-3 py-1.5 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50\"\n >\n 추가\n </button>\n </div>\n </div>\n ) : (\n <button\n onClick={() => setShowAddForm(true)}\n className=\"flex items-center justify-center gap-2 w-full py-2 text-sm text-blue-600 hover:bg-blue-50 border border-dashed border-blue-300 rounded\"\n >\n <Plus className=\"w-4 h-4\" />\n 템플릿 추가\n </button>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-4 py-3 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={closeDialog}\n className=\"px-4 py-1.5 text-sm bg-gray-200 hover:bg-gray-300 rounded\"\n >\n 닫기\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\nimport { DialogTabs } from \"./DialogTabs\";\n\nexport function HeaderFooterDialog() {\n const doc = useEditorStore((s) => s.doc);\n const viewModel = useEditorStore((s) => s.viewModel);\n const selection = useEditorStore((s) => s.selection);\n const uiState = useEditorStore((s) => s.uiState);\n const closeHeaderFooterDialog = useEditorStore((s) => s.closeHeaderFooterDialog);\n const setHeaderFooter = useEditorStore((s) => s.setHeaderFooter);\n\n const sectionIdx = selection?.sectionIndex ?? 0;\n const section = viewModel?.sections[sectionIdx];\n\n const [activeTab, setActiveTab] = useState<\"header\" | \"footer\">(\"header\");\n const [headerText, setHeaderText] = useState(section?.headerText ?? \"\");\n const [footerText, setFooterText] = useState(section?.footerText ?? \"\");\n const [headerPosition, setHeaderPosition] = useState<\"left\" | \"center\" | \"right\">(\"center\");\n const [footerPosition, setFooterPosition] = useState<\"left\" | \"center\" | \"right\">(\"center\");\n\n useEffect(() => {\n if (uiState.headerFooterDialogOpen && section) {\n setHeaderText(section.headerText);\n setFooterText(section.footerText);\n }\n }, [uiState.headerFooterDialogOpen, section?.headerText, section?.footerText]);\n\n const handleApply = () => {\n setHeaderFooter({ headerText, footerText });\n closeHeaderFooterDialog();\n };\n\n const insertPlaceholder = (placeholder: string) => {\n if (activeTab === \"header\") {\n setHeaderText((prev) => prev + placeholder);\n } else {\n setFooterText((prev) => prev + placeholder);\n }\n };\n\n const inputClass =\n \"w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:border-blue-400\";\n const btnClass =\n \"px-2 py-1 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-gray-700\";\n\n return (\n <Dialog\n title=\"머리말/꼬리말\"\n open={uiState.headerFooterDialogOpen}\n onClose={closeHeaderFooterDialog}\n onApply={handleApply}\n width={480}\n >\n <DialogTabs\n tabs={[\n { id: \"header\", label: \"머리말\" },\n { id: \"footer\", label: \"꼬리말\" },\n ]}\n activeTab={activeTab}\n onTabChange={(id) => setActiveTab(id as \"header\" | \"footer\")}\n />\n\n {activeTab === \"header\" && (\n <DialogSection title=\"머리말 내용\">\n <textarea\n value={headerText}\n onChange={(e) => setHeaderText(e.target.value)}\n placeholder=\"머리말 내용을 입력하세요\"\n className={`${inputClass} h-20 resize-none`}\n />\n <div className=\"flex gap-2 mt-2\">\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{page}}\")}>\n 쪽 번호\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{total}}\")}>\n 총 쪽 수\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{date}}\")}>\n 날짜\n </button>\n </div>\n <div className=\"flex items-center gap-4 mt-3\">\n <span className=\"text-xs text-gray-600\">정렬:</span>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"headerPos\"\n checked={headerPosition === \"left\"}\n onChange={() => setHeaderPosition(\"left\")}\n />\n 왼쪽\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"headerPos\"\n checked={headerPosition === \"center\"}\n onChange={() => setHeaderPosition(\"center\")}\n />\n 가운데\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"headerPos\"\n checked={headerPosition === \"right\"}\n onChange={() => setHeaderPosition(\"right\")}\n />\n 오른쪽\n </label>\n </div>\n </DialogSection>\n )}\n\n {activeTab === \"footer\" && (\n <DialogSection title=\"꼬리말 내용\">\n <textarea\n value={footerText}\n onChange={(e) => setFooterText(e.target.value)}\n placeholder=\"꼬리말 내용을 입력하세요\"\n className={`${inputClass} h-20 resize-none`}\n />\n <div className=\"flex gap-2 mt-2\">\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{page}}\")}>\n 쪽 번호\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{total}}\")}>\n 총 쪽 수\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{date}}\")}>\n 날짜\n </button>\n </div>\n <div className=\"flex items-center gap-4 mt-3\">\n <span className=\"text-xs text-gray-600\">정렬:</span>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"footerPos\"\n checked={footerPosition === \"left\"}\n onChange={() => setFooterPosition(\"left\")}\n />\n 왼쪽\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"footerPos\"\n checked={footerPosition === \"center\"}\n onChange={() => setFooterPosition(\"center\")}\n />\n 가운데\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"footerPos\"\n checked={footerPosition === \"right\"}\n onChange={() => setFooterPosition(\"right\")}\n />\n 오른쪽\n </label>\n </div>\n </DialogSection>\n )}\n\n <div className=\"text-xs text-gray-500 mt-3\">\n <p>사용 가능한 변수:</p>\n <ul className=\"list-disc pl-4 mt-1 space-y-0.5\">\n <li><code className=\"bg-gray-100 px-1 rounded\">{\"{{page}}\"}</code> - 현재 쪽 번호</li>\n <li><code className=\"bg-gray-100 px-1 rounded\">{\"{{total}}\"}</code> - 총 쪽 수</li>\n <li><code className=\"bg-gray-100 px-1 rounded\">{\"{{date}}\"}</code> - 오늘 날짜</li>\n </ul>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\n\nexport function FindReplaceDialog() {\n const doc = useEditorStore((s) => s.doc);\n const uiState = useEditorStore((s) => s.uiState);\n const closeFindReplaceDialog = useEditorStore((s) => s.closeFindReplaceDialog);\n const findAndReplace = useEditorStore((s) => s.findAndReplace);\n\n const [activeTab, setActiveTab] = useState<\"find\" | \"replace\">(\"find\");\n const [findText, setFindText] = useState(\"\");\n const [replaceText, setReplaceText] = useState(\"\");\n const [matchCase, setMatchCase] = useState(false);\n const [wholeWord, setWholeWord] = useState(false);\n const [resultMessage, setResultMessage] = useState<string | null>(null);\n\n // Reset result message when find text changes\n useEffect(() => {\n setResultMessage(null);\n }, [findText]);\n\n const handleFind = useCallback(() => {\n if (!doc || !findText) return;\n // Simple find by checking if text exists\n const text = doc.text;\n const searchText = matchCase ? findText : findText.toLowerCase();\n const docText = matchCase ? text : text.toLowerCase();\n\n if (docText.includes(searchText)) {\n const count = (docText.match(new RegExp(escapeRegex(searchText), \"g\")) || []).length;\n setResultMessage(`\"${findText}\"을(를) ${count}개 찾았습니다.`);\n } else {\n setResultMessage(`\"${findText}\"을(를) 찾을 수 없습니다.`);\n }\n }, [doc, findText, matchCase]);\n\n const handleReplace = useCallback(() => {\n if (!doc || !findText) return;\n const count = findAndReplace(findText, replaceText, 1);\n setResultMessage(count > 0 ? `1개를 바꿨습니다.` : `\"${findText}\"을(를) 찾을 수 없습니다.`);\n }, [doc, findText, replaceText, findAndReplace]);\n\n const handleReplaceAll = useCallback(() => {\n if (!doc || !findText) return;\n const count = findAndReplace(findText, replaceText);\n setResultMessage(count > 0 ? `${count}개를 모두 바꿨습니다.` : `\"${findText}\"을(를) 찾을 수 없습니다.`);\n }, [doc, findText, replaceText, findAndReplace]);\n\n const inputClass =\n \"w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:border-blue-400\";\n const btnClass =\n \"px-3 py-1.5 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-gray-700 disabled:opacity-40 disabled:cursor-not-allowed\";\n const primaryBtnClass =\n \"px-3 py-1.5 text-xs border border-blue-500 rounded bg-blue-500 hover:bg-blue-600 text-white disabled:opacity-40 disabled:cursor-not-allowed\";\n\n return (\n <Dialog\n title=\"찾기/바꾸기\"\n open={uiState.findReplaceDialogOpen}\n onClose={closeFindReplaceDialog}\n width={420}\n >\n <DialogTabs\n tabs={[\n { id: \"find\", label: \"찾기\" },\n { id: \"replace\", label: \"바꾸기\" },\n ]}\n activeTab={activeTab}\n onTabChange={(id) => setActiveTab(id as \"find\" | \"replace\")}\n />\n\n <div className=\"space-y-3 mt-3\">\n <div>\n <label className=\"block text-xs text-gray-600 mb-1\">찾을 내용</label>\n <input\n type=\"text\"\n value={findText}\n onChange={(e) => setFindText(e.target.value)}\n placeholder=\"찾을 텍스트를 입력하세요\"\n className={inputClass}\n autoFocus\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (activeTab === \"find\") handleFind();\n else handleReplace();\n }\n }}\n />\n </div>\n\n {activeTab === \"replace\" && (\n <div>\n <label className=\"block text-xs text-gray-600 mb-1\">바꿀 내용</label>\n <input\n type=\"text\"\n value={replaceText}\n onChange={(e) => setReplaceText(e.target.value)}\n placeholder=\"바꿀 텍스트를 입력하세요\"\n className={inputClass}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleReplace();\n }\n }}\n />\n </div>\n )}\n\n <div className=\"flex gap-4\">\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input\n type=\"checkbox\"\n checked={matchCase}\n onChange={(e) => setMatchCase(e.target.checked)}\n className=\"w-3.5 h-3.5\"\n />\n 대/소문자 구분\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input\n type=\"checkbox\"\n checked={wholeWord}\n onChange={(e) => setWholeWord(e.target.checked)}\n className=\"w-3.5 h-3.5\"\n disabled\n />\n 온전한 낱말\n </label>\n </div>\n\n {resultMessage && (\n <div className={`text-xs px-2 py-1.5 rounded ${\n resultMessage.includes(\"찾을 수 없\")\n ? \"bg-yellow-50 text-yellow-700 border border-yellow-200\"\n : \"bg-green-50 text-green-700 border border-green-200\"\n }`}>\n {resultMessage}\n </div>\n )}\n\n <div className=\"flex gap-2 pt-2\">\n {activeTab === \"find\" ? (\n <>\n <button\n className={primaryBtnClass}\n disabled={!findText}\n onClick={handleFind}\n >\n 찾기\n </button>\n <button className={btnClass} disabled>\n 다음 찾기\n </button>\n </>\n ) : (\n <>\n <button\n className={primaryBtnClass}\n disabled={!findText}\n onClick={handleReplace}\n >\n 바꾸기\n </button>\n <button\n className={btnClass}\n disabled={!findText}\n onClick={handleReplaceAll}\n >\n 모두 바꾸기\n </button>\n </>\n )}\n <button className={btnClass} onClick={closeFindReplaceDialog}>\n 닫기\n </button>\n </div>\n </div>\n </Dialog>\n );\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\n\ninterface WordCountStats {\n characters: number;\n charactersNoSpaces: number;\n words: number;\n paragraphs: number;\n lines: number;\n pages: number;\n}\n\nfunction countStats(text: string, pageCount: number): WordCountStats {\n const lines = text.split(\"\\n\");\n const paragraphs = lines.filter((line) => line.trim().length > 0);\n const characters = text.length;\n const charactersNoSpaces = text.replace(/\\s/g, \"\").length;\n\n // Count words (Korean: treat each character as a word, English: split by spaces)\n let words = 0;\n const segments = text.split(/\\s+/).filter((s) => s.length > 0);\n for (const segment of segments) {\n // Count Korean characters individually\n const koreanChars = (segment.match(/[\\uAC00-\\uD7AF]/g) || []).length;\n // Count English words (sequences of non-Korean characters)\n const nonKorean = segment.replace(/[\\uAC00-\\uD7AF]/g, \" \").split(/\\s+/).filter((s) => s.length > 0);\n words += koreanChars + nonKorean.length;\n }\n\n return {\n characters,\n charactersNoSpaces,\n words,\n paragraphs: paragraphs.length,\n lines: lines.length,\n pages: pageCount,\n };\n}\n\nexport function WordCountDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closeWordCountDialog = useEditorStore((s) => s.closeWordCountDialog);\n const doc = useEditorStore((s) => s.doc);\n const viewModel = useEditorStore((s) => s.viewModel);\n\n const [stats, setStats] = useState<WordCountStats | null>(null);\n\n useEffect(() => {\n if (uiState.wordCountDialogOpen && doc && viewModel) {\n const text = doc.text;\n const sectionCount = viewModel.sections.length;\n setStats(countStats(text, sectionCount));\n }\n }, [uiState.wordCountDialogOpen, doc, viewModel]);\n\n const statItems = stats\n ? [\n { label: \"글자 수 (공백 제외)\", value: stats.charactersNoSpaces.toLocaleString(), highlight: true },\n { label: \"글자 수 (공백 포함)\", value: stats.characters.toLocaleString() },\n { label: \"낱말 수\", value: stats.words.toLocaleString() },\n { label: \"문단 수\", value: stats.paragraphs.toLocaleString() },\n { label: \"줄 수\", value: stats.lines.toLocaleString() },\n { label: \"쪽 수\", value: stats.pages.toLocaleString() },\n ]\n : [];\n\n return (\n <Dialog\n title=\"글자 수 세기\"\n open={uiState.wordCountDialogOpen}\n onClose={closeWordCountDialog}\n width={320}\n >\n <div className=\"space-y-1.5\">\n {statItems.map((item, idx) => (\n <div\n key={item.label}\n className={`flex justify-between items-center py-1.5 px-2 rounded ${\n idx === 0 ? \"bg-blue-50 border border-blue-200\" : \"bg-gray-50\"\n }`}\n >\n <span className={`text-xs ${idx === 0 ? \"text-blue-700 font-medium\" : \"text-gray-600\"}`}>\n {item.label}\n </span>\n <span className={`text-sm font-medium ${idx === 0 ? \"text-blue-800\" : \"text-gray-800\"}`}>\n {item.value}\n </span>\n </div>\n ))}\n </div>\n\n <div className=\"flex justify-end mt-4\">\n <button\n onClick={closeWordCountDialog}\n className=\"px-4 py-1.5 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-gray-700\"\n >\n 닫기\n </button>\n </div>\n </Dialog>\n );\n}\n"],"mappings":"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","names":["import_react","import_hwpxcore","section","para","import_hwpxcore","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_react","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","PX_TO_MM","import_react","import_jsx_runtime","PX_TO_MM","getMediaType","getImageDimensions","roundMm","_a","widthMm","heightMm","import_react","import_jsx_runtime","roundMm","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","_a","_b","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_lucide_react","import_hwpxcore","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","TABS","BasicTab","ExtendedTab","import_react","import_jsx_runtime","TABS","import_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/editor/Editor.tsx","../src/lib/store.ts","../src/lib/view-model.ts","../src/lib/hwp-units.ts","../src/lib/image-extractor.ts","../src/lib/format-bridge.ts","../src/lib/skeleton-loader.ts","../src/components/toolbar/MenuBar.tsx","../src/components/toolbar/ClipboardGroup.tsx","../src/components/toolbar/ToolbarButton.tsx","../src/components/toolbar/RibbonGroup.tsx","../src/components/toolbar/InsertGroup.tsx","../src/components/toolbar/RibbonToolbar.tsx","../src/lib/constants.ts","../src/components/toolbar/ToolbarDropdown.tsx","../src/components/toolbar/StyleSelector.tsx","../src/components/toolbar/FontSelector.tsx","../src/components/toolbar/FontSizeInput.tsx","../src/components/toolbar/CharFormatButtons.tsx","../src/components/toolbar/ColorPicker.tsx","../src/components/toolbar/AlignmentButtons.tsx","../src/components/toolbar/LineSpacingControl.tsx","../src/components/toolbar/ToolbarDivider.tsx","../src/components/toolbar/SecondaryToolbar.tsx","../src/components/ruler/HorizontalRuler.tsx","../src/components/sidebar/FormatSidebar.tsx","../src/components/sidebar/SidebarSection.tsx","../src/components/sidebar/SidebarField.tsx","../src/components/sidebar/BorderSettings.tsx","../src/components/sidebar/BackgroundSettings.tsx","../src/components/sidebar/CharFormatPanel.tsx","../src/components/sidebar/ParaFormatPanel.tsx","../src/components/sidebar/PageSetupPanel.tsx","../src/components/sidebar/ImageLayoutPanel.tsx","../src/components/sidebar/ImagePropertiesPanel.tsx","../src/components/sidebar/TablePropertiesPanel.tsx","../src/components/sidebar/CellPropertiesPanel.tsx","../src/components/editor/ParagraphBlock.tsx","../src/components/editor/RunSpan.tsx","../src/components/editor/TableBlock.tsx","../src/components/editor/TableCell.tsx","../src/components/editor/ImageBlock.tsx","../src/components/editor/TextBoxBlock.tsx","../src/components/editor/EquationBlock.tsx","../src/components/editor/Page.tsx","../src/components/editor/PageView.tsx","../src/components/editor/SaveDialog.tsx","../src/components/upload/FileUpload.tsx","../src/components/upload/NewDocumentButton.tsx","../src/components/dialog/CharFormatDialog.tsx","../src/components/dialog/Dialog.tsx","../src/components/dialog/DialogTabs.tsx","../src/components/dialog/DialogSection.tsx","../src/components/dialog/ParaFormatDialog.tsx","../src/components/dialog/BulletNumberDialog.tsx","../src/components/dialog/CharMapDialog.tsx","../src/components/dialog/TemplateDialog.tsx","../src/components/dialog/HeaderFooterDialog.tsx","../src/components/dialog/FindReplaceDialog.tsx","../src/components/dialog/WordCountDialog.tsx","../src/components/dialog/PageNumberDialog.tsx","../src/components/dialog/StyleDialog.tsx","../src/components/dialog/AutoCorrectDialog.tsx","../src/lib/autocorrect.ts","../src/components/dialog/OutlineDialog.tsx","../src/components/dialog/ShapeDialog.tsx","../src/components/dialog/TocDialog.tsx"],"sourcesContent":["/**\n * @hwpx/editor — React editor components for HWPX documents.\n *\n * Provides a Korean word processor-style UI with ribbon toolbar,\n * format sidebar, ruler, and full page editing.\n */\n\n// ── Editor components ─────────────────────────────────────────────────────\nexport { Editor } from \"./components/editor/Editor\";\nexport { PageView } from \"./components/editor/PageView\";\nexport { Page } from \"./components/editor/Page\";\nexport { ParagraphBlock } from \"./components/editor/ParagraphBlock\";\nexport { RunSpan } from \"./components/editor/RunSpan\";\nexport { ImageBlock } from \"./components/editor/ImageBlock\";\nexport { TableBlock } from \"./components/editor/TableBlock\";\nexport { TableCell } from \"./components/editor/TableCell\";\n\n// ── Toolbar components ────────────────────────────────────────────────────\nexport { RibbonToolbar } from \"./components/toolbar/RibbonToolbar\";\nexport { SecondaryToolbar } from \"./components/toolbar/SecondaryToolbar\";\nexport { ToolbarButton } from \"./components/toolbar/ToolbarButton\";\nexport { ToolbarDropdown } from \"./components/toolbar/ToolbarDropdown\";\nexport { ToolbarDivider } from \"./components/toolbar/ToolbarDivider\";\nexport { ColorPicker } from \"./components/toolbar/ColorPicker\";\nexport { RibbonGroup } from \"./components/toolbar/RibbonGroup\";\nexport { ClipboardGroup } from \"./components/toolbar/ClipboardGroup\";\nexport { InsertGroup } from \"./components/toolbar/InsertGroup\";\nexport { StyleSelector } from \"./components/toolbar/StyleSelector\";\nexport { FontSelector } from \"./components/toolbar/FontSelector\";\nexport { FontSizeInput } from \"./components/toolbar/FontSizeInput\";\nexport { CharFormatButtons } from \"./components/toolbar/CharFormatButtons\";\nexport { AlignmentButtons } from \"./components/toolbar/AlignmentButtons\";\nexport { LineSpacingControl } from \"./components/toolbar/LineSpacingControl\";\n\n// ── Sidebar components ────────────────────────────────────────────────────\nexport { FormatSidebar } from \"./components/sidebar/FormatSidebar\";\nexport { SidebarSection } from \"./components/sidebar/SidebarSection\";\nexport { SidebarField } from \"./components/sidebar/SidebarField\";\nexport { CharFormatPanel } from \"./components/sidebar/CharFormatPanel\";\nexport { ParaFormatPanel } from \"./components/sidebar/ParaFormatPanel\";\nexport { BorderSettings } from \"./components/sidebar/BorderSettings\";\nexport { BackgroundSettings } from \"./components/sidebar/BackgroundSettings\";\n\n// ── Ruler ─────────────────────────────────────────────────────────────────\nexport { HorizontalRuler } from \"./components/ruler/HorizontalRuler\";\n\n// ── Upload components ─────────────────────────────────────────────────────\nexport { FileUpload } from \"./components/upload/FileUpload\";\nexport { NewDocumentButton } from \"./components/upload/NewDocumentButton\";\n\n// ── Store ─────────────────────────────────────────────────────────────────\nexport { useEditorStore } from \"./lib/store\";\nexport type {\n SelectionState,\n ActiveFormat,\n ExtendedFormat,\n UIState,\n EditorStore,\n} from \"./lib/store\";\n\n// ── Constants ─────────────────────────────────────────────────────────────\nexport {\n FONT_FAMILIES,\n FONT_SIZES,\n STYLE_PRESETS,\n ALIGNMENT_OPTIONS,\n LINE_SPACING_OPTIONS,\n UNDERLINE_TYPES,\n COLOR_PRESETS,\n HIGHLIGHT_COLORS,\n} from \"./lib/constants\";\nexport type {\n FontFamily,\n StylePreset,\n AlignmentType,\n AlignmentOption,\n LineSpacingOption,\n SidebarTab,\n} from \"./lib/constants\";\n\n// ── Format bridge ─────────────────────────────────────────────────────────\nexport {\n readCharFormat,\n readParaFormat,\n readStyleInfo,\n getDocumentStyles,\n readFormatFromSelection,\n} from \"./lib/format-bridge\";\nexport type { CharFormat, ParaFormat } from \"./lib/format-bridge\";\n\n// ── View model ────────────────────────────────────────────────────────────\nexport { buildViewModel } from \"./lib/view-model\";\nexport type {\n RunVM,\n TableCellVM,\n TableVM,\n ImageVM,\n ParagraphVM,\n SectionVM,\n EditorViewModel,\n} from \"./lib/view-model\";\n\n// ── Utilities ─────────────────────────────────────────────────────────────\nexport { hwpToPx, pxToHwp, hwpToMm, mmToHwp } from \"./lib/hwp-units\";\nexport { extractImages } from \"./lib/image-extractor\";\nexport { ensureSkeletonLoaded, createNewDocument } from \"./lib/skeleton-loader\";\n","\"use client\";\n\nimport { useEffect, useRef, useCallback } from \"react\";\nimport { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ensureSkeletonLoaded } from \"@/lib/skeleton-loader\";\nimport { MenuBar } from \"../toolbar/MenuBar\";\nimport { RibbonToolbar } from \"../toolbar/RibbonToolbar\";\nimport { SecondaryToolbar } from \"../toolbar/SecondaryToolbar\";\nimport { HorizontalRuler } from \"../ruler/HorizontalRuler\";\nimport { FormatSidebar } from \"../sidebar/FormatSidebar\";\nimport { PageView } from \"./PageView\";\nimport { SaveDialog } from \"./SaveDialog\";\nimport { FileUpload } from \"../upload/FileUpload\";\nimport { NewDocumentButton } from \"../upload/NewDocumentButton\";\nimport { CharFormatDialog } from \"../dialog/CharFormatDialog\";\nimport { ParaFormatDialog } from \"../dialog/ParaFormatDialog\";\nimport { BulletNumberDialog } from \"../dialog/BulletNumberDialog\";\nimport { CharMapDialog } from \"../dialog/CharMapDialog\";\nimport { TemplateDialog } from \"../dialog/TemplateDialog\";\nimport { HeaderFooterDialog } from \"../dialog/HeaderFooterDialog\";\nimport { FindReplaceDialog } from \"../dialog/FindReplaceDialog\";\nimport { WordCountDialog } from \"../dialog/WordCountDialog\";\nimport { PageNumberDialog } from \"../dialog/PageNumberDialog\";\nimport { StyleDialog } from \"../dialog/StyleDialog\";\nimport { AutoCorrectDialog } from \"../dialog/AutoCorrectDialog\";\nimport { OutlineDialog } from \"../dialog/OutlineDialog\";\nimport { ShapeDialog } from \"../dialog/ShapeDialog\";\nimport { TocDialog } from \"../dialog/TocDialog\";\nimport { PanelRight } from \"lucide-react\";\n\nexport function Editor() {\n const doc = useEditorStore((s) => s.doc);\n const loading = useEditorStore((s) => s.loading);\n const error = useEditorStore((s) => s.error);\n const uiState = useEditorStore((s) => s.uiState);\n const toggleSidebar = useEditorStore((s) => s.toggleSidebar);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // Pre-load skeleton on mount\n useEffect(() => {\n ensureSkeletonLoaded().catch(console.error);\n }, []);\n\n // Handle file open from hidden input\n const handleFileChange = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const store = useEditorStore.getState();\n store.setLoading(true);\n store.setError(null);\n try {\n const buffer = await file.arrayBuffer();\n const newDoc = await HwpxDocument.open(buffer);\n store.setDocument(newDoc);\n } catch (err) {\n console.error(\"Failed to open file:\", err);\n store.setError(\"파일을 열 수 없습니다. HWPX 파일인지 확인하세요.\");\n } finally {\n store.setLoading(false);\n }\n e.target.value = \"\";\n }, []);\n\n // Listen for hwpx-open-file custom event\n useEffect(() => {\n const handler = () => fileInputRef.current?.click();\n window.addEventListener(\"hwpx-open-file\", handler);\n return () => window.removeEventListener(\"hwpx-open-file\", handler);\n }, []);\n\n // Global keyboard shortcuts\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n const store = useEditorStore.getState();\n if (!store.doc) return;\n\n const mod = e.ctrlKey || e.metaKey;\n\n if (mod && e.key === \"o\") {\n e.preventDefault();\n store.openFile();\n return;\n }\n\n if (mod && e.key === \"s\") {\n e.preventDefault();\n store.openSaveDialog();\n return;\n }\n\n // Undo / Redo (works without selection)\n if (mod && e.key === \"z\" && !e.shiftKey) {\n e.preventDefault();\n store.undo();\n return;\n }\n if (mod && (e.key === \"y\" || (e.key === \"z\" && e.shiftKey))) {\n e.preventDefault();\n store.redo();\n return;\n }\n\n // Dialog shortcuts (⌘L = char format, ⌘T = para format, Ctrl+F10 = char map)\n if (mod && e.key === \"l\") {\n e.preventDefault();\n store.openCharFormatDialog();\n return;\n }\n if (mod && e.key === \"t\") {\n e.preventDefault();\n store.openParaFormatDialog();\n return;\n }\n if (e.key === \"F10\" && (e.ctrlKey || e.metaKey)) {\n e.preventDefault();\n store.openCharMapDialog();\n return;\n }\n if (mod && (e.key === \"f\" || e.key === \"h\")) {\n e.preventDefault();\n store.openFindReplaceDialog();\n return;\n }\n\n if (!store.selection) return;\n\n if (mod && e.key === \"b\") {\n e.preventDefault();\n store.toggleBold();\n } else if (mod && e.key === \"i\") {\n e.preventDefault();\n store.toggleItalic();\n } else if (mod && e.key === \"u\") {\n e.preventDefault();\n store.toggleUnderline();\n } else if (mod && e.key === \"d\") {\n e.preventDefault();\n store.toggleStrikethrough();\n } else if (mod && e.key === \"e\") {\n e.preventDefault();\n store.setAlignment(\"CENTER\");\n } else if (mod && e.key === \"r\") {\n e.preventDefault();\n store.setAlignment(\"RIGHT\");\n } else if (mod && e.key === \"j\") {\n e.preventDefault();\n store.setAlignment(\"JUSTIFY\");\n }\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-screen items-center justify-center\">\n <div className=\"text-gray-500\">로딩 중...</div>\n </div>\n );\n }\n\n if (!doc) {\n return (\n <div className=\"flex h-screen flex-col items-center justify-center gap-6 bg-gray-100 p-8\">\n <h1 className=\"text-2xl font-bold text-gray-800\">HWPX Editor</h1>\n <p className=\"text-gray-500 max-w-md text-center\">\n HWPX 문서를 열거나 새 문서를 만들어 편집하세요.\n </p>\n <div className=\"w-full max-w-md\">\n <FileUpload />\n </div>\n <div className=\"flex gap-3\">\n <NewDocumentButton />\n </div>\n {error && (\n <div className=\"bg-red-50 text-red-600 px-4 py-2 rounded-lg text-sm\">\n {error}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"flex h-screen flex-col\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".hwpx\"\n className=\"hidden\"\n onChange={handleFileChange}\n />\n <SaveDialog />\n <CharFormatDialog />\n <ParaFormatDialog />\n <BulletNumberDialog />\n <CharMapDialog />\n <TemplateDialog />\n <HeaderFooterDialog />\n <FindReplaceDialog />\n <WordCountDialog />\n <PageNumberDialog />\n <StyleDialog />\n <AutoCorrectDialog />\n <OutlineDialog />\n <ShapeDialog />\n <TocDialog />\n {/* Menu bar */}\n <MenuBar />\n {/* Ribbon toolbar */}\n <RibbonToolbar />\n {/* Secondary toolbar (formatting bar) */}\n <SecondaryToolbar />\n {/* Horizontal ruler */}\n <HorizontalRuler />\n {/* Error banner */}\n {error && (\n <div className=\"bg-red-50 text-red-600 px-4 py-2 text-sm border-b border-red-200\">\n {error}\n </div>\n )}\n {/* Main content area: Page + Sidebar */}\n <div className=\"flex flex-1 overflow-hidden\">\n <PageView />\n <FormatSidebar />\n {/* Sidebar toggle when closed */}\n {!uiState.sidebarOpen && (\n <button\n onClick={toggleSidebar}\n className=\"absolute right-2 top-[140px] z-10 p-1.5 bg-white border border-gray-200 rounded shadow-sm text-gray-400 hover:text-gray-600 hover:bg-gray-50\"\n title=\"서식 사이드바 열기\"\n >\n <PanelRight className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n {/* Status bar */}\n <StatusBar />\n </div>\n );\n}\n\nfunction StatusBar() {\n const doc = useEditorStore((s) => s.doc);\n const viewModel = useEditorStore((s) => s.viewModel);\n const openWordCountDialog = useEditorStore((s) => s.openWordCountDialog);\n\n if (!doc || !viewModel) return null;\n\n const text = doc.text;\n const charCount = text.replace(/\\s/g, \"\").length;\n // Estimate page count (1 section = 1 page minimum)\n const sectionCount = viewModel.sections.length;\n\n return (\n <div className=\"h-5 flex items-center justify-end px-3 bg-gray-100 border-t border-gray-200 text-[10px] text-gray-500\">\n <button\n onClick={openWordCountDialog}\n className=\"hover:text-gray-700 hover:underline\"\n title=\"글자 수 세기 대화상자 열기\"\n >\n 글자 수 (공백 제외): {charCount.toLocaleString()} | 쪽: {sectionCount}\n </button>\n </div>\n );\n}\n","/**\n * Zustand store — manages HwpxDocument + EditorViewModel + actions.\n */\n\nimport { create } from \"zustand\";\nimport type { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { buildViewModel, type EditorViewModel } from \"./view-model\";\nimport {\n readFormatFromSelection,\n type CharFormat,\n type ParaFormat,\n} from \"./format-bridge\";\nimport type { AlignmentType, OrientationType, SidebarTab } from \"./constants\";\nimport { mmToHwp } from \"./hwp-units\";\n\nexport interface SelectionState {\n sectionIndex: number;\n paragraphIndex: number;\n type: \"paragraph\" | \"cell\" | \"table\";\n // For cell selection\n tableIndex?: number;\n row?: number;\n col?: number;\n // For cell range selection (merge)\n endRow?: number;\n endCol?: number;\n // For object selection (image/table/textBox context)\n objectType?: \"image\" | \"table\" | \"textBox\";\n imageIndex?: number;\n textBoxIndex?: number;\n // Text cursor position\n textStartOffset?: number;\n textEndOffset?: number;\n}\n\nexport interface ActiveFormat {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n}\n\nexport interface ExtendedFormat {\n char: CharFormat;\n para: ParaFormat;\n}\n\nexport interface Template {\n id: string;\n name: string;\n path: string;\n description?: string;\n createdAt: number;\n}\n\nexport interface UIState {\n sidebarOpen: boolean;\n sidebarTab: SidebarTab;\n saveDialogOpen: boolean;\n charFormatDialogOpen: boolean;\n paraFormatDialogOpen: boolean;\n bulletNumberDialogOpen: boolean;\n charMapDialogOpen: boolean;\n templateDialogOpen: boolean;\n headerFooterDialogOpen: boolean;\n findReplaceDialogOpen: boolean;\n wordCountDialogOpen: boolean;\n pageNumberDialogOpen: boolean;\n styleDialogOpen: boolean;\n autoCorrectDialogOpen: boolean;\n outlineDialogOpen: boolean;\n shapeDialogOpen: boolean;\n tocDialogOpen: boolean;\n zoomLevel: number;\n}\n\ninterface UndoEntry {\n sectionElements: Element[];\n headerElements: Element[];\n selection: SelectionState | null;\n}\n\nexport interface EditorStore {\n doc: HwpxDocument | null;\n viewModel: EditorViewModel | null;\n revision: number;\n selection: SelectionState | null;\n activeFormat: ActiveFormat;\n extendedFormat: ExtendedFormat;\n uiState: UIState;\n loading: boolean;\n error: string | null;\n undoStack: UndoEntry[];\n redoStack: UndoEntry[];\n\n // Actions\n setDocument: (doc: HwpxDocument) => void;\n rebuild: () => void;\n setSelection: (sel: SelectionState | null) => void;\n setActiveFormat: (fmt: Partial<ActiveFormat>) => void;\n refreshExtendedFormat: () => void;\n\n // UI actions\n toggleSidebar: () => void;\n setSidebarTab: (tab: SidebarTab) => void;\n\n // Text editing\n updateParagraphText: (\n sectionIndex: number,\n paragraphIndex: number,\n text: string,\n ) => void;\n updateCellText: (\n sectionIndex: number,\n paragraphIndex: number,\n tableIndex: number,\n row: number,\n col: number,\n text: string,\n ) => void;\n\n // Formatting\n toggleBold: () => void;\n toggleItalic: () => void;\n toggleUnderline: () => void;\n toggleStrikethrough: () => void;\n setFontFamily: (fontFamily: string) => void;\n setFontSize: (size: number) => void;\n setTextColor: (color: string) => void;\n setHighlightColor: (color: string) => void;\n setAlignment: (alignment: AlignmentType) => void;\n setLineSpacing: (spacing: number) => void;\n\n // Block operations\n deleteBlock: (sectionIndex: number, paragraphIndex: number) => void;\n insertBlockAt: (\n sectionIndex: number,\n paragraphIndex: number,\n text?: string,\n ) => void;\n\n // Paragraph editing\n splitParagraph: (\n sectionIndex: number,\n paragraphIndex: number,\n offset: number,\n ) => void;\n mergeParagraphWithPrevious: (\n sectionIndex: number,\n paragraphIndex: number,\n ) => void;\n\n // Undo/Redo\n pushUndo: () => void;\n undo: () => void;\n redo: () => void;\n\n // Content insertion\n addParagraph: (text?: string) => void;\n addTable: (\n sectionIndex: number,\n paragraphIndex: number,\n rows: number,\n cols: number,\n ) => void;\n insertImage: (\n data: Uint8Array,\n mediaType: string,\n widthMm: number,\n heightMm: number,\n ) => void;\n insertColumnBreak: () => void;\n insertPageBreak: () => void;\n\n // Image editing\n updatePictureSize: (widthMm: number, heightMm: number) => void;\n resizeImage: (deltaWidthHwp: number, deltaHeightHwp: number) => void;\n setImageOutMargin: (margins: Partial<{ top: number; bottom: number; left: number; right: number }>) => void;\n\n // Table editing\n setTablePageBreak: (mode: \"CELL\" | \"NONE\") => void;\n setTableRepeatHeader: (repeat: boolean) => void;\n setTableSize: (widthMm: number, heightMm: number) => void;\n setTableOutMargin: (margins: Partial<{ top: number; bottom: number; left: number; right: number }>) => void;\n setTableInMargin: (margins: Partial<{ top: number; bottom: number; left: number; right: number }>) => void;\n resizeTableColumn: (sectionIdx: number, paraIdx: number, tableIdx: number, colIdx: number, deltaHwp: number) => void;\n\n // Paragraph indent\n setFirstLineIndent: (valueHwp: number) => void;\n setLeftIndent: (valueHwp: number) => void;\n\n // Page numbering\n setPageNumbering: (opts: { position: string; startNumber: number }) => void;\n\n // Footnote / Endnote\n insertFootnote: () => void;\n insertEndnote: () => void;\n\n // Watermark\n setWatermarkText: (text: string) => void;\n\n // Dialog open/close\n openCharFormatDialog: () => void;\n closeCharFormatDialog: () => void;\n openParaFormatDialog: () => void;\n closeParaFormatDialog: () => void;\n openBulletNumberDialog: () => void;\n closeBulletNumberDialog: () => void;\n openCharMapDialog: () => void;\n closeCharMapDialog: () => void;\n openTemplateDialog: () => void;\n closeTemplateDialog: () => void;\n openHeaderFooterDialog: () => void;\n closeHeaderFooterDialog: () => void;\n openFindReplaceDialog: () => void;\n closeFindReplaceDialog: () => void;\n openWordCountDialog: () => void;\n closeWordCountDialog: () => void;\n openPageNumberDialog: () => void;\n closePageNumberDialog: () => void;\n openStyleDialog: () => void;\n closeStyleDialog: () => void;\n openAutoCorrectDialog: () => void;\n closeAutoCorrectDialog: () => void;\n openOutlineDialog: () => void;\n closeOutlineDialog: () => void;\n openShapeDialog: () => void;\n closeShapeDialog: () => void;\n openTocDialog: () => void;\n closeTocDialog: () => void;\n setZoom: (level: number) => void;\n zoomIn: () => void;\n zoomOut: () => void;\n\n // Template management\n templates: Template[];\n loadTemplates: () => void;\n saveTemplates: () => void;\n addTemplate: (name: string, path: string, description?: string) => void;\n removeTemplate: (id: string) => void;\n\n // Text insertion at cursor\n insertTextAtCursor: (text: string) => void;\n insertTab: () => void;\n\n // Page setup\n updatePageSize: (width: number, height: number) => void;\n updatePageMargins: (margins: Partial<{ left: number; right: number; top: number; bottom: number; header: number; footer: number; gutter: number }>) => void;\n updatePageOrientation: (orientation: OrientationType) => void;\n\n // Cell style operations\n setCellBorder: (sides: (\"left\"|\"right\"|\"top\"|\"bottom\")[], style: { type?: string; width?: string; color?: string }) => void;\n setCellBackground: (color: string | null) => void;\n setCellVertAlign: (align: \"TOP\" | \"CENTER\" | \"BOTTOM\") => void;\n\n // Table-wide border/background\n setTableBorder: (sides: (\"left\"|\"right\"|\"top\"|\"bottom\")[], style: { type?: string; width?: string; color?: string }) => void;\n setTableBackground: (color: string | null) => void;\n\n // Table structure operations\n insertTableRow: (position: \"above\" | \"below\") => void;\n deleteTableRow: () => void;\n insertTableColumn: (position: \"left\" | \"right\") => void;\n deleteTableColumn: () => void;\n mergeTableCells: () => void;\n splitTableCell: () => void;\n deleteTable: () => void;\n\n // File operations\n openFile: () => void;\n saveDocument: () => Promise<void>;\n saveDocumentAs: (filename: string) => Promise<void>;\n openSaveDialog: () => void;\n closeSaveDialog: () => void;\n setLoading: (loading: boolean) => void;\n setError: (error: string | null) => void;\n}\n\nconst defaultCharFormat: CharFormat = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n fontFamily: null,\n fontSize: null,\n textColor: null,\n highlightColor: null,\n letterSpacing: null,\n};\n\nconst defaultParaFormat: ParaFormat = {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n};\n\nexport const useEditorStore = create<EditorStore>((set, get) => ({\n doc: null,\n viewModel: null,\n revision: 0,\n selection: null,\n activeFormat: { bold: false, italic: false, underline: false, strikethrough: false },\n undoStack: [],\n redoStack: [],\n templates: [],\n extendedFormat: { char: defaultCharFormat, para: defaultParaFormat },\n uiState: { sidebarOpen: true, sidebarTab: \"char\", saveDialogOpen: false, charFormatDialogOpen: false, paraFormatDialogOpen: false, bulletNumberDialogOpen: false, charMapDialogOpen: false, templateDialogOpen: false, headerFooterDialogOpen: false, findReplaceDialogOpen: false, wordCountDialogOpen: false, pageNumberDialogOpen: false, styleDialogOpen: false, autoCorrectDialogOpen: false, outlineDialogOpen: false, shapeDialogOpen: false, tocDialogOpen: false, zoomLevel: 100 },\n loading: false,\n error: null,\n\n setDocument: (doc) => {\n const viewModel = buildViewModel(doc);\n set({ doc, viewModel, revision: get().revision + 1, error: null });\n },\n\n rebuild: () => {\n const { doc } = get();\n if (!doc) return;\n const viewModel = buildViewModel(doc);\n set({ viewModel, revision: get().revision + 1 });\n },\n\n setSelection: (selection) => {\n set({ selection });\n // Auto-refresh extended format when selection changes\n if (selection) {\n // Use setTimeout to avoid synchronous read during render\n setTimeout(() => get().refreshExtendedFormat(), 0);\n }\n },\n\n setActiveFormat: (fmt) =>\n set((s) => ({ activeFormat: { ...s.activeFormat, ...fmt } })),\n\n refreshExtendedFormat: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const fmt = readFormatFromSelection(\n doc,\n selection.sectionIndex,\n selection.paragraphIndex,\n );\n set({\n extendedFormat: fmt,\n activeFormat: {\n bold: fmt.char.bold,\n italic: fmt.char.italic,\n underline: fmt.char.underline,\n strikethrough: fmt.char.strikethrough,\n },\n });\n } catch (e) {\n console.error(\"refreshExtendedFormat failed:\", e);\n }\n },\n\n // UI actions\n toggleSidebar: () =>\n set((s) => ({\n uiState: { ...s.uiState, sidebarOpen: !s.uiState.sidebarOpen },\n })),\n\n setSidebarTab: (tab) =>\n set((s) => ({\n uiState: { ...s.uiState, sidebarTab: tab },\n })),\n\n setLoading: (loading) => set({ loading }),\n setError: (error) => set({ error }),\n\n updateParagraphText: (sectionIndex, paragraphIndex, text) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) return;\n const oldText = para.text;\n if (oldText === text) return;\n get().pushUndo();\n para.text = text;\n get().rebuild();\n } catch (e) {\n console.error(\"updateParagraphText failed:\", e);\n }\n },\n\n updateCellText: (sectionIndex, paragraphIndex, tableIndex, row, col, text) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) return;\n const table = para.tables[tableIndex];\n if (!table) return;\n table.setCellText(row, col, text);\n get().rebuild();\n } catch (e) {\n console.error(\"updateCellText failed:\", e);\n }\n },\n\n toggleBold: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newBold = !activeFormat.bold;\n try {\n get().pushUndo();\n const charPrIdRef = doc.ensureRunStyle({\n bold: newBold,\n italic: activeFormat.italic,\n underline: activeFormat.underline,\n strikethrough: activeFormat.strikethrough,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, bold: newBold } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleBold failed:\", e);\n }\n },\n\n toggleItalic: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newItalic = !activeFormat.italic;\n try {\n get().pushUndo();\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: newItalic,\n underline: activeFormat.underline,\n strikethrough: activeFormat.strikethrough,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, italic: newItalic } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleItalic failed:\", e);\n }\n },\n\n toggleUnderline: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newUnderline = !activeFormat.underline;\n try {\n get().pushUndo();\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: activeFormat.italic,\n underline: newUnderline,\n strikethrough: activeFormat.strikethrough,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, underline: newUnderline } });\n get().rebuild();\n } catch (e) {\n console.error(\"toggleUnderline failed:\", e);\n }\n },\n\n toggleStrikethrough: () => {\n const { doc, activeFormat, selection } = get();\n if (!doc || !selection) return;\n const newStrike = !activeFormat.strikethrough;\n try {\n get().pushUndo();\n const cf = get().extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: activeFormat.bold,\n italic: activeFormat.italic,\n underline: activeFormat.underline,\n strikethrough: newStrike,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: cf.fontSize ?? undefined,\n textColor: cf.textColor ?? undefined,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n set({ activeFormat: { ...activeFormat, strikethrough: newStrike } });\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"toggleStrikethrough failed:\", e);\n }\n },\n\n setFontFamily: (fontFamily) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily,\n fontSize: cf.fontSize ?? undefined,\n textColor: cf.textColor ?? undefined,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setFontFamily failed:\", e);\n }\n },\n\n setFontSize: (size) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: size,\n textColor: cf.textColor ?? undefined,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setFontSize failed:\", e);\n }\n },\n\n setTextColor: (color) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: cf.fontSize ?? undefined,\n textColor: color,\n highlightColor: cf.highlightColor ?? undefined,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setTextColor failed:\", e);\n }\n },\n\n setHighlightColor: (color) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n const cf = extendedFormat.char;\n const charPrIdRef = doc.ensureRunStyle({\n bold: cf.bold,\n italic: cf.italic,\n underline: cf.underline,\n fontFamily: cf.fontFamily ?? undefined,\n fontSize: cf.fontSize ?? undefined,\n textColor: cf.textColor ?? undefined,\n highlightColor: color,\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.charPrIdRef = charPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setHighlightColor failed:\", e);\n }\n },\n\n setAlignment: (alignment) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment,\n lineSpacingValue: Math.round(pf.lineSpacing * 100),\n baseParaPrId: (() => {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return undefined;\n const para = section.paragraphs[selection.paragraphIndex];\n return para?.paraPrIdRef ?? undefined;\n })(),\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setAlignment failed:\", e);\n }\n },\n\n setLineSpacing: (spacing) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment: pf.alignment,\n lineSpacingValue: Math.round(spacing * 100),\n baseParaPrId: (() => {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return undefined;\n const para = section.paragraphs[selection.paragraphIndex];\n return para?.paraPrIdRef ?? undefined;\n })(),\n });\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setLineSpacing failed:\", e);\n }\n },\n\n splitParagraph: (sectionIndex, paragraphIndex, offset) => {\n const { doc } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const para = section.paragraphs[paragraphIndex];\n if (!para) return;\n const fullText = para.text;\n const before = fullText.substring(0, offset);\n const after = fullText.substring(offset);\n\n // Update current paragraph text\n para.text = before;\n\n // Insert new paragraph after current one\n doc.insertParagraphAt(sectionIndex, paragraphIndex + 1, after, {\n paraPrIdRef: para.paraPrIdRef ?? undefined,\n charPrIdRef: para.charPrIdRef ?? undefined,\n });\n\n // Move selection to the new paragraph\n set({\n selection: {\n sectionIndex,\n paragraphIndex: paragraphIndex + 1,\n type: \"paragraph\",\n },\n });\n get().rebuild();\n } catch (e) {\n console.error(\"splitParagraph failed:\", e);\n }\n },\n\n mergeParagraphWithPrevious: (sectionIndex, paragraphIndex) => {\n const { doc } = get();\n if (!doc) return;\n if (paragraphIndex <= 0) return;\n try {\n get().pushUndo();\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const prevPara = section.paragraphs[paragraphIndex - 1];\n const currPara = section.paragraphs[paragraphIndex];\n if (!prevPara || !currPara) return;\n\n const prevText = prevPara.text;\n const currText = currPara.text;\n\n // Merge text into previous paragraph\n prevPara.text = prevText + currText;\n\n // Remove current paragraph\n doc.removeParagraph(sectionIndex, paragraphIndex);\n\n // Move selection to previous paragraph\n set({\n selection: {\n sectionIndex,\n paragraphIndex: paragraphIndex - 1,\n type: \"paragraph\",\n },\n });\n get().rebuild();\n } catch (e) {\n console.error(\"mergeParagraphWithPrevious failed:\", e);\n }\n },\n\n pushUndo: () => {\n const { doc, selection, undoStack } = get();\n if (!doc) return;\n try {\n const sections = doc.oxml.sections;\n const headers = doc.oxml.headers;\n const entry: UndoEntry = {\n sectionElements: sections.map((s) => s.element.cloneNode(true) as Element),\n headerElements: headers.map((h) => h.element.cloneNode(true) as Element),\n selection: selection ? { ...selection } : null,\n };\n // Limit stack size to 50\n const newStack = undoStack.length >= 50\n ? [...undoStack.slice(undoStack.length - 49), entry]\n : [...undoStack, entry];\n set({ undoStack: newStack, redoStack: [] });\n } catch (e) {\n console.error(\"pushUndo failed:\", e);\n }\n },\n\n undo: () => {\n const { doc, selection, undoStack, redoStack } = get();\n if (!doc || undoStack.length === 0) return;\n try {\n const sections = doc.oxml.sections;\n const headers = doc.oxml.headers;\n\n // Save current state to redo stack\n const currentEntry: UndoEntry = {\n sectionElements: sections.map((s) => s.element.cloneNode(true) as Element),\n headerElements: headers.map((h) => h.element.cloneNode(true) as Element),\n selection: selection ? { ...selection } : null,\n };\n\n // Pop from undo stack\n const entry = undoStack[undoStack.length - 1]!;\n const newUndoStack = undoStack.slice(0, -1);\n\n // Restore section elements\n sections.forEach((s, i) => {\n if (entry.sectionElements[i]) {\n s.replaceElement(entry.sectionElements[i]!);\n }\n });\n // Restore header elements\n headers.forEach((h, i) => {\n if (entry.headerElements[i]) {\n h.replaceElement(entry.headerElements[i]!);\n }\n });\n\n doc.oxml.invalidateCharPropertyCache();\n set({\n undoStack: newUndoStack,\n redoStack: [...redoStack, currentEntry],\n selection: entry.selection,\n });\n get().rebuild();\n } catch (e) {\n console.error(\"undo failed:\", e);\n }\n },\n\n redo: () => {\n const { doc, selection, undoStack, redoStack } = get();\n if (!doc || redoStack.length === 0) return;\n try {\n const sections = doc.oxml.sections;\n const headers = doc.oxml.headers;\n\n // Save current state to undo stack\n const currentEntry: UndoEntry = {\n sectionElements: sections.map((s) => s.element.cloneNode(true) as Element),\n headerElements: headers.map((h) => h.element.cloneNode(true) as Element),\n selection: selection ? { ...selection } : null,\n };\n\n // Pop from redo stack\n const entry = redoStack[redoStack.length - 1]!;\n const newRedoStack = redoStack.slice(0, -1);\n\n // Restore section elements\n sections.forEach((s, i) => {\n if (entry.sectionElements[i]) {\n s.replaceElement(entry.sectionElements[i]!);\n }\n });\n // Restore header elements\n headers.forEach((h, i) => {\n if (entry.headerElements[i]) {\n h.replaceElement(entry.headerElements[i]!);\n }\n });\n\n doc.oxml.invalidateCharPropertyCache();\n set({\n undoStack: [...undoStack, currentEntry],\n redoStack: newRedoStack,\n selection: entry.selection,\n });\n get().rebuild();\n } catch (e) {\n console.error(\"redo failed:\", e);\n }\n },\n\n deleteBlock: (sectionIndex, paragraphIndex) => {\n const { doc } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n doc.removeParagraph(sectionIndex, paragraphIndex);\n // Adjust selection if it pointed at or after the deleted block\n const { selection } = get();\n if (selection && selection.sectionIndex === sectionIndex) {\n if (selection.paragraphIndex === paragraphIndex) {\n set({ selection: null });\n } else if (selection.paragraphIndex > paragraphIndex) {\n set({\n selection: {\n ...selection,\n paragraphIndex: selection.paragraphIndex - 1,\n },\n });\n }\n }\n get().rebuild();\n } catch (e) {\n console.error(\"deleteBlock failed:\", e);\n }\n },\n\n insertBlockAt: (sectionIndex, paragraphIndex, text = \"\") => {\n const { doc } = get();\n if (!doc) return;\n try {\n get().pushUndo();\n doc.insertParagraphAt(sectionIndex, paragraphIndex, text);\n // Shift selection if it's at or after the insertion point\n const { selection } = get();\n if (\n selection &&\n selection.sectionIndex === sectionIndex &&\n selection.paragraphIndex >= paragraphIndex\n ) {\n set({\n selection: {\n ...selection,\n paragraphIndex: selection.paragraphIndex + 1,\n },\n });\n }\n get().rebuild();\n } catch (e) {\n console.error(\"insertBlockAt failed:\", e);\n }\n },\n\n addParagraph: (text = \"\") => {\n const { doc } = get();\n if (!doc) return;\n try {\n doc.addParagraph(text);\n get().rebuild();\n } catch (e) {\n console.error(\"addParagraph failed:\", e);\n }\n },\n\n addTable: (sectionIndex, paragraphIndex, rows, cols) => {\n const { doc } = get();\n if (!doc) return;\n try {\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const para = section.paragraphs[paragraphIndex];\n if (!para) return;\n get().pushUndo();\n para.addTable(rows, cols);\n get().rebuild();\n } catch (e) {\n console.error(\"addTable failed:\", e);\n }\n },\n\n insertImage: (data, mediaType, widthMm, heightMm) => {\n const { doc } = get();\n if (!doc) return;\n try {\n doc.addImage(data, { mediaType, widthMm, heightMm });\n get().rebuild();\n } catch (e) {\n console.error(\"insertImage failed:\", e);\n }\n },\n\n insertColumnBreak: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const para = doc.addParagraph(\"\");\n para.columnBreak = true;\n get().rebuild();\n } catch (e) {\n console.error(\"insertColumnBreak failed:\", e);\n }\n },\n\n insertPageBreak: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const para = doc.addParagraph(\"\");\n para.pageBreak = true;\n get().rebuild();\n } catch (e) {\n console.error(\"insertPageBreak failed:\", e);\n }\n },\n\n // Image editing actions\n updatePictureSize: (widthMm, heightMm) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.objectType !== \"image\") return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n try {\n para.setPictureSize(selection.imageIndex ?? 0, mmToHwp(widthMm), mmToHwp(heightMm));\n get().rebuild();\n } catch (e) {\n console.error(\"updatePictureSize failed:\", e);\n }\n },\n\n resizeImage: (deltaWidthHwp, deltaHeightHwp) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.objectType !== \"image\") return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const imgIdx = selection.imageIndex ?? 0;\n const pics = para.pictures;\n const pic = pics[imgIdx];\n if (!pic) return;\n try {\n get().pushUndo();\n // Read current size from curSz\n const vm = get().viewModel;\n const imgVM = vm?.sections[selection.sectionIndex]?.paragraphs[selection.paragraphIndex]?.images[imgIdx];\n if (!imgVM) return;\n const newW = Math.max(imgVM.widthHwp + deltaWidthHwp, 200);\n const newH = Math.max(imgVM.heightHwp + deltaHeightHwp, 200);\n para.setPictureSize(imgIdx, newW, newH);\n get().rebuild();\n } catch (e) {\n console.error(\"resizeImage failed:\", e);\n }\n },\n\n setImageOutMargin: (margins) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.objectType !== \"image\") return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const imgIdx = selection.imageIndex ?? 0;\n try {\n get().pushUndo();\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n para.setPictureOutMargin(imgIdx, converted);\n get().rebuild();\n } catch (e) {\n console.error(\"setImageOutMargin failed:\", e);\n }\n },\n\n // Table editing actions\n setTablePageBreak: (mode) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n table.pageBreak = mode;\n get().rebuild();\n } catch (e) {\n console.error(\"setTablePageBreak failed:\", e);\n }\n },\n\n setTableRepeatHeader: (repeat) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n table.repeatHeader = repeat;\n get().rebuild();\n } catch (e) {\n console.error(\"setTableRepeatHeader failed:\", e);\n }\n },\n\n setTableSize: (widthMm, heightMm) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n table.setSize(mmToHwp(widthMm), mmToHwp(heightMm));\n get().rebuild();\n } catch (e) {\n console.error(\"setTableSize failed:\", e);\n }\n },\n\n setTableOutMargin: (margins) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n table.setOutMargin(converted);\n get().rebuild();\n } catch (e) {\n console.error(\"setTableOutMargin failed:\", e);\n }\n },\n\n setTableInMargin: (margins) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n table.setInMargin(converted);\n get().rebuild();\n } catch (e) {\n console.error(\"setTableInMargin failed:\", e);\n }\n },\n\n resizeTableColumn: (sectionIdx, paraIdx, tableIdx, colIdx, deltaHwp) => {\n const { doc } = get();\n if (!doc) return;\n const section = doc.sections[sectionIdx];\n if (!section) return;\n const para = section.paragraphs[paraIdx];\n if (!para) return;\n const table = para.tables[tableIdx];\n if (!table) return;\n try {\n get().pushUndo();\n const colCount = table.columnCount;\n // Get current widths via the grid\n const grid = table.getCellMap();\n const widths: number[] = [];\n for (let c = 0; c < colCount; c++) {\n const pos = grid[0]?.[c];\n widths.push(pos ? pos.cell.width : 0);\n }\n // Adjust left column (colIdx) and right column (colIdx+1)\n if (colIdx < colCount - 1) {\n const newLeft = Math.max(widths[colIdx]! + deltaHwp, 200);\n const newRight = Math.max(widths[colIdx + 1]! - deltaHwp, 200);\n table.setColumnWidth(colIdx, newLeft);\n table.setColumnWidth(colIdx + 1, newRight);\n } else {\n // Last column: adjust its width and the table total width\n const newWidth = Math.max(widths[colIdx]! + deltaHwp, 200);\n table.setColumnWidth(colIdx, newWidth);\n const totalWidth = widths.reduce((a, b) => a + b, 0) + deltaHwp;\n table.setSize(Math.max(totalWidth, 200));\n }\n get().rebuild();\n } catch (e) {\n console.error(\"resizeTableColumn failed:\", e);\n }\n },\n\n // Cell style operations\n setCellBorder: (sides, style) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.row == null || selection.col == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const cell = table.cell(selection.row, selection.col);\n const baseBorderFillId = cell.borderFillIDRef ?? table.borderFillIDRef ?? undefined;\n const baseInfo = baseBorderFillId ? doc.oxml.getBorderFillInfo(baseBorderFillId) : null;\n const getBorderSide = (s: string) => {\n if (!baseInfo) return null;\n if (s === \"left\") return baseInfo.left;\n if (s === \"right\") return baseInfo.right;\n if (s === \"top\") return baseInfo.top;\n if (s === \"bottom\") return baseInfo.bottom;\n return null;\n };\n const sideMap: Record<string, { type: string; width: string; color: string }> = {};\n for (const s of sides) {\n const base = getBorderSide(s);\n sideMap[s] = {\n type: style.type ?? base?.type ?? \"SOLID\",\n width: style.width ?? base?.width ?? \"0.12 mm\",\n color: style.color ?? base?.color ?? \"#000000\",\n };\n }\n const newId = doc.oxml.ensureBorderFillStyle({\n baseBorderFillId,\n sides: sideMap as { left?: { type: string; width: string; color: string }; right?: { type: string; width: string; color: string }; top?: { type: string; width: string; color: string }; bottom?: { type: string; width: string; color: string } },\n });\n cell.borderFillIDRef = newId;\n get().rebuild();\n } catch (e) {\n console.error(\"setCellBorder failed:\", e);\n }\n },\n\n setCellBackground: (color) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.row == null || selection.col == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const cell = table.cell(selection.row, selection.col);\n const baseBorderFillId = cell.borderFillIDRef ?? table.borderFillIDRef ?? undefined;\n const newId = doc.oxml.ensureBorderFillStyle({\n baseBorderFillId,\n backgroundColor: color,\n });\n cell.borderFillIDRef = newId;\n get().rebuild();\n } catch (e) {\n console.error(\"setCellBackground failed:\", e);\n }\n },\n\n setCellVertAlign: (align) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.row == null || selection.col == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const cell = table.cell(selection.row, selection.col);\n cell.vertAlign = align;\n get().rebuild();\n } catch (e) {\n console.error(\"setCellVertAlign failed:\", e);\n }\n },\n\n setTableBorder: (sides, style) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n // Apply to all cells in the table\n const grid = table.iterGrid();\n const processed = new Set<string>();\n for (const pos of grid) {\n const key = `${pos.anchor[0]},${pos.anchor[1]}`;\n if (processed.has(key)) continue;\n processed.add(key);\n const cell = pos.cell;\n const baseBorderFillId = cell.borderFillIDRef ?? table.borderFillIDRef ?? undefined;\n const baseInfo = baseBorderFillId ? doc.oxml.getBorderFillInfo(baseBorderFillId) : null;\n const getBorderSide = (s: string) => {\n if (!baseInfo) return null;\n if (s === \"left\") return baseInfo.left;\n if (s === \"right\") return baseInfo.right;\n if (s === \"top\") return baseInfo.top;\n if (s === \"bottom\") return baseInfo.bottom;\n return null;\n };\n const sideMap: Record<string, { type: string; width: string; color: string }> = {};\n for (const s of sides) {\n const base = getBorderSide(s);\n sideMap[s] = {\n type: style.type ?? base?.type ?? \"SOLID\",\n width: style.width ?? base?.width ?? \"0.12 mm\",\n color: style.color ?? base?.color ?? \"#000000\",\n };\n }\n const newId = doc.oxml.ensureBorderFillStyle({\n baseBorderFillId,\n sides: sideMap as { left?: { type: string; width: string; color: string }; right?: { type: string; width: string; color: string }; top?: { type: string; width: string; color: string }; bottom?: { type: string; width: string; color: string } },\n });\n cell.borderFillIDRef = newId;\n }\n get().rebuild();\n } catch (e) {\n console.error(\"setTableBorder failed:\", e);\n }\n },\n\n setTableBackground: (color) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n try {\n get().pushUndo();\n const grid = table.iterGrid();\n const processed = new Set<string>();\n for (const pos of grid) {\n const key = `${pos.anchor[0]},${pos.anchor[1]}`;\n if (processed.has(key)) continue;\n processed.add(key);\n const cell = pos.cell;\n const baseBorderFillId = cell.borderFillIDRef ?? table.borderFillIDRef ?? undefined;\n const newId = doc.oxml.ensureBorderFillStyle({\n baseBorderFillId,\n backgroundColor: color,\n });\n cell.borderFillIDRef = newId;\n }\n get().rebuild();\n } catch (e) {\n console.error(\"setTableBackground failed:\", e);\n }\n },\n\n setFirstLineIndent: (valueHwp) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment: pf.alignment,\n lineSpacingValue: Math.round(pf.lineSpacing * 100),\n indent: valueHwp,\n marginLeft: pf.indentLeft,\n baseParaPrId: para.paraPrIdRef ?? undefined,\n });\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setFirstLineIndent failed:\", e);\n }\n },\n\n setLeftIndent: (valueHwp) => {\n const { doc, extendedFormat, selection } = get();\n if (!doc || !selection) return;\n try {\n get().pushUndo();\n const pf = extendedFormat.para;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const paraPrIdRef = doc.ensureParaStyle({\n alignment: pf.alignment,\n lineSpacingValue: Math.round(pf.lineSpacing * 100),\n marginLeft: valueHwp,\n indent: pf.firstLineIndent,\n baseParaPrId: para.paraPrIdRef ?? undefined,\n });\n para.paraPrIdRef = paraPrIdRef;\n get().rebuild();\n get().refreshExtendedFormat();\n } catch (e) {\n console.error(\"setLeftIndent failed:\", e);\n }\n },\n\n setPageNumbering: (opts) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n get().pushUndo();\n const props = section.properties;\n if (opts.position === \"none\") {\n // Remove page number text by setting empty header/footer\n props.setHeaderText(\"\");\n props.setFooterText(\"\");\n } else if (opts.position.startsWith(\"header\")) {\n props.setFooterText(\"\"); // clear footer\n const pageNumText = `- {{page}} -`;\n props.setHeaderText(pageNumText);\n } else if (opts.position.startsWith(\"footer\")) {\n props.setHeaderText(\"\"); // clear header\n const pageNumText = `- {{page}} -`;\n props.setFooterText(pageNumText);\n }\n // Set start number if > 0\n if (opts.startNumber > 0) {\n section.properties.setStartNumbering({ page: opts.startNumber });\n }\n get().rebuild();\n } catch (e) {\n console.error(\"setPageNumbering failed:\", e);\n }\n },\n\n // Footnote / Endnote\n insertFootnote: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n try {\n get().pushUndo();\n // Insert a footnote element into the paragraph's run\n // Since the core doesn't have a dedicated API, we'll add via raw XML manipulation\n const paraEl = para.element;\n const NS = \"http://www.hancom.co.kr/hwpml/2011/paragraph\";\n const runs = paraEl.getElementsByTagNameNS(NS, \"run\");\n const lastRun = runs.length > 0 ? runs[runs.length - 1]! : null;\n if (lastRun) {\n const fnEl = paraEl.ownerDocument.createElementNS(NS, \"hp:footNote\");\n // Count existing footnotes in the section to get the marker number\n const existingFn = section.element.getElementsByTagNameNS(NS, \"footNote\");\n const fnNum = existingFn.length + 1;\n fnEl.setAttribute(\"number\", String(fnNum));\n // Add a sub-paragraph with placeholder text\n const subPara = paraEl.ownerDocument.createElementNS(NS, \"hp:subPara\");\n const subRun = paraEl.ownerDocument.createElementNS(NS, \"hp:run\");\n const tEl = paraEl.ownerDocument.createElementNS(NS, \"hp:t\");\n tEl.textContent = `각주 ${fnNum}`;\n subRun.appendChild(tEl);\n subPara.appendChild(subRun);\n fnEl.appendChild(subPara);\n lastRun.appendChild(fnEl);\n }\n get().rebuild();\n } catch (e) {\n console.error(\"insertFootnote failed:\", e);\n }\n },\n\n insertEndnote: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n try {\n get().pushUndo();\n const paraEl = para.element;\n const NS = \"http://www.hancom.co.kr/hwpml/2011/paragraph\";\n const runs = paraEl.getElementsByTagNameNS(NS, \"run\");\n const lastRun = runs.length > 0 ? runs[runs.length - 1]! : null;\n if (lastRun) {\n const enEl = paraEl.ownerDocument.createElementNS(NS, \"hp:endNote\");\n const existingEn = section.element.getElementsByTagNameNS(NS, \"endNote\");\n const enNum = existingEn.length + 1;\n enEl.setAttribute(\"number\", String(enNum));\n const subPara = paraEl.ownerDocument.createElementNS(NS, \"hp:subPara\");\n const subRun = paraEl.ownerDocument.createElementNS(NS, \"hp:run\");\n const tEl = paraEl.ownerDocument.createElementNS(NS, \"hp:t\");\n tEl.textContent = `미주 ${enNum}`;\n subRun.appendChild(tEl);\n subPara.appendChild(subRun);\n enEl.appendChild(subPara);\n lastRun.appendChild(enEl);\n }\n get().rebuild();\n } catch (e) {\n console.error(\"insertEndnote failed:\", e);\n }\n },\n\n setWatermarkText: (text) => {\n const vm = get().viewModel;\n if (!vm) return;\n // Watermark is a UI-only feature stored in the view model\n set({\n viewModel: { ...vm, watermarkText: text },\n revision: get().revision + 1,\n });\n },\n\n // Page setup actions\n updatePageSize: (width, height) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n section.properties.setPageSize({ width: mmToHwp(width), height: mmToHwp(height) });\n get().rebuild();\n } catch (e) {\n console.error(\"updatePageSize failed:\", e);\n }\n },\n\n updatePageMargins: (margins) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n const converted: Record<string, number> = {};\n for (const [k, v] of Object.entries(margins)) {\n if (v !== undefined) converted[k] = mmToHwp(v);\n }\n section.properties.setPageMargins(converted);\n get().rebuild();\n } catch (e) {\n console.error(\"updatePageMargins failed:\", e);\n }\n },\n\n updatePageOrientation: (orientation) => {\n const { doc, selection } = get();\n if (!doc) return;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc.sections[sIdx];\n if (!section) return;\n try {\n const ps = section.properties.pageSize;\n if (orientation === \"LANDSCAPE\" && ps.width < ps.height) {\n section.properties.setPageSize({ width: ps.height, height: ps.width, orientation: \"LANDSCAPE\" });\n } else if (orientation === \"PORTRAIT\" && ps.width > ps.height) {\n section.properties.setPageSize({ width: ps.height, height: ps.width, orientation: \"PORTRAIT\" });\n } else {\n section.properties.setPageSize({ orientation });\n }\n get().rebuild();\n } catch (e) {\n console.error(\"updatePageOrientation failed:\", e);\n }\n },\n\n // Table structure operations\n insertTableRow: (position) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.row == null) return;\n try {\n get().pushUndo();\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n table.insertRow(selection.row, position === \"above\" ? \"before\" : \"after\");\n get().rebuild();\n } catch (e) {\n console.error(\"insertTableRow failed:\", e);\n }\n },\n\n deleteTableRow: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.row == null) return;\n try {\n get().pushUndo();\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n table.deleteRow(selection.row);\n set({ selection: null });\n get().rebuild();\n } catch (e) {\n console.error(\"deleteTableRow failed:\", e);\n }\n },\n\n insertTableColumn: (position) => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.col == null) return;\n try {\n get().pushUndo();\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n table.insertColumn(selection.col, position === \"left\" ? \"before\" : \"after\");\n get().rebuild();\n } catch (e) {\n console.error(\"insertTableColumn failed:\", e);\n }\n },\n\n deleteTableColumn: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null || selection.col == null) return;\n try {\n get().pushUndo();\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n table.deleteColumn(selection.col);\n set({ selection: null });\n get().rebuild();\n } catch (e) {\n console.error(\"deleteTableColumn failed:\", e);\n }\n },\n\n mergeTableCells: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n if (selection.row == null || selection.col == null) return;\n if (selection.endRow == null || selection.endCol == null) return;\n try {\n get().pushUndo();\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n const r1 = Math.min(selection.row, selection.endRow);\n const c1 = Math.min(selection.col, selection.endCol);\n const r2 = Math.max(selection.row, selection.endRow);\n const c2 = Math.max(selection.col, selection.endCol);\n table.mergeCells(r1, c1, r2, c2);\n set({ selection: { ...selection, row: r1, col: c1, endRow: undefined, endCol: undefined } });\n get().rebuild();\n } catch (e) {\n console.error(\"mergeTableCells failed:\", e);\n }\n },\n\n splitTableCell: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n if (selection.row == null || selection.col == null) return;\n try {\n get().pushUndo();\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const table = para.tables[selection.tableIndex];\n if (!table) return;\n table.splitCell(selection.row, selection.col);\n get().rebuild();\n } catch (e) {\n console.error(\"splitTableCell failed:\", e);\n }\n },\n\n deleteTable: () => {\n const { doc, selection } = get();\n if (!doc || !selection || selection.tableIndex == null) return;\n try {\n get().pushUndo();\n doc.removeParagraph(selection.sectionIndex, selection.paragraphIndex);\n set({ selection: null });\n get().rebuild();\n } catch (e) {\n console.error(\"deleteTable failed:\", e);\n }\n },\n\n // File operations\n openFile: () => {\n window.dispatchEvent(new CustomEvent(\"hwpx-open-file\"));\n },\n\n saveDocument: async () => {\n get().openSaveDialog();\n },\n\n saveDocumentAs: async (filename) => {\n const { doc } = get();\n if (!doc) return;\n try {\n set({ loading: true });\n const bytes = await doc.save();\n const blob = new Blob([bytes as unknown as BlobPart], {\n type: \"application/vnd.hancom.hwpx\",\n });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename.endsWith(\".hwpx\") ? filename : `${filename}.hwpx`;\n a.click();\n URL.revokeObjectURL(url);\n get().closeSaveDialog();\n } catch (e) {\n console.error(\"save failed:\", e);\n set({ error: \"문서 저장에 실패했습니다.\" });\n } finally {\n set({ loading: false });\n }\n },\n\n openSaveDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, saveDialogOpen: true } })),\n\n closeSaveDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, saveDialogOpen: false } })),\n\n // Dialog open/close\n openCharFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charFormatDialogOpen: true } })),\n closeCharFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charFormatDialogOpen: false } })),\n openParaFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, paraFormatDialogOpen: true } })),\n closeParaFormatDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, paraFormatDialogOpen: false } })),\n openBulletNumberDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, bulletNumberDialogOpen: true } })),\n closeBulletNumberDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, bulletNumberDialogOpen: false } })),\n openCharMapDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charMapDialogOpen: true } })),\n closeCharMapDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, charMapDialogOpen: false } })),\n openTemplateDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, templateDialogOpen: true } })),\n closeTemplateDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, templateDialogOpen: false } })),\n openHeaderFooterDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, headerFooterDialogOpen: true } })),\n closeHeaderFooterDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, headerFooterDialogOpen: false } })),\n openFindReplaceDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, findReplaceDialogOpen: true } })),\n closeFindReplaceDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, findReplaceDialogOpen: false } })),\n openWordCountDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, wordCountDialogOpen: true } })),\n closeWordCountDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, wordCountDialogOpen: false } })),\n openPageNumberDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, pageNumberDialogOpen: true } })),\n closePageNumberDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, pageNumberDialogOpen: false } })),\n openStyleDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, styleDialogOpen: true } })),\n closeStyleDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, styleDialogOpen: false } })),\n openAutoCorrectDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, autoCorrectDialogOpen: true } })),\n closeAutoCorrectDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, autoCorrectDialogOpen: false } })),\n openOutlineDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, outlineDialogOpen: true } })),\n closeOutlineDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, outlineDialogOpen: false } })),\n openShapeDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, shapeDialogOpen: true } })),\n closeShapeDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, shapeDialogOpen: false } })),\n openTocDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, tocDialogOpen: true } })),\n closeTocDialog: () =>\n set((s) => ({ uiState: { ...s.uiState, tocDialogOpen: false } })),\n setZoom: (level) =>\n set((s) => ({ uiState: { ...s.uiState, zoomLevel: level } })),\n zoomIn: () =>\n set((s) => ({ uiState: { ...s.uiState, zoomLevel: Math.min(s.uiState.zoomLevel + 10, 400) } })),\n zoomOut: () =>\n set((s) => ({ uiState: { ...s.uiState, zoomLevel: Math.max(s.uiState.zoomLevel - 10, 25) } })),\n\n insertTextAtCursor: (text) => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n get().pushUndo();\n para.text = para.text + text;\n get().rebuild();\n } catch (e) {\n console.error(\"insertTextAtCursor failed:\", e);\n }\n },\n\n insertTab: () => {\n const { doc, selection } = get();\n if (!doc || !selection) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n get().pushUndo();\n para.addTab();\n get().rebuild();\n } catch (e) {\n console.error(\"insertTab failed:\", e);\n }\n },\n\n // Template management (browser localStorage)\n loadTemplates: () => {\n try {\n const raw = localStorage.getItem(\"hwpx-editor-templates\");\n if (raw) {\n const templates = JSON.parse(raw);\n if (Array.isArray(templates)) set({ templates });\n }\n } catch { /* ignore parse errors */ }\n },\n saveTemplates: () => {\n try {\n localStorage.setItem(\"hwpx-editor-templates\", JSON.stringify(get().templates));\n } catch { /* ignore storage errors */ }\n },\n addTemplate: (name, path, description) => {\n const template = { id: crypto.randomUUID(), name, path, description, createdAt: Date.now() };\n const templates = [...get().templates, template];\n set({ templates });\n try { localStorage.setItem(\"hwpx-editor-templates\", JSON.stringify(templates)); } catch {}\n },\n removeTemplate: (id) => {\n const templates = get().templates.filter((t) => t.id !== id);\n set({ templates });\n try { localStorage.setItem(\"hwpx-editor-templates\", JSON.stringify(templates)); } catch {}\n },\n}));\n","/**\n * EditorViewModel — pure data structures derived from HwpxDocument for rendering.\n */\n\nimport type {\n HwpxDocument,\n RunStyle,\n HwpxTableGridPosition,\n} from \"@ubermensch1218/hwpxcore\";\nimport { parseHeaderXml, serializeXml } from \"@ubermensch1218/hwpxcore\";\nimport type { Header, ParagraphProperty } from \"@ubermensch1218/hwpxcore\";\nimport { hwpToPx } from \"./hwp-units\";\nimport { extractImages } from \"./image-extractor\";\n\n// ── ViewModel types ────────────────────────────────────────────────────────\n\nexport interface RunVM {\n text: string;\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n color: string | null;\n fontFamily: string | null;\n fontSize: number | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n charPrIdRef: string | null;\n hasTab?: boolean; // true if this run contains a tab character\n hasFwSpace?: boolean; // true if this run is a full-width space\n hasLineBreak?: boolean; // true if this run is a line break\n hyperlink?: string; // URL if this run is inside a hyperlink\n}\n\nexport interface MarginVM {\n top: number;\n bottom: number;\n left: number;\n right: number;\n}\n\nexport interface CellBorderStyleVM {\n type: string;\n width: string;\n color: string;\n}\n\nexport interface CellStyleVM {\n borderLeft: CellBorderStyleVM | null;\n borderRight: CellBorderStyleVM | null;\n borderTop: CellBorderStyleVM | null;\n borderBottom: CellBorderStyleVM | null;\n backgroundColor: string | null;\n}\n\nexport interface TableCellVM {\n row: number;\n col: number;\n rowSpan: number;\n colSpan: number;\n widthPx: number;\n heightPx: number;\n text: string;\n isAnchor: boolean; // true if this is the top-left of a merged region\n borderFillIDRef: string | null;\n vertAlign: string; // \"TOP\" | \"CENTER\" | \"BOTTOM\"\n style: CellStyleVM | null;\n}\n\nexport interface TableVM {\n rowCount: number;\n colCount: number;\n cells: TableCellVM[][]; // 2D grid [row][col], non-anchor cells have isAnchor=false\n tableIndex: number; // index within the paragraph\n pageBreak: string; // \"CELL\", \"NONE\", etc.\n repeatHeader: boolean;\n widthHwp: number;\n heightHwp: number;\n outMargin: MarginVM; // table outer margin in hwpUnits\n inMargin: MarginVM; // table inner cell margin in hwpUnits\n columnWidths: number[]; // per-column width in hwpUnits\n borderFillIDRef: string | null;\n}\n\nexport interface ImageVM {\n dataUrl: string;\n widthPx: number;\n heightPx: number;\n widthHwp: number;\n heightHwp: number;\n binaryItemIdRef: string;\n outMargin: MarginVM;\n}\n\nexport interface EquationVM {\n script: string; // HWP equation script\n widthPx: number;\n heightPx: number;\n textColor: string;\n font: string;\n baseLine: number;\n}\n\nexport interface TextBoxVM {\n text: string;\n widthPx: number;\n heightPx: number;\n widthHwp: number;\n heightHwp: number;\n x: number;\n y: number;\n borderColor: string;\n fillColor: string;\n textBoxIndex: number;\n}\n\nexport interface ParagraphVM {\n runs: RunVM[];\n tables: TableVM[];\n images: ImageVM[];\n textBoxes: TextBoxVM[];\n equations: EquationVM[];\n alignment: string;\n lineSpacing: number;\n spacingBefore: number;\n spacingAfter: number;\n firstLineIndent: number;\n marginLeftPx: number;\n marginRightPx: number;\n paragraphIndex: number; // global index across all sections\n defaultFontSize: number | null;\n defaultFontFamily: string | null;\n}\n\nexport interface FootnoteVM {\n marker: string; // e.g. \"1\", \"2\", ...\n text: string;\n}\n\nexport interface ColumnLayoutVM {\n colCount: number;\n sameGap: number; // gap in px\n type: string; // \"NEWSPAPER\", \"BALANCED\", etc.\n}\n\nexport interface PageNumVM {\n pos: string; // \"BOTTOM_CENTER\", \"TOP_CENTER\", etc.\n formatType: string; // \"DIGIT\", \"ROMAN\", etc.\n sideChar: string; // e.g. \"-\" for \"- 1 -\"\n}\n\nexport interface PageBorderFillVM {\n type: string; // \"BOTH\", \"EVEN\", \"ODD\"\n borderFillIdRef: string;\n textBorder: string; // \"PAPER\", \"CONTENT\"\n fillArea: string; // \"PAPER\", \"CONTENT\"\n}\n\nexport interface SectionVM {\n pageWidthPx: number;\n pageHeightPx: number;\n marginTopPx: number;\n marginBottomPx: number;\n marginLeftPx: number;\n marginRightPx: number;\n headerHeightPx: number;\n footerHeightPx: number;\n paragraphs: ParagraphVM[];\n sectionIndex: number;\n headerText: string;\n footerText: string;\n footnotes: FootnoteVM[];\n endnotes: FootnoteVM[];\n columnLayout: ColumnLayoutVM;\n pageNum: PageNumVM | null;\n pageBorderFill: PageBorderFillVM | null;\n}\n\nexport interface EditorViewModel {\n sections: SectionVM[];\n watermarkText: string;\n}\n\n// ── Builder ────────────────────────────────────────────────────────────────\n\nfunction extractRunStyle(\n style: RunStyle | null,\n doc?: HwpxDocument | null,\n): {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n color: string | null;\n fontFamily: string | null;\n fontSize: number | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n} {\n if (!style) {\n return {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n color: null,\n fontFamily: null,\n fontSize: null,\n highlightColor: null,\n letterSpacing: null,\n };\n }\n\n const bold = style.attributes[\"bold\"] === \"1\";\n const italic = style.attributes[\"italic\"] === \"1\";\n\n // Check underline child element\n const underlineChild = style.childAttributes[\"underline\"];\n const underline =\n underlineChild != null &&\n underlineChild[\"type\"] != null &&\n underlineChild[\"type\"] !== \"NONE\";\n\n // Strikethrough\n const strikeChild = style.childAttributes[\"strikeout\"];\n const strikethrough =\n strikeChild != null &&\n strikeChild[\"type\"] != null &&\n strikeChild[\"type\"] !== \"NONE\";\n\n const color = style.attributes[\"textColor\"] ?? null;\n\n // Highlight\n const highlightColor = style.attributes[\"shadeColor\"] ?? null;\n\n // Font family — resolve numeric ID to face name\n let fontFamily: string | null = null;\n const fontRef = style.childAttributes[\"fontRef\"];\n if (fontRef) {\n const hangulId = fontRef[\"hangul\"] ?? fontRef[\"latin\"] ?? null;\n if (hangulId != null && doc) {\n fontFamily = doc.fontFaceName(hangulId) ?? hangulId;\n } else {\n fontFamily = hangulId;\n }\n }\n\n // Font size (height in hwpUnits / 100 = pt)\n let fontSize: number | null = null;\n const sizeStr = style.attributes[\"height\"];\n if (sizeStr) {\n const hwpVal = parseInt(sizeStr, 10);\n if (!isNaN(hwpVal)) fontSize = hwpVal / 100;\n }\n\n // Letter spacing\n let letterSpacing: number | null = null;\n const spacingStr = style.attributes[\"spacing\"];\n if (spacingStr) {\n const val = parseInt(spacingStr, 10);\n if (!isNaN(val) && val !== 0) letterSpacing = val;\n }\n\n return { bold, italic, underline, strikethrough, color, fontFamily, fontSize, highlightColor, letterSpacing };\n}\n\n/** Find equation elements inside a run. */\nfunction findEquationRefs(\n runElement: Element,\n): { script: string; width: number; height: number; textColor: string; font: string; baseLine: number }[] {\n const results: { script: string; width: number; height: number; textColor: string; font: string; baseLine: number }[] = [];\n\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"equation\") continue;\n\n let width = 0;\n let height = 0;\n let script = \"\";\n const textColor = el.getAttribute(\"textColor\") ?? \"#000000\";\n const font = el.getAttribute(\"font\") ?? \"HancomEQN\";\n const baseLine = parseInt(el.getAttribute(\"baseLine\") ?? \"85\", 10);\n\n const eqChildren = el.childNodes;\n for (let j = 0; j < eqChildren.length; j++) {\n const ec = eqChildren.item(j);\n if (!ec || ec.nodeType !== 1) continue;\n const eel = ec as Element;\n const eName = eel.localName || eel.nodeName.split(\":\").pop() || \"\";\n\n if (eName === \"sz\") {\n width = parseInt(eel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(eel.getAttribute(\"height\") ?? \"0\", 10);\n } else if (eName === \"script\") {\n script = eel.textContent ?? \"\";\n }\n }\n\n results.push({ script, width, height, textColor, font, baseLine });\n }\n\n return results;\n}\n\n/** Find drawText (text box) elements inside a run. */\nfunction findTextBoxRefs(\n runElement: Element,\n): { text: string; width: number; height: number; x: number; y: number; borderColor: string; fillColor: string }[] {\n const results: { text: string; width: number; height: number; x: number; y: number; borderColor: string; fillColor: string }[] = [];\n\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"drawText\") continue;\n\n let width = 0;\n let height = 0;\n let x = 0;\n let y = 0;\n let borderColor = \"#000000\";\n let fillColor = \"#FFFFFF\";\n let text = \"\";\n\n const boxChildren = el.childNodes;\n for (let j = 0; j < boxChildren.length; j++) {\n const bc = boxChildren.item(j);\n if (!bc || bc.nodeType !== 1) continue;\n const bel = bc as Element;\n const bName = bel.localName || bel.nodeName.split(\":\").pop() || \"\";\n\n if (bName === \"sz\") {\n width = parseInt(bel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(bel.getAttribute(\"height\") ?? \"0\", 10);\n } else if (bName === \"pos\") {\n x = parseInt(bel.getAttribute(\"horzOffset\") ?? \"0\", 10);\n y = parseInt(bel.getAttribute(\"vertOffset\") ?? \"0\", 10);\n } else if (bName === \"lineShape\") {\n borderColor = bel.getAttribute(\"color\") ?? \"#000000\";\n }\n }\n\n // Get fill color from fillBrush/winBrush\n const fillBrushes = el.getElementsByTagName(\"*\");\n for (let k = 0; k < fillBrushes.length; k++) {\n const fb = fillBrushes.item(k);\n if (!fb) continue;\n const fbName = fb.localName || fb.nodeName.split(\":\").pop() || \"\";\n if (fbName === \"winBrush\") {\n fillColor = fb.getAttribute(\"faceColor\") ?? \"#FFFFFF\";\n }\n }\n\n // Get text from sub-paragraphs\n const textEls = el.getElementsByTagName(\"*\");\n for (let k = 0; k < textEls.length; k++) {\n const te = textEls.item(k);\n if (!te) continue;\n const teName = te.localName || te.nodeName.split(\":\").pop() || \"\";\n if (teName === \"t\") {\n text += te.textContent ?? \"\";\n }\n }\n\n results.push({ text, width, height, x, y, borderColor, fillColor });\n }\n\n return results;\n}\n\n/** Find binaryItemIDRef from a picture element inside a run. */\nfunction findPictureRefs(\n runElement: Element,\n): { binaryItemIdRef: string; width: number; height: number }[] {\n const results: { binaryItemIdRef: string; width: number; height: number }[] = [];\n\n // Look for <pic> elements inside the run\n const children = runElement.childNodes;\n for (let i = 0; i < children.length; i++) {\n const child = children.item(i);\n if (!child || child.nodeType !== 1) continue;\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (localName !== \"pic\") continue;\n\n // Get size from curSz\n let width = 0;\n let height = 0;\n const picChildren = el.childNodes;\n for (let j = 0; j < picChildren.length; j++) {\n const pc = picChildren.item(j);\n if (!pc || pc.nodeType !== 1) continue;\n const pel = pc as Element;\n const pName = pel.localName || pel.nodeName.split(\":\").pop() || \"\";\n\n if (pName === \"curSz\") {\n width = parseInt(pel.getAttribute(\"width\") ?? \"0\", 10);\n height = parseInt(pel.getAttribute(\"height\") ?? \"0\", 10);\n }\n\n // Find img element inside pic (possibly nested in renderingInfo or directly)\n if (pName === \"img\") {\n const ref = pel.getAttribute(\"binaryItemIDRef\");\n if (ref) results.push({ binaryItemIdRef: ref, width, height });\n }\n }\n\n // Also search deeper for img (might be in a sub-element)\n const allDescendants = el.getElementsByTagName(\"*\");\n for (let k = 0; k < allDescendants.length; k++) {\n const desc = allDescendants.item(k);\n if (!desc) continue;\n const dName = desc.localName || desc.nodeName.split(\":\").pop() || \"\";\n if (dName === \"img\") {\n const ref = desc.getAttribute(\"binaryItemIDRef\");\n if (ref && !results.some((r) => r.binaryItemIdRef === ref)) {\n results.push({ binaryItemIdRef: ref, width, height });\n }\n }\n }\n }\n\n return results;\n}\n\n/** Parse the header element to get ParagraphProperty lookup. */\nfunction buildParaPrLookup(doc: HwpxDocument): Map<string, ParagraphProperty> {\n const lookup = new Map<string, ParagraphProperty>();\n try {\n const headers = doc.headers;\n if (headers.length === 0) return lookup;\n const headerEl = headers[0]!.element;\n const xml = serializeXml(headerEl);\n const parsed: Header = parseHeaderXml(xml);\n if (!parsed.refList?.paraProperties) return lookup;\n for (const prop of parsed.refList.paraProperties.properties) {\n if (prop.rawId) lookup.set(prop.rawId, prop);\n if (prop.id != null) lookup.set(String(prop.id), prop);\n }\n } catch {\n // ignore parse errors\n }\n return lookup;\n}\n\nexport function buildViewModel(doc: HwpxDocument): EditorViewModel {\n const imageMap = extractImages(doc.package);\n const paraPrLookup = buildParaPrLookup(doc);\n const sections: SectionVM[] = [];\n\n let globalParaIndex = 0;\n\n for (let sIdx = 0; sIdx < doc.sections.length; sIdx++) {\n const section = doc.sections[sIdx]!;\n const props = section.properties;\n const pageSize = props.pageSize;\n const pageMargins = props.pageMargins;\n\n // Extract header/footer text\n let headerText = \"\";\n let footerText = \"\";\n try {\n const hdr = props.getHeader(\"BOTH\");\n if (hdr) headerText = hdr.text;\n } catch { /* no header */ }\n try {\n const ftr = props.getFooter(\"BOTH\");\n if (ftr) footerText = ftr.text;\n } catch { /* no footer */ }\n\n // Extract footnotes from paragraph annotation elements\n const footnotes: FootnoteVM[] = [];\n const endnotes: FootnoteVM[] = [];\n try {\n const sectionEl = section.element;\n const allEls = sectionEl.getElementsByTagName(\"*\");\n let fnIdx = 1;\n let enIdx = 1;\n for (let k = 0; k < allEls.length; k++) {\n const el = allEls.item(k);\n if (!el) continue;\n const ln = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (ln === \"footNote\" || ln === \"endNote\") {\n // Extract text from sub paragraphs\n const subParas = el.getElementsByTagName(\"*\");\n let noteText = \"\";\n for (let m = 0; m < subParas.length; m++) {\n const sp = subParas.item(m);\n if (!sp) continue;\n const spName = sp.localName || sp.nodeName.split(\":\").pop() || \"\";\n if (spName === \"t\") noteText += sp.textContent ?? \"\";\n }\n if (ln === \"footNote\") {\n footnotes.push({ marker: String(fnIdx++), text: noteText });\n } else {\n endnotes.push({ marker: String(enIdx++), text: noteText });\n }\n }\n }\n } catch { /* ignore */ }\n\n // Extract column layout\n let columnLayoutVM: ColumnLayoutVM = { colCount: 1, sameGap: 0, type: \"NEWSPAPER\" };\n try {\n const colLayout = props.columnLayout;\n columnLayoutVM = {\n colCount: colLayout.colCount,\n sameGap: hwpToPx(colLayout.sameGap),\n type: colLayout.type,\n };\n } catch { /* ignore */ }\n\n // Extract page numbering\n let pageNumVM: PageNumVM | null = null;\n try {\n const sectionEl = section.element;\n const pageNumEls = sectionEl.getElementsByTagName(\"*\");\n for (let k = 0; k < pageNumEls.length; k++) {\n const el = pageNumEls.item(k);\n if (!el) continue;\n const ln = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (ln === \"pageNum\") {\n pageNumVM = {\n pos: el.getAttribute(\"pos\") ?? \"BOTTOM_CENTER\",\n formatType: el.getAttribute(\"formatType\") ?? \"DIGIT\",\n sideChar: el.getAttribute(\"sideChar\") ?? \"\",\n };\n break;\n }\n }\n } catch { /* ignore */ }\n\n // Extract page border fill\n let pageBorderFillVM: PageBorderFillVM | null = null;\n try {\n const sectionEl = section.element;\n const borderFillEls = sectionEl.getElementsByTagName(\"*\");\n for (let k = 0; k < borderFillEls.length; k++) {\n const el = borderFillEls.item(k);\n if (!el) continue;\n const ln = el.localName || el.nodeName.split(\":\").pop() || \"\";\n if (ln === \"pageBorderFill\") {\n const type = el.getAttribute(\"type\") ?? \"BOTH\";\n // Use the BOTH type or first found\n if (type === \"BOTH\" || !pageBorderFillVM) {\n pageBorderFillVM = {\n type,\n borderFillIdRef: el.getAttribute(\"borderFillIDRef\") ?? \"0\",\n textBorder: el.getAttribute(\"textBorder\") ?? \"PAPER\",\n fillArea: el.getAttribute(\"fillArea\") ?? \"PAPER\",\n };\n if (type === \"BOTH\") break;\n }\n }\n }\n } catch { /* ignore */ }\n\n const sectionVM: SectionVM = {\n pageWidthPx: hwpToPx(pageSize.width),\n pageHeightPx: hwpToPx(pageSize.height),\n marginTopPx: hwpToPx(pageMargins.top),\n marginBottomPx: hwpToPx(pageMargins.bottom),\n marginLeftPx: hwpToPx(pageMargins.left),\n marginRightPx: hwpToPx(pageMargins.right),\n headerHeightPx: hwpToPx(pageMargins.header ?? 0),\n footerHeightPx: hwpToPx(pageMargins.footer ?? 0),\n paragraphs: [],\n sectionIndex: sIdx,\n headerText,\n footerText,\n footnotes,\n endnotes,\n columnLayout: columnLayoutVM,\n pageNum: pageNumVM,\n pageBorderFill: pageBorderFillVM,\n };\n\n const paragraphs = section.paragraphs;\n for (const para of paragraphs) {\n const runs: RunVM[] = [];\n const images: ImageVM[] = [];\n const textBoxes: TextBoxVM[] = [];\n const equations: EquationVM[] = [];\n let currentHyperlink: string | null = null; // Track hyperlink across runs\n\n for (const run of para.runs) {\n const style = run.style;\n const {\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n } = extractRunStyle(style, doc);\n\n // Process run children to handle tabs and text in order\n const runChildren = run.element.childNodes;\n let currentText = \"\";\n let hasTab = false;\n\n for (let i = 0; i < runChildren.length; i++) {\n const child = runChildren.item(i);\n if (!child) continue;\n\n if (child.nodeType === 1) {\n const el = child as Element;\n const localName = el.localName || el.nodeName.split(\":\").pop() || \"\";\n\n if (localName === \"t\") {\n currentText += el.textContent ?? \"\";\n } else if (localName === \"tab\") {\n // Flush current text if any, then add tab\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n currentText = \"\";\n }\n // Add a tab run\n runs.push({\n text: \"\\t\",\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hasTab: true,\n });\n hasTab = true;\n } else if (localName === \"fwSpace\") {\n // Full-width space (전각 공백)\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n currentText = \"\";\n }\n runs.push({\n text: \"\\u3000\", // Full-width space character\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hasFwSpace: true,\n hyperlink: currentHyperlink ?? undefined,\n });\n } else if (localName === \"lineBreak\") {\n // Line break within paragraph\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n currentText = \"\";\n }\n runs.push({\n text: \"\\n\",\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hasLineBreak: true,\n });\n } else if (localName === \"fieldBegin\") {\n // Start of a field (e.g., hyperlink)\n const fieldType = el.getAttribute(\"type\");\n if (fieldType === \"HYPERLINK\") {\n // Flush current text before hyperlink\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n });\n currentText = \"\";\n }\n // Extract URL from stringParam elements\n const params = el.getElementsByTagName(\"*\");\n for (let pi = 0; pi < params.length; pi++) {\n const param = params.item(pi);\n if (!param) continue;\n const pName = param.localName || param.nodeName.split(\":\").pop() || \"\";\n if (pName === \"stringParam\") {\n const paramName = param.getAttribute(\"name\");\n if (paramName === \"Command\" || paramName === \"Path\") {\n const url = param.textContent?.trim();\n if (url) {\n currentHyperlink = url;\n break;\n }\n }\n }\n }\n }\n } else if (localName === \"fieldEnd\") {\n // End of a field\n if (currentHyperlink && currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink,\n });\n currentText = \"\";\n }\n currentHyperlink = null;\n }\n }\n }\n\n // Flush remaining text\n if (currentText) {\n runs.push({\n text: currentText,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n hyperlink: currentHyperlink ?? undefined,\n });\n }\n\n // If no content was found but run has text, use fallback\n if (runs.length === 0 || (!currentText && !hasTab)) {\n const text = run.text;\n if (text) {\n runs.push({\n text,\n bold, italic, underline, strikethrough, color,\n fontFamily, fontSize, highlightColor, letterSpacing,\n charPrIdRef: run.charPrIdRef,\n });\n }\n }\n\n // Check for images inside this run\n const picRefs = findPictureRefs(run.element);\n for (let picIdx = 0; picIdx < picRefs.length; picIdx++) {\n const ref = picRefs[picIdx]!;\n const dataUrl = imageMap.get(ref.binaryItemIdRef);\n if (dataUrl) {\n const outMargin = para.getPictureOutMargin(images.length);\n images.push({\n dataUrl,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n widthHwp: ref.width,\n heightHwp: ref.height,\n binaryItemIdRef: ref.binaryItemIdRef,\n outMargin,\n });\n }\n }\n\n // Check for text boxes inside this run\n const textBoxRefs = findTextBoxRefs(run.element);\n for (let tbIdx = 0; tbIdx < textBoxRefs.length; tbIdx++) {\n const ref = textBoxRefs[tbIdx]!;\n textBoxes.push({\n text: ref.text,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n widthHwp: ref.width,\n heightHwp: ref.height,\n x: ref.x,\n y: ref.y,\n borderColor: ref.borderColor,\n fillColor: ref.fillColor,\n textBoxIndex: textBoxes.length,\n });\n }\n\n // Check for equations inside this run\n const equationRefs = findEquationRefs(run.element);\n for (const ref of equationRefs) {\n equations.push({\n script: ref.script,\n widthPx: hwpToPx(ref.width),\n heightPx: hwpToPx(ref.height),\n textColor: ref.textColor,\n font: ref.font,\n baseLine: ref.baseLine,\n });\n }\n }\n\n // Tables\n const tables: TableVM[] = [];\n const paraTables = para.tables;\n for (let tIdx = 0; tIdx < paraTables.length; tIdx++) {\n const table = paraTables[tIdx]!;\n const rowCount = table.rowCount;\n const colCount = table.columnCount;\n\n let cellGrid: HwpxTableGridPosition[][] = [];\n try {\n cellGrid = table.getCellMap();\n } catch {\n // If grid building fails, skip\n continue;\n }\n\n const cellsVM: TableCellVM[][] = [];\n for (let r = 0; r < rowCount; r++) {\n const row: TableCellVM[] = [];\n for (let c = 0; c < colCount; c++) {\n const pos = cellGrid[r]?.[c];\n if (!pos) {\n row.push({\n row: r,\n col: c,\n rowSpan: 1,\n colSpan: 1,\n widthPx: 0,\n heightPx: 0,\n text: \"\",\n isAnchor: false,\n borderFillIDRef: null,\n vertAlign: \"CENTER\",\n style: null,\n });\n continue;\n }\n\n const isAnchor = pos.anchor[0] === r && pos.anchor[1] === c;\n const cellBfId = pos.cell.element.getAttribute(\"borderFillIDRef\");\n let cellStyle: CellStyleVM | null = null;\n if (cellBfId) {\n try {\n const bfInfo = doc.oxml.getBorderFillInfo(cellBfId);\n if (bfInfo) {\n cellStyle = {\n borderLeft: bfInfo.left.type !== \"NONE\" ? bfInfo.left : null,\n borderRight: bfInfo.right.type !== \"NONE\" ? bfInfo.right : null,\n borderTop: bfInfo.top.type !== \"NONE\" ? bfInfo.top : null,\n borderBottom: bfInfo.bottom.type !== \"NONE\" ? bfInfo.bottom : null,\n backgroundColor: bfInfo.backgroundColor,\n };\n }\n } catch { /* ignore */ }\n }\n row.push({\n row: r,\n col: c,\n rowSpan: pos.span[0],\n colSpan: pos.span[1],\n widthPx: hwpToPx(pos.cell.width),\n heightPx: hwpToPx(pos.cell.height),\n text: isAnchor ? pos.cell.text : \"\",\n isAnchor,\n borderFillIDRef: cellBfId,\n vertAlign: (() => {\n const sl = Array.from(pos.cell.element.childNodes).find(\n (n) => n.nodeType === 1 && ((n as Element).localName === \"subList\" || (n as Element).nodeName.split(\":\").pop() === \"subList\"),\n ) as Element | undefined;\n return (sl?.getAttribute?.(\"vertAlign\") ?? \"CENTER\").toUpperCase();\n })(),\n style: cellStyle,\n });\n }\n cellsVM.push(row);\n }\n\n // Compute per-column widths - find a cell with colSpan=1 for each column\n const columnWidths: number[] = [];\n for (let c = 0; c < colCount; c++) {\n let width = 0;\n // First, try to find a cell with colSpan=1 in this column\n for (let r = 0; r < rowCount && width === 0; r++) {\n const pos = cellGrid[r]?.[c];\n if (pos && pos.anchor[1] === c && pos.span[1] === 1) {\n width = pos.cell.width;\n }\n }\n // If not found, distribute merged cell width\n if (width === 0) {\n const pos = cellGrid[0]?.[c];\n if (pos) {\n width = Math.round(pos.cell.width / pos.span[1]);\n }\n }\n columnWidths.push(width);\n }\n\n const outMargin = table.getOutMargin();\n const inMargin = table.getInMargin();\n\n tables.push({\n rowCount,\n colCount,\n cells: cellsVM,\n tableIndex: tIdx,\n pageBreak: table.pageBreak,\n repeatHeader: table.repeatHeader,\n widthHwp: table.width,\n heightHwp: table.height,\n outMargin,\n inMargin,\n columnWidths,\n borderFillIDRef: table.element.getAttribute(\"borderFillIDRef\"),\n });\n }\n\n // Extract default character formatting from paragraph's charPrIdRef\n let defaultFontSize: number | null = null;\n let defaultFontFamily: string | null = null;\n const paraCharPrIdRef = para.charPrIdRef;\n if (paraCharPrIdRef) {\n const charStyle = doc.charProperty(paraCharPrIdRef);\n if (charStyle) {\n const extracted = extractRunStyle(charStyle, doc);\n defaultFontSize = extracted.fontSize;\n defaultFontFamily = extracted.fontFamily;\n }\n }\n // Fallback: use first run's style if paragraph-level is missing\n if (defaultFontSize == null && runs.length > 0) {\n defaultFontSize = runs[0]!.fontSize;\n }\n if (defaultFontFamily == null && runs.length > 0) {\n defaultFontFamily = runs[0]!.fontFamily;\n }\n\n // Extract paragraph formatting from paraPrIdRef\n let alignment = \"LEFT\";\n let lineSpacing = 1.6;\n let spacingBefore = 0;\n let spacingAfter = 0;\n let firstLineIndent = 0;\n let marginLeftPx = 0;\n let marginRightPx = 0;\n\n const paraPrIdRef = para.paraPrIdRef;\n if (paraPrIdRef) {\n const paraPr = paraPrLookup.get(paraPrIdRef);\n if (paraPr) {\n // Alignment\n if (paraPr.align?.horizontal) {\n alignment = paraPr.align.horizontal.toUpperCase();\n }\n // Line spacing\n if (paraPr.lineSpacing?.value != null) {\n lineSpacing = paraPr.lineSpacing.value / 100;\n }\n // Margins and spacing\n if (paraPr.margin) {\n if (paraPr.margin.left) {\n marginLeftPx = hwpToPx(parseInt(paraPr.margin.left, 10) || 0);\n }\n if (paraPr.margin.right) {\n marginRightPx = hwpToPx(parseInt(paraPr.margin.right, 10) || 0);\n }\n if (paraPr.margin.intent) {\n firstLineIndent = hwpToPx(parseInt(paraPr.margin.intent, 10) || 0);\n }\n if (paraPr.margin.prev) {\n spacingBefore = hwpToPx(parseInt(paraPr.margin.prev, 10) || 0);\n }\n if (paraPr.margin.next) {\n spacingAfter = hwpToPx(parseInt(paraPr.margin.next, 10) || 0);\n }\n }\n }\n }\n\n sectionVM.paragraphs.push({\n runs,\n tables,\n images,\n textBoxes,\n equations,\n alignment,\n lineSpacing,\n spacingBefore,\n spacingAfter,\n firstLineIndent,\n marginLeftPx,\n marginRightPx,\n paragraphIndex: globalParaIndex,\n defaultFontSize,\n defaultFontFamily,\n });\n\n globalParaIndex++;\n }\n\n sections.push(sectionVM);\n }\n\n return { sections, watermarkText: \"\" };\n}\n","/**\n * HWPX unit conversion utilities.\n *\n * HWPX uses hwpUnit where 7200 hwpUnit = 1 inch = 25.4 mm.\n * Screen rendering at 96 DPI: 1 hwpUnit = 96/7200 px ≈ 0.01333 px.\n */\n\nconst HWP_UNITS_PER_INCH = 7200;\nconst PX_PER_INCH = 96;\nconst MM_PER_INCH = 25.4;\n\n/** Convert hwpUnit to pixels at 96 DPI. */\nexport function hwpToPx(hwpUnit: number): number {\n return (hwpUnit * PX_PER_INCH) / HWP_UNITS_PER_INCH;\n}\n\n/** Convert pixels (96 DPI) to hwpUnit. */\nexport function pxToHwp(px: number): number {\n return Math.round((px * HWP_UNITS_PER_INCH) / PX_PER_INCH);\n}\n\n/** Convert hwpUnit to millimeters. */\nexport function hwpToMm(hwpUnit: number): number {\n return (hwpUnit * MM_PER_INCH) / HWP_UNITS_PER_INCH;\n}\n\n/** Convert millimeters to hwpUnit. */\nexport function mmToHwp(mm: number): number {\n return Math.round((mm * HWP_UNITS_PER_INCH) / MM_PER_INCH);\n}\n","/**\n * Extract binary image data from an HwpxDocument package as data URLs.\n */\n\nimport type { HwpxPackage } from \"@ubermensch1218/hwpxcore\";\n\n/** Map of binaryItemIdRef → data:... URL for all images in the package. */\nexport function extractImages(pkg: HwpxPackage): Map<string, string> {\n const images = new Map<string, string>();\n const partNames = pkg.partNames();\n\n for (const name of partNames) {\n if (!name.startsWith(\"BinData/\")) continue;\n\n const ext = name.split(\".\").pop()?.toLowerCase() ?? \"\";\n let mediaType = \"application/octet-stream\";\n if (ext === \"png\") mediaType = \"image/png\";\n else if (ext === \"jpg\" || ext === \"jpeg\") mediaType = \"image/jpeg\";\n else if (ext === \"gif\") mediaType = \"image/gif\";\n else if (ext === \"bmp\") mediaType = \"image/bmp\";\n else if (ext === \"svg\") mediaType = \"image/svg+xml\";\n else if (ext === \"webp\") mediaType = \"image/webp\";\n else if (ext === \"tif\" || ext === \"tiff\") mediaType = \"image/tiff\";\n else if (ext === \"emf\") mediaType = \"image/x-emf\";\n else if (ext === \"wmf\") mediaType = \"image/x-wmf\";\n\n try {\n const data = pkg.getPart(name);\n const base64 = uint8ToBase64(data);\n const dataUrl = `data:${mediaType};base64,${base64}`;\n\n // Store with the filename (e.g. \"image1.png\")\n const fileName = name.replace(\"BinData/\", \"\");\n images.set(fileName, dataUrl);\n // Also store without extension (e.g. \"image1\") to match binaryItemIDRef\n const baseName = fileName.replace(/\\.[^.]+$/, \"\");\n if (baseName !== fileName) {\n images.set(baseName, dataUrl);\n }\n } catch {\n // Skip parts that can't be read\n }\n }\n\n return images;\n}\n\nfunction uint8ToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]!);\n }\n return btoa(binary);\n}\n","/**\n * format-bridge.ts — Bridge between UI and @ubermensch1218/hwpxcore formatting APIs.\n *\n * Reads charPr / paraPr from the document and converts to UI-friendly formats.\n * Also provides methods to apply format changes back to the document.\n */\n\nimport type {\n HwpxDocument,\n HwpxOxmlParagraph,\n RunStyle,\n ParagraphProperty,\n Header,\n Style,\n} from \"@ubermensch1218/hwpxcore\";\nimport {\n parseHeaderXml,\n} from \"@ubermensch1218/hwpxcore\";\nimport { serializeXml } from \"@ubermensch1218/hwpxcore\";\nimport type { AlignmentType } from \"./constants\";\n\n// ── Read format types ──────────────────────────────────────────────────────\n\nexport interface CharFormat {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strikethrough: boolean;\n fontFamily: string | null;\n fontSize: number | null;\n textColor: string | null;\n highlightColor: string | null;\n letterSpacing: number | null;\n}\n\nexport interface ParaFormat {\n alignment: AlignmentType;\n lineSpacing: number;\n spacingBefore: number;\n spacingAfter: number;\n indentLeft: number;\n indentRight: number;\n firstLineIndent: number;\n}\n\n// ── Parse header to get paragraph properties ───────────────────────────────\n\nfunction getParsedHeader(doc: HwpxDocument): Header | null {\n const headers = doc.headers;\n if (headers.length === 0) return null;\n const headerEl = headers[0]!.element;\n try {\n const xml = serializeXml(headerEl);\n return parseHeaderXml(xml);\n } catch {\n return null;\n }\n}\n\n// ── Read character formatting from a run style ─────────────────────────────\n\nexport function readCharFormat(style: RunStyle | null, doc?: HwpxDocument | null): CharFormat {\n const result: CharFormat = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n fontFamily: null,\n fontSize: null,\n textColor: null,\n highlightColor: null,\n letterSpacing: null,\n };\n\n if (!style) return result;\n\n result.bold = style.attributes[\"bold\"] === \"1\";\n result.italic = style.attributes[\"italic\"] === \"1\";\n\n // Underline\n const underlineChild = style.childAttributes[\"underline\"];\n result.underline =\n underlineChild != null &&\n underlineChild[\"type\"] != null &&\n underlineChild[\"type\"] !== \"NONE\";\n\n // Strikethrough\n const strikeChild = style.childAttributes[\"strikeout\"];\n result.strikethrough =\n strikeChild != null &&\n strikeChild[\"type\"] != null &&\n strikeChild[\"type\"] !== \"NONE\";\n\n // Text color\n result.textColor = style.attributes[\"textColor\"] ?? null;\n\n // Highlight color\n result.highlightColor = style.attributes[\"shadeColor\"] ?? null;\n\n // Letter spacing\n const spacing = style.attributes[\"spacing\"];\n if (spacing) {\n const val = parseInt(spacing, 10);\n if (!isNaN(val)) result.letterSpacing = val;\n }\n\n // Font family — look in fontRef child, resolve numeric ID to face name\n const fontRef = style.childAttributes[\"fontRef\"];\n if (fontRef) {\n const hangulId = fontRef[\"hangul\"] ?? fontRef[\"latin\"] ?? null;\n if (hangulId != null && doc) {\n result.fontFamily = doc.fontFaceName(hangulId) ?? hangulId;\n } else {\n result.fontFamily = hangulId;\n }\n }\n\n // Font size\n const sizeStr = style.attributes[\"height\"];\n if (sizeStr) {\n // Height is in hwp units (1/7200 inch), convert to pt: hwpUnit / 100\n const hwpVal = parseInt(sizeStr, 10);\n if (!isNaN(hwpVal)) result.fontSize = hwpVal / 100;\n }\n\n return result;\n}\n\n// ── Read paragraph formatting ──────────────────────────────────────────────\n\nexport function readParaFormat(\n doc: HwpxDocument,\n paragraph: HwpxOxmlParagraph,\n): ParaFormat {\n const result: ParaFormat = {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n };\n\n const paraPrIdRef = paragraph.paraPrIdRef;\n if (!paraPrIdRef) return result;\n\n const header = getParsedHeader(doc);\n if (!header) return result;\n\n // Look up the paragraph property\n const paraPr = findParaPr(header, paraPrIdRef);\n if (!paraPr) return result;\n\n // Alignment\n if (paraPr.align?.horizontal) {\n const h = paraPr.align.horizontal.toUpperCase();\n if (\n h === \"LEFT\" || h === \"CENTER\" || h === \"RIGHT\" ||\n h === \"JUSTIFY\" || h === \"DISTRIBUTE\"\n ) {\n result.alignment = h as AlignmentType;\n }\n }\n\n // Line spacing\n if (paraPr.lineSpacing?.value != null) {\n const spacingType = paraPr.lineSpacing.spacingType?.toUpperCase();\n if (spacingType === \"PERCENT\" || spacingType === \"PROPORTIONAL\") {\n // Value is in percent (e.g., 160 = 1.6x)\n result.lineSpacing = paraPr.lineSpacing.value / 100;\n } else {\n // Fixed value in hwp units\n result.lineSpacing = paraPr.lineSpacing.value / 100;\n }\n }\n\n // Margins / indentation\n if (paraPr.margin) {\n if (paraPr.margin.left) {\n result.indentLeft = parseInt(paraPr.margin.left, 10) || 0;\n }\n if (paraPr.margin.right) {\n result.indentRight = parseInt(paraPr.margin.right, 10) || 0;\n }\n if (paraPr.margin.intent) {\n result.firstLineIndent = parseInt(paraPr.margin.intent, 10) || 0;\n }\n if (paraPr.margin.prev) {\n result.spacingBefore = parseInt(paraPr.margin.prev, 10) || 0;\n }\n if (paraPr.margin.next) {\n result.spacingAfter = parseInt(paraPr.margin.next, 10) || 0;\n }\n }\n\n return result;\n}\n\n// ── Helper: find paragraph property by ID ──────────────────────────────────\n\nfunction findParaPr(header: Header, paraPrIdRef: string): ParagraphProperty | null {\n if (!header.refList?.paraProperties) return null;\n for (const prop of header.refList.paraProperties.properties) {\n if (prop.rawId === paraPrIdRef) return prop;\n if (prop.id != null && String(prop.id) === paraPrIdRef) return prop;\n }\n return null;\n}\n\n// ── Read style info ────────────────────────────────────────────────────────\n\nexport function readStyleInfo(\n doc: HwpxDocument,\n paragraph: HwpxOxmlParagraph,\n): { styleName: string | null; styleId: string | null } {\n const styleIdRef = paragraph.styleIdRef;\n if (!styleIdRef) return { styleName: null, styleId: null };\n\n const header = getParsedHeader(doc);\n if (!header?.refList?.styles) return { styleName: null, styleId: null };\n\n for (const style of header.refList.styles.styles) {\n if (style.rawId === styleIdRef || (style.id != null && String(style.id) === styleIdRef)) {\n return { styleName: style.name, styleId: styleIdRef };\n }\n }\n\n return { styleName: null, styleId: styleIdRef };\n}\n\n// ── Get available styles from document ─────────────────────────────────────\n\nexport function getDocumentStyles(doc: HwpxDocument): Style[] {\n const header = getParsedHeader(doc);\n if (!header?.refList?.styles) return [];\n return header.refList.styles.styles;\n}\n\n// ── Read format from current selection ─────────────────────────────────────\n\nexport function readFormatFromSelection(\n doc: HwpxDocument,\n sectionIndex: number,\n paragraphIndex: number,\n): { char: CharFormat; para: ParaFormat } {\n const section = doc.sections[sectionIndex];\n if (!section) {\n return {\n char: readCharFormat(null),\n para: {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n },\n };\n }\n\n const paras = section.paragraphs;\n const para = paras[paragraphIndex];\n if (!para) {\n return {\n char: readCharFormat(null),\n para: {\n alignment: \"LEFT\",\n lineSpacing: 1.6,\n spacingBefore: 0,\n spacingAfter: 0,\n indentLeft: 0,\n indentRight: 0,\n firstLineIndent: 0,\n },\n };\n }\n\n // Character format: use the first run's style or the paragraph's charPrIdRef\n const runs = para.runs;\n let charStyle: RunStyle | null = null;\n if (runs.length > 0) {\n charStyle = runs[0]!.style;\n } else {\n const charPrIdRef = para.charPrIdRef;\n if (charPrIdRef) {\n charStyle = doc.charProperty(charPrIdRef);\n }\n }\n\n return {\n char: readCharFormat(charStyle, doc),\n para: readParaFormat(doc, para),\n };\n}\n","/**\n * Browser-side Skeleton.hwpx loader.\n * Fetches from /Skeleton.hwpx and calls setSkeletonHwpx() to register it.\n */\n\nimport { setSkeletonHwpx, HwpxDocument } from \"@ubermensch1218/hwpxcore\";\n\nlet loaded = false;\n\n/** Fetch Skeleton.hwpx from the public folder and register it with @ubermensch1218/hwpxcore. */\nexport async function ensureSkeletonLoaded(): Promise<void> {\n if (loaded) return;\n const res = await fetch(\"/Skeleton.hwpx\");\n if (!res.ok) throw new Error(`Failed to fetch Skeleton.hwpx: ${res.status}`);\n const buf = await res.arrayBuffer();\n setSkeletonHwpx(new Uint8Array(buf));\n loaded = true;\n}\n\n/** Create a new empty HwpxDocument from the skeleton template. */\nexport async function createNewDocument(): Promise<HwpxDocument> {\n await ensureSkeletonLoaded();\n const res = await fetch(\"/Skeleton.hwpx\");\n const buf = await res.arrayBuffer();\n return HwpxDocument.open(buf);\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\n\n// ── Menu data types ──────────────────────────────────────────────────────────\n\ninterface MenuItem {\n label: string;\n shortcut?: string;\n disabled?: boolean;\n dividerAfter?: boolean;\n action?: () => void;\n}\n\ninterface Menu {\n label: string;\n items: MenuItem[];\n}\n\n// ── MenuBar component ────────────────────────────────────────────────────────\n\nexport function MenuBar() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const [openMenu, setOpenMenu] = useState<number | null>(null);\n const barRef = useRef<HTMLDivElement>(null);\n\n const disabled = !doc;\n\n // Close menu on outside click\n useEffect(() => {\n if (openMenu === null) return;\n const handler = (e: MouseEvent) => {\n if (barRef.current && !barRef.current.contains(e.target as Node)) {\n setOpenMenu(null);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [openMenu]);\n\n // Close on Escape\n useEffect(() => {\n if (openMenu === null) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpenMenu(null);\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [openMenu]);\n\n const store = useEditorStore.getState;\n\n const menus: Menu[] = [\n {\n label: \"파일\",\n items: [\n { label: \"새 문서\", shortcut: \"Ctrl+N\", disabled: true },\n { label: \"불러오기...\", shortcut: \"Ctrl+O\", disabled: false, action: () => store().openFile(), dividerAfter: true },\n { label: \"저장\", shortcut: \"Ctrl+S\", disabled, action: () => store().openSaveDialog() },\n { label: \"다른 이름으로 저장...\", disabled, action: () => store().openSaveDialog(), dividerAfter: true },\n { label: \"문서 정보\", disabled: true },\n { label: \"인쇄...\", shortcut: \"Ctrl+P\", disabled: true },\n ],\n },\n {\n label: \"편집\",\n items: [\n { label: \"실행 취소\", shortcut: \"Ctrl+Z\", disabled, action: () => store().undo() },\n { label: \"다시 실행\", shortcut: \"Ctrl+Y\", disabled, action: () => store().redo(), dividerAfter: true },\n { label: \"오려두기\", shortcut: \"Ctrl+X\", action: () => document.execCommand(\"cut\") },\n { label: \"복사\", shortcut: \"Ctrl+C\", action: () => document.execCommand(\"copy\") },\n { label: \"붙이기\", shortcut: \"Ctrl+V\", action: () => document.execCommand(\"paste\"), dividerAfter: true },\n { label: \"모두 선택\", shortcut: \"Ctrl+A\", action: () => document.execCommand(\"selectAll\") },\n { label: \"찾기\", shortcut: \"Ctrl+F\", disabled: true },\n { label: \"찾아 바꾸기\", shortcut: \"Ctrl+H\", disabled: true },\n ],\n },\n {\n label: \"보기\",\n items: [\n { label: \"서식 사이드바\", action: () => store().toggleSidebar() },\n { label: \"눈금자\", disabled: true, dividerAfter: true },\n { label: \"확대\", shortcut: \"Ctrl++\", disabled: true },\n { label: \"축소\", shortcut: \"Ctrl+-\", disabled: true },\n { label: \"전체 화면\", shortcut: \"F11\", disabled: true },\n ],\n },\n {\n label: \"입력\",\n items: [\n { label: \"표...\", disabled: disabled || !selection, action: () => { /* handled via InsertGroup dialog */ } },\n { label: \"그림...\", disabled, action: () => { /* handled via InsertGroup file input */ } },\n { label: \"도형\", disabled: true },\n { label: \"차트\", disabled: true, dividerAfter: true },\n { label: \"문자표...\", shortcut: \"⌃F10\", disabled, action: () => store().openCharMapDialog(), dividerAfter: true },\n { label: \"각주\", shortcut: \"Ctrl+N,N\", disabled, action: () => store().insertFootnote() },\n { label: \"미주\", shortcut: \"Ctrl+N,E\", disabled, action: () => store().insertEndnote(), dividerAfter: true },\n { label: \"머리말/꼬리말...\", disabled: true },\n { label: \"쪽 번호...\", disabled: true, dividerAfter: true },\n { label: \"단 나누기\", disabled: disabled || !selection, action: () => store().insertColumnBreak() },\n { label: \"쪽 나누기\", disabled: disabled || !selection, action: () => store().insertPageBreak() },\n ],\n },\n {\n label: \"서식\",\n items: [\n { label: \"글자 모양...\", shortcut: \"⌘L\", disabled, action: () => store().openCharFormatDialog() },\n { label: \"문단 모양...\", shortcut: \"⌘T\", disabled, action: () => store().openParaFormatDialog(), dividerAfter: true },\n { label: \"문단 첫 글자 장식...\", disabled: true },\n { label: \"문단 번호 모양...\", disabled, action: () => store().openBulletNumberDialog() },\n { label: \"문단 번호 적용/해제\", disabled: true },\n { label: \"글머리표 적용/해제\", shortcut: \"⌃⇧⌫\", disabled, action: () => store().openBulletNumberDialog(), dividerAfter: true },\n { label: \"개요 번호 모양...\", disabled: true },\n { label: \"개요 적용/해제\", disabled: true },\n { label: \"한 수준 증가\", shortcut: \"⌃-\", disabled: true },\n { label: \"한 수준 감소\", shortcut: \"⌃+\", disabled: true, dividerAfter: true },\n { label: \"스타일...\", shortcut: \"F6\", disabled: true },\n ],\n },\n {\n label: \"쪽\",\n items: [\n { label: \"편집 용지...\", disabled, action: () => { store().setSidebarTab(\"page\"); if (!store().uiState.sidebarOpen) store().toggleSidebar(); } },\n { label: \"쪽 번호 매기기...\", disabled: true, dividerAfter: true },\n { label: \"머리말...\", disabled: true },\n { label: \"꼬리말...\", disabled: true, dividerAfter: true },\n { label: \"바탕쪽\", disabled: true },\n { label: \"워터마크...\", disabled, action: () => store().setWatermarkText(\"DRAFT\") },\n { label: \"워터마크 제거\", disabled, action: () => store().setWatermarkText(\"\") },\n ],\n },\n {\n label: \"도구\",\n items: [\n { label: \"맞춤법 검사...\", shortcut: \"F8\", disabled: true },\n { label: \"자동 고침...\", disabled: true, dividerAfter: true },\n { label: \"글자 수 세기\", disabled: true },\n { label: \"매크로...\", disabled: true },\n { label: \"환경 설정...\", disabled: true },\n ],\n },\n {\n label: \"표\",\n items: (() => {\n const noCell = disabled || selection?.tableIndex == null;\n const hasRange = !disabled && selection?.endRow != null && selection?.endCol != null;\n return [\n { label: \"표 속성...\", disabled: noCell, action: () => { store().setSidebarTab(\"table\"); if (!store().uiState.sidebarOpen) store().toggleSidebar(); } },\n { label: \"셀 합치기\", disabled: !hasRange, action: () => store().mergeTableCells() },\n { label: \"셀 나누기\", disabled: noCell, action: () => store().splitTableCell(), dividerAfter: true },\n { label: \"줄 삽입 (위)\", disabled: noCell, action: () => store().insertTableRow(\"above\") },\n { label: \"줄 삽입 (아래)\", disabled: noCell, action: () => store().insertTableRow(\"below\") },\n { label: \"칸 삽입 (왼쪽)\", disabled: noCell, action: () => store().insertTableColumn(\"left\") },\n { label: \"칸 삽입 (오른쪽)\", disabled: noCell, action: () => store().insertTableColumn(\"right\"), dividerAfter: true },\n { label: \"줄 삭제\", disabled: noCell, action: () => store().deleteTableRow() },\n { label: \"칸 삭제\", disabled: noCell, action: () => store().deleteTableColumn() },\n { label: \"표 삭제\", disabled: noCell, action: () => store().deleteTable() },\n ];\n })(),\n },\n ];\n\n const handleMenuClick = useCallback((menuIdx: number) => {\n setOpenMenu((prev) => (prev === menuIdx ? null : menuIdx));\n }, []);\n\n const handleItemClick = useCallback((item: MenuItem) => {\n if (item.disabled) return;\n item.action?.();\n setOpenMenu(null);\n }, []);\n\n return (\n <div ref={barRef} className=\"flex items-center bg-gray-50 border-b border-gray-200 text-xs select-none relative z-50\">\n {menus.map((menu, mIdx) => (\n <div key={menu.label} className=\"relative\">\n <button\n onClick={() => handleMenuClick(mIdx)}\n onMouseEnter={() => { if (openMenu !== null) setOpenMenu(mIdx); }}\n className={`px-3 py-1.5 transition-colors ${\n openMenu === mIdx\n ? \"bg-blue-100 text-blue-700\"\n : \"text-gray-700 hover:bg-gray-100\"\n }`}\n >\n {menu.label}\n </button>\n {openMenu === mIdx && (\n <div className=\"absolute left-0 top-full bg-white border border-gray-200 shadow-lg rounded-b min-w-[220px] py-1 z-50\">\n {menu.items.map((item, iIdx) => (\n <div key={iIdx}>\n <button\n onClick={() => handleItemClick(item)}\n disabled={item.disabled}\n className={`w-full text-left px-4 py-1.5 flex items-center justify-between gap-4 ${\n item.disabled\n ? \"text-gray-300 cursor-default\"\n : \"text-gray-700 hover:bg-blue-50 hover:text-blue-700\"\n }`}\n >\n <span>{item.label}</span>\n {item.shortcut && (\n <span className=\"text-[10px] text-gray-400 ml-4 flex-shrink-0\">{item.shortcut}</span>\n )}\n </button>\n {item.dividerAfter && <div className=\"border-t border-gray-100 my-0.5\" />}\n </div>\n ))}\n </div>\n )}\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { Clipboard, Copy, ClipboardPaste, Paintbrush } from \"lucide-react\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { RibbonGroup } from \"./RibbonGroup\";\n\nexport function ClipboardGroup() {\n return (\n <RibbonGroup label=\"클립보드\">\n <ToolbarButton\n icon={<Clipboard className=\"w-4 h-4\" />}\n label=\"잘라내기\"\n layout=\"vertical\"\n title=\"오려두기 (Ctrl+X)\"\n onClick={() => document.execCommand(\"cut\")}\n />\n <ToolbarButton\n icon={<Copy className=\"w-4 h-4\" />}\n label=\"복사\"\n layout=\"vertical\"\n title=\"복사 (Ctrl+C)\"\n onClick={() => document.execCommand(\"copy\")}\n />\n <ToolbarButton\n icon={<ClipboardPaste className=\"w-4 h-4\" />}\n label=\"붙이기\"\n layout=\"vertical\"\n title=\"붙이기 (Ctrl+V)\"\n onClick={() => document.execCommand(\"paste\")}\n />\n <ToolbarButton\n icon={<Paintbrush className=\"w-4 h-4\" />}\n label=\"모양복사\"\n layout=\"vertical\"\n title=\"모양 복사\"\n disabled\n />\n </RibbonGroup>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface ToolbarButtonProps {\n icon: ReactNode;\n label?: string;\n active?: boolean;\n disabled?: boolean;\n onClick?: () => void;\n title?: string;\n size?: \"sm\" | \"md\";\n layout?: \"horizontal\" | \"vertical\";\n className?: string;\n}\n\nexport function ToolbarButton({\n icon,\n label,\n active,\n disabled,\n onClick,\n title,\n size = \"sm\",\n layout = \"horizontal\",\n className = \"\",\n}: ToolbarButtonProps) {\n const sizeClass = size === \"md\" ? \"p-2\" : \"p-1.5\";\n const isVertical = layout === \"vertical\";\n return (\n <button\n disabled={disabled}\n onClick={onClick}\n title={title}\n className={`${sizeClass} rounded transition-colors flex ${\n isVertical ? \"flex-col items-center gap-0.5 px-2\" : \"items-center gap-1\"\n } ${\n active\n ? \"bg-blue-100 text-blue-700\"\n : \"text-gray-600 hover:bg-gray-100\"\n } disabled:opacity-40 disabled:cursor-not-allowed ${className}`}\n >\n {icon}\n {label && (\n <span className={isVertical ? \"text-[9px] leading-tight\" : \"text-xs\"}>\n {label}\n </span>\n )}\n </button>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface RibbonGroupProps {\n label: string;\n children: ReactNode;\n}\n\nexport function RibbonGroup({ label, children }: RibbonGroupProps) {\n return (\n <div className=\"flex flex-col items-center border-r border-gray-200 px-2 last:border-r-0\">\n <div className=\"flex items-center gap-0.5 py-1\">{children}</div>\n <span className=\"text-[10px] text-gray-400 pb-0.5\">{label}</span>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useRef, useState } from \"react\";\nimport { Table, BarChart3, Shapes, ImageIcon, Save, Columns, FileDown } from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { RibbonGroup } from \"./RibbonGroup\";\n\nexport function InsertGroup() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const addTable = useEditorStore((s) => s.addTable);\n const insertImage = useEditorStore((s) => s.insertImage);\n const insertColumnBreak = useEditorStore((s) => s.insertColumnBreak);\n const insertPageBreak = useEditorStore((s) => s.insertPageBreak);\n const saveDocument = useEditorStore((s) => s.saveDocument);\n const loading = useEditorStore((s) => s.loading);\n\n const [showTableDialog, setShowTableDialog] = useState(false);\n const [tableRows, setTableRows] = useState(3);\n const [tableCols, setTableCols] = useState(3);\n const imageInputRef = useRef<HTMLInputElement>(null);\n\n const disabled = !doc;\n\n const handleAddTable = useCallback(() => {\n if (!selection) return;\n addTable(selection.sectionIndex, selection.paragraphIndex, tableRows, tableCols);\n setShowTableDialog(false);\n }, [selection, tableRows, tableCols, addTable]);\n\n const handleImageSelect = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n\n const img = new window.Image();\n const url = URL.createObjectURL(file);\n img.onload = () => {\n const widthMm = (img.naturalWidth / 96) * 25.4;\n const heightMm = (img.naturalHeight / 96) * 25.4;\n insertImage(data, file.type, widthMm, heightMm);\n URL.revokeObjectURL(url);\n };\n img.src = url;\n e.target.value = \"\";\n },\n [insertImage],\n );\n\n return (\n <>\n <RibbonGroup label=\"삽입\">\n <ToolbarButton\n icon={<Table className=\"w-4 h-4\" />}\n label=\"표\"\n layout=\"vertical\"\n title=\"표 삽입\"\n disabled={disabled || !selection}\n onClick={() => setShowTableDialog(true)}\n />\n <ToolbarButton\n icon={<BarChart3 className=\"w-4 h-4\" />}\n label=\"차트\"\n layout=\"vertical\"\n title=\"차트 삽입\"\n disabled\n />\n <ToolbarButton\n icon={<Shapes className=\"w-4 h-4\" />}\n label=\"도형\"\n layout=\"vertical\"\n title=\"도형 삽입\"\n disabled\n />\n <ToolbarButton\n icon={<ImageIcon className=\"w-4 h-4\" />}\n label=\"그림\"\n layout=\"vertical\"\n title=\"그림 삽입\"\n disabled={disabled}\n onClick={() => imageInputRef.current?.click()}\n />\n <input\n ref={imageInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={handleImageSelect}\n />\n <ToolbarButton\n icon={<Columns className=\"w-4 h-4\" />}\n label=\"단\"\n layout=\"vertical\"\n title=\"단 나누기\"\n disabled={disabled || !selection}\n onClick={() => insertColumnBreak()}\n />\n <ToolbarButton\n icon={<FileDown className=\"w-4 h-4\" />}\n label=\"쪽\"\n layout=\"vertical\"\n title=\"쪽 나누기\"\n disabled={disabled || !selection}\n onClick={() => insertPageBreak()}\n />\n </RibbonGroup>\n\n <RibbonGroup label=\"파일\">\n <ToolbarButton\n icon={<Save className=\"w-4 h-4\" />}\n label=\"저장\"\n layout=\"vertical\"\n title=\"저장 (Ctrl+S)\"\n disabled={disabled || loading}\n onClick={() => saveDocument()}\n />\n </RibbonGroup>\n\n {/* Table dialog */}\n {showTableDialog && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/30\">\n <div className=\"bg-white rounded-lg shadow-xl p-6 min-w-[280px]\">\n <h3 className=\"font-semibold mb-4\">표 삽입</h3>\n <div className=\"flex gap-4 mb-4\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-gray-600\">행</span>\n <input\n type=\"number\"\n min={1}\n max={50}\n value={tableRows}\n onChange={(e) => setTableRows(Number(e.target.value))}\n className=\"border rounded px-2 py-1 w-20\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-gray-600\">열</span>\n <input\n type=\"number\"\n min={1}\n max={20}\n value={tableCols}\n onChange={(e) => setTableCols(Number(e.target.value))}\n className=\"border rounded px-2 py-1 w-20\"\n />\n </label>\n </div>\n <div className=\"flex justify-end gap-2\">\n <button\n onClick={() => setShowTableDialog(false)}\n className=\"px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded\"\n >\n 취소\n </button>\n <button\n onClick={handleAddTable}\n className=\"px-4 py-2 text-sm bg-blue-500 text-white rounded hover:bg-blue-600\"\n >\n 삽입\n </button>\n </div>\n </div>\n </div>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { ClipboardGroup } from \"./ClipboardGroup\";\nimport { InsertGroup } from \"./InsertGroup\";\n\nexport function RibbonToolbar() {\n return (\n <div className=\"flex items-stretch bg-white border-b border-gray-200 px-1 min-h-[52px]\">\n <ClipboardGroup />\n <InsertGroup />\n </div>\n );\n}\n","/**\n * Constants for the HWPX editor UI — font lists, style presets, alignment/spacing options.\n */\n\n// ── Korean font families ───────────────────────────────────────────────────\n\nexport const FONT_FAMILIES = [\n \"맑은 고딕\",\n \"함초롬돋움\",\n \"함초롬바탕\",\n \"나눔고딕\",\n \"나눔명조\",\n \"나눔바른고딕\",\n \"Noto Sans KR\",\n \"Noto Serif KR\",\n \"교보손글씨 2024 박서우\",\n \"교보손글씨 2023 우선아\",\n \"학교안심 알림장\",\n \"바탕\",\n \"돋움\",\n \"굴림\",\n \"궁서\",\n \"Arial\",\n \"Times New Roman\",\n \"Courier New\",\n \"Verdana\",\n \"Georgia\",\n] as const;\n\nexport type FontFamily = (typeof FONT_FAMILIES)[number];\n\n// ── Font sizes ─────────────────────────────────────────────────────────────\n\nexport const FONT_SIZES = [\n 8, 9, 10, 10.5, 11, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 48, 72,\n] as const;\n\n// ── Paragraph styles ───────────────────────────────────────────────────────\n\nexport interface StylePreset {\n id: string;\n name: string;\n engName: string;\n}\n\nexport const STYLE_PRESETS: StylePreset[] = [\n { id: \"0\", name: \"바탕글\", engName: \"Normal\" },\n { id: \"1\", name: \"본문\", engName: \"Body\" },\n { id: \"2\", name: \"개요 1\", engName: \"Outline 1\" },\n { id: \"3\", name: \"개요 2\", engName: \"Outline 2\" },\n { id: \"4\", name: \"개요 3\", engName: \"Outline 3\" },\n { id: \"5\", name: \"쪽 번호\", engName: \"Page Number\" },\n { id: \"6\", name: \"머리말\", engName: \"Header\" },\n { id: \"7\", name: \"꼬리말\", engName: \"Footer\" },\n { id: \"8\", name: \"각주\", engName: \"Footnote\" },\n { id: \"9\", name: \"미주\", engName: \"Endnote\" },\n];\n\n// ── Alignment ──────────────────────────────────────────────────────────────\n\nexport type AlignmentType = \"LEFT\" | \"CENTER\" | \"RIGHT\" | \"JUSTIFY\" | \"DISTRIBUTE\";\n\nexport interface AlignmentOption {\n value: AlignmentType;\n label: string;\n shortcut?: string;\n}\n\nexport const ALIGNMENT_OPTIONS: AlignmentOption[] = [\n { value: \"LEFT\", label: \"왼쪽 정렬\", shortcut: \"Ctrl+L\" },\n { value: \"CENTER\", label: \"가운데 정렬\", shortcut: \"Ctrl+E\" },\n { value: \"RIGHT\", label: \"오른쪽 정렬\", shortcut: \"Ctrl+R\" },\n { value: \"JUSTIFY\", label: \"양쪽 정렬\", shortcut: \"Ctrl+J\" },\n { value: \"DISTRIBUTE\", label: \"배분 정렬\" },\n];\n\n// ── Line spacing ───────────────────────────────────────────────────────────\n\nexport interface LineSpacingOption {\n value: number;\n label: string;\n}\n\nexport const LINE_SPACING_OPTIONS: LineSpacingOption[] = [\n { value: 1.0, label: \"1.0\" },\n { value: 1.15, label: \"1.15\" },\n { value: 1.5, label: \"1.5\" },\n { value: 1.6, label: \"1.6\" },\n { value: 2.0, label: \"2.0\" },\n { value: 2.5, label: \"2.5\" },\n { value: 3.0, label: \"3.0\" },\n];\n\n// ── Underline types ────────────────────────────────────────────────────────\n\nexport const UNDERLINE_TYPES = [\n \"NONE\",\n \"SOLID\",\n \"DASH\",\n \"DOT\",\n \"DASH_DOT\",\n \"DASH_DOT_DOT\",\n \"LONG_DASH\",\n \"DOUBLE\",\n \"WAVE\",\n \"HEAVY_WAVE\",\n \"DOUBLE_WAVE\",\n] as const;\n\n// ── Color presets ──────────────────────────────────────────────────────────\n\nexport const COLOR_PRESETS = [\n // Row 1: Primary colors\n \"#000000\", \"#333333\", \"#555555\", \"#777777\", \"#999999\", \"#BBBBBB\", \"#DDDDDD\", \"#FFFFFF\",\n // Row 2: Vivid colors\n \"#FF0000\", \"#FF6600\", \"#FFCC00\", \"#33CC33\", \"#0099FF\", \"#3366FF\", \"#6633CC\", \"#CC33CC\",\n // Row 3: Pastel colors\n \"#FF9999\", \"#FFCC99\", \"#FFFF99\", \"#CCFFCC\", \"#99CCFF\", \"#9999FF\", \"#CC99FF\", \"#FF99CC\",\n // Row 4: Dark colors\n \"#CC0000\", \"#CC6600\", \"#CC9900\", \"#009900\", \"#006699\", \"#003399\", \"#330099\", \"#990066\",\n] as const;\n\n// ── Highlight colors ───────────────────────────────────────────────────────\n\nexport const HIGHLIGHT_COLORS = [\n { value: \"#FFFF00\", label: \"노랑\" },\n { value: \"#00FF00\", label: \"연두\" },\n { value: \"#00FFFF\", label: \"하늘\" },\n { value: \"#FF00FF\", label: \"분홍\" },\n { value: \"#0000FF\", label: \"파랑\" },\n { value: \"#FF0000\", label: \"빨강\" },\n { value: \"#008000\", label: \"초록\" },\n { value: \"#800080\", label: \"보라\" },\n { value: \"#808080\", label: \"회색\" },\n { value: \"none\", label: \"없음\" },\n] as const;\n\n// ── Page size presets ─────────────────────────────────────────────────────\n\nexport const PAGE_SIZE_PRESETS = [\n { name: \"A4(국배판) [210x297mm]\", width: 210, height: 297 },\n { name: \"A3 [297x420mm]\", width: 297, height: 420 },\n { name: \"B4 [257x364mm]\", width: 257, height: 364 },\n { name: \"B5(국판) [182x257mm]\", width: 182, height: 257 },\n { name: \"Letter [216x279mm]\", width: 216, height: 279 },\n { name: \"Legal [216x356mm]\", width: 216, height: 356 },\n] as const;\n\nexport type OrientationType = \"PORTRAIT\" | \"LANDSCAPE\";\nexport type BindingType = \"LEFT\" | \"FACING\" | \"TOP\";\n\n// ── Sidebar tabs ───────────────────────────────────────────────────────────\n\nexport type SidebarTab = \"char\" | \"para\" | \"page\" | \"img-layout\" | \"img-props\" | \"table\" | \"cell\";\n","\"use client\";\n\nimport { useState, useRef, useEffect, type ReactNode } from \"react\";\n\ninterface ToolbarDropdownProps {\n value: string;\n options: { value: string; label: string }[];\n onChange: (value: string) => void;\n disabled?: boolean;\n title?: string;\n className?: string;\n width?: string;\n icon?: ReactNode;\n}\n\nexport function ToolbarDropdown({\n value,\n options,\n onChange,\n disabled,\n title,\n className = \"\",\n width = \"w-28\",\n icon,\n}: ToolbarDropdownProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n const selectedLabel = options.find((o) => o.value === value)?.label ?? value;\n\n return (\n <div ref={ref} className={`relative ${className}`} title={title}>\n <button\n disabled={disabled}\n onClick={() => setOpen(!open)}\n className={`flex items-center gap-1 ${width} h-7 px-2 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-left disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {icon}\n <span className=\"flex-1 truncate\">{selectedLabel}</span>\n <svg className=\"w-3 h-3 text-gray-400 flex-shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded shadow-lg max-h-64 overflow-auto min-w-full\">\n {options.map((opt) => (\n <button\n key={opt.value}\n onClick={() => {\n onChange(opt.value);\n setOpen(false);\n }}\n className={`block w-full text-left px-3 py-1.5 text-xs hover:bg-blue-50 ${\n opt.value === value ? \"bg-blue-50 text-blue-700 font-medium\" : \"text-gray-700\"\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { STYLE_PRESETS } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\ninterface StyleSelectorProps {\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\nexport function StyleSelector({ value, onChange, disabled }: StyleSelectorProps) {\n const options = STYLE_PRESETS.map((s) => ({\n value: s.id,\n label: s.name,\n }));\n\n return (\n <ToolbarDropdown\n value={value}\n options={options}\n onChange={onChange}\n disabled={disabled}\n title=\"스타일\"\n width=\"w-24\"\n />\n );\n}\n","\"use client\";\n\nimport { FONT_FAMILIES } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\ninterface FontSelectorProps {\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\nexport function FontSelector({ value, onChange, disabled }: FontSelectorProps) {\n const options = FONT_FAMILIES.map((f) => ({\n value: f,\n label: f,\n }));\n\n return (\n <ToolbarDropdown\n value={value}\n options={options}\n onChange={onChange}\n disabled={disabled}\n title=\"글꼴\"\n width=\"w-32\"\n />\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { FONT_SIZES } from \"@/lib/constants\";\n\ninterface FontSizeInputProps {\n value: number;\n onChange: (value: number) => void;\n disabled?: boolean;\n}\n\nexport function FontSizeInput({ value, onChange, disabled }: FontSizeInputProps) {\n const [editing, setEditing] = useState(false);\n const [inputValue, setInputValue] = useState(String(value));\n\n const handleBlur = useCallback(() => {\n setEditing(false);\n const num = parseFloat(inputValue);\n if (!isNaN(num) && num > 0 && num <= 200) {\n onChange(num);\n } else {\n setInputValue(String(value));\n }\n }, [inputValue, value, onChange]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n (e.target as HTMLInputElement).blur();\n } else if (e.key === \"Escape\") {\n setInputValue(String(value));\n setEditing(false);\n }\n },\n [value],\n );\n\n if (editing) {\n return (\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n autoFocus\n className=\"w-14 h-7 px-2 text-xs border border-blue-400 rounded text-center focus:outline-none\"\n />\n );\n }\n\n return (\n <div className=\"relative\">\n <select\n value={String(value)}\n onChange={(e) => {\n const num = parseFloat(e.target.value);\n if (!isNaN(num)) onChange(num);\n }}\n disabled={disabled}\n className=\"w-14 h-7 px-1 text-xs border border-gray-300 rounded bg-white text-center appearance-none cursor-pointer disabled:opacity-40\"\n title=\"글자 크기\"\n onDoubleClick={() => {\n setInputValue(String(value));\n setEditing(true);\n }}\n >\n {FONT_SIZES.map((s) => (\n <option key={s} value={String(s)}>\n {s}\n </option>\n ))}\n {!FONT_SIZES.includes(value as any) && (\n <option value={String(value)}>{value}</option>\n )}\n </select>\n </div>\n );\n}\n","\"use client\";\n\nimport {\n Bold,\n Italic,\n Underline,\n Strikethrough,\n Highlighter,\n Type,\n} from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport { ColorPicker } from \"./ColorPicker\";\n\nexport function CharFormatButtons() {\n const activeFormat = useEditorStore((s) => s.activeFormat);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const selection = useEditorStore((s) => s.selection);\n const doc = useEditorStore((s) => s.doc);\n const toggleBold = useEditorStore((s) => s.toggleBold);\n const toggleItalic = useEditorStore((s) => s.toggleItalic);\n const toggleUnderline = useEditorStore((s) => s.toggleUnderline);\n const toggleStrikethrough = useEditorStore((s) => s.toggleStrikethrough);\n const setTextColor = useEditorStore((s) => s.setTextColor);\n const setHighlightColor = useEditorStore((s) => s.setHighlightColor);\n\n const disabled = !doc || !selection;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <ColorPicker\n color={extendedFormat.char.textColor || \"#000000\"}\n onChange={(c) => setTextColor(c)}\n icon={<Type className=\"w-3.5 h-3.5\" />}\n title=\"글자색\"\n disabled={disabled}\n />\n <ColorPicker\n color={extendedFormat.char.highlightColor || \"#FFFF00\"}\n onChange={(c) => setHighlightColor(c)}\n icon={<Highlighter className=\"w-3.5 h-3.5\" />}\n title=\"형광펜\"\n disabled={disabled}\n />\n <ToolbarButton\n icon={<Bold className=\"w-3.5 h-3.5\" />}\n active={activeFormat.bold}\n disabled={disabled}\n onClick={toggleBold}\n title=\"굵게 (Ctrl+B)\"\n />\n <ToolbarButton\n icon={<Italic className=\"w-3.5 h-3.5\" />}\n active={activeFormat.italic}\n disabled={disabled}\n onClick={toggleItalic}\n title=\"기울임 (Ctrl+I)\"\n />\n <ToolbarButton\n icon={<Underline className=\"w-3.5 h-3.5\" />}\n active={activeFormat.underline}\n disabled={disabled}\n onClick={toggleUnderline}\n title=\"밑줄 (Ctrl+U)\"\n />\n <ToolbarButton\n icon={<Strikethrough className=\"w-3.5 h-3.5\" />}\n active={activeFormat.strikethrough}\n disabled={disabled}\n onClick={toggleStrikethrough}\n title=\"취소선 (Ctrl+D)\"\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, type ReactNode } from \"react\";\nimport { COLOR_PRESETS } from \"@/lib/constants\";\n\ninterface ColorPickerProps {\n color: string;\n onChange: (color: string) => void;\n icon: ReactNode;\n title?: string;\n disabled?: boolean;\n}\n\nexport function ColorPicker({\n color,\n onChange,\n icon,\n title,\n disabled,\n}: ColorPickerProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n disabled={disabled}\n onClick={() => setOpen(!open)}\n title={title}\n className=\"p-1.5 rounded transition-colors text-gray-600 hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed flex flex-col items-center\"\n >\n {icon}\n <div\n className=\"w-4 h-0.5 mt-0.5 rounded-sm\"\n style={{ backgroundColor: color || \"#000000\" }}\n />\n </button>\n {open && (\n <div className=\"absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-lg p-2\">\n <div className=\"grid grid-cols-8 gap-1\">\n {COLOR_PRESETS.map((c) => (\n <button\n key={c}\n onClick={() => {\n onChange(c);\n setOpen(false);\n }}\n className={`w-5 h-5 rounded border ${\n c === color ? \"border-blue-500 ring-1 ring-blue-300\" : \"border-gray-300\"\n } hover:scale-110 transition-transform`}\n style={{ backgroundColor: c }}\n title={c}\n />\n ))}\n </div>\n <div className=\"mt-2 pt-2 border-t border-gray-100 flex items-center gap-2\">\n <label className=\"text-xs text-gray-500\">커스텀:</label>\n <input\n type=\"color\"\n value={color && color !== \"none\" ? color : \"#000000\"}\n onChange={(e) => {\n onChange(e.target.value);\n setOpen(false);\n }}\n className=\"w-6 h-6 cursor-pointer border-0\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport {\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n Columns2,\n} from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ToolbarButton } from \"./ToolbarButton\";\nimport type { AlignmentType } from \"@/lib/constants\";\n\nconst ALIGNMENT_ICONS: Record<AlignmentType, React.ReactNode> = {\n LEFT: <AlignLeft className=\"w-3.5 h-3.5\" />,\n CENTER: <AlignCenter className=\"w-3.5 h-3.5\" />,\n RIGHT: <AlignRight className=\"w-3.5 h-3.5\" />,\n JUSTIFY: <AlignJustify className=\"w-3.5 h-3.5\" />,\n DISTRIBUTE: <Columns2 className=\"w-3.5 h-3.5\" />,\n};\n\nconst ALIGNMENT_LABELS: Record<AlignmentType, string> = {\n LEFT: \"왼쪽 정렬 (Ctrl+L)\",\n CENTER: \"가운데 정렬 (Ctrl+E)\",\n RIGHT: \"오른쪽 정렬 (Ctrl+R)\",\n JUSTIFY: \"양쪽 정렬 (Ctrl+J)\",\n DISTRIBUTE: \"배분 정렬\",\n};\n\nexport function AlignmentButtons() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setAlignment = useEditorStore((s) => s.setAlignment);\n\n const disabled = !doc || !selection;\n const currentAlignment = extendedFormat.para.alignment;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n {(Object.keys(ALIGNMENT_ICONS) as AlignmentType[]).map((align) => (\n <ToolbarButton\n key={align}\n icon={ALIGNMENT_ICONS[align]}\n active={currentAlignment === align}\n disabled={disabled}\n onClick={() => setAlignment(align)}\n title={ALIGNMENT_LABELS[align]}\n />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { LINE_SPACING_OPTIONS } from \"@/lib/constants\";\nimport { ToolbarDropdown } from \"./ToolbarDropdown\";\n\nexport function LineSpacingControl() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setLineSpacing = useEditorStore((s) => s.setLineSpacing);\n\n const disabled = !doc || !selection;\n const currentSpacing = extendedFormat.para.lineSpacing;\n\n // Find closest matching option\n const closestValue = LINE_SPACING_OPTIONS.reduce((prev, curr) =>\n Math.abs(curr.value - currentSpacing) < Math.abs(prev.value - currentSpacing)\n ? curr\n : prev,\n ).value;\n\n const options = LINE_SPACING_OPTIONS.map((o) => ({\n value: String(o.value),\n label: o.label,\n }));\n\n return (\n <ToolbarDropdown\n value={String(closestValue)}\n options={options}\n onChange={(val) => setLineSpacing(Number(val))}\n disabled={disabled}\n title=\"줄 간격\"\n width=\"w-14\"\n />\n );\n}\n","\"use client\";\n\nexport function ToolbarDivider() {\n return <div className=\"h-6 w-px bg-gray-200 mx-1 self-center\" />;\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { StyleSelector } from \"./StyleSelector\";\nimport { FontSelector } from \"./FontSelector\";\nimport { FontSizeInput } from \"./FontSizeInput\";\nimport { CharFormatButtons } from \"./CharFormatButtons\";\nimport { AlignmentButtons } from \"./AlignmentButtons\";\nimport { LineSpacingControl } from \"./LineSpacingControl\";\nimport { ToolbarDivider } from \"./ToolbarDivider\";\nimport { Plus } from \"lucide-react\";\n\nexport function SecondaryToolbar() {\n const doc = useEditorStore((s) => s.doc);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const addParagraph = useEditorStore((s) => s.addParagraph);\n\n const disabled = !doc;\n\n return (\n <div className=\"flex items-center gap-1 bg-gray-50 border-b border-gray-200 px-3 py-1 flex-wrap min-h-[36px]\">\n {/* Style selector */}\n <StyleSelector\n value=\"0\"\n onChange={() => {\n // Style change — placeholder\n }}\n disabled={disabled}\n />\n\n <ToolbarDivider />\n\n {/* Font selector */}\n <FontSelector\n value={extendedFormat.char.fontFamily || \"맑은 고딕\"}\n onChange={() => {\n // Font change — placeholder\n }}\n disabled={disabled}\n />\n\n {/* Font size */}\n <FontSizeInput\n value={extendedFormat.char.fontSize || 10}\n onChange={() => {\n // Font size change — placeholder\n }}\n disabled={disabled}\n />\n\n <ToolbarDivider />\n\n {/* Character format buttons */}\n <CharFormatButtons />\n\n <ToolbarDivider />\n\n {/* Alignment buttons */}\n <AlignmentButtons />\n\n <ToolbarDivider />\n\n {/* Line spacing */}\n <LineSpacingControl />\n\n {/* Spacer */}\n <div className=\"flex-1\" />\n\n {/* Add paragraph */}\n <button\n disabled={disabled}\n onClick={() => addParagraph(\"\")}\n className=\"flex items-center gap-1 px-2.5 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n <Plus className=\"w-3 h-3\" />\n 문단 추가\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback, useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { pxToHwp } from \"@/lib/hwp-units\";\n\n// ── Indent drag handle components ─────────────────────────────────────────\n\ninterface HandleProps {\n /** Offset from left edge of content area in px */\n positionPx: number;\n onDrag: (deltaPx: number) => void;\n}\n\n/** ▽ First-line indent handle (top triangle) */\nfunction FirstLineHandle({ positionPx, onDrag }: HandleProps) {\n const startXRef = useRef(0);\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n const onMove = (me: MouseEvent) => {\n /* visual-only during drag; commit on up */\n };\n const onUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n const delta = me.clientX - startXRef.current;\n if (Math.abs(delta) >= 2) onDrag(delta);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"ew-resize\";\n },\n [onDrag],\n );\n\n return (\n <div\n className=\"absolute cursor-ew-resize select-none\"\n style={{ left: positionPx - 5, top: 0 }}\n onMouseDown={onMouseDown}\n title=\"첫줄 들여쓰기\"\n >\n <svg width=\"10\" height=\"8\" viewBox=\"0 0 10 8\">\n <polygon points=\"5,8 0,0 10,0\" fill=\"#4A90D9\" />\n </svg>\n </div>\n );\n}\n\n/** △ Left indent handle (bottom triangle) */\nfunction LeftIndentHandle({ positionPx, onDrag }: HandleProps) {\n const startXRef = useRef(0);\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n const onMove = (me: MouseEvent) => {};\n const onUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n const delta = me.clientX - startXRef.current;\n if (Math.abs(delta) >= 2) onDrag(delta);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"ew-resize\";\n },\n [onDrag],\n );\n\n return (\n <div\n className=\"absolute cursor-ew-resize select-none\"\n style={{ left: positionPx - 5, bottom: 0 }}\n onMouseDown={onMouseDown}\n title=\"둘째줄 시작 위치 (왼쪽 들여쓰기)\"\n >\n <svg width=\"10\" height=\"8\" viewBox=\"0 0 10 8\">\n <polygon points=\"5,0 10,8 0,8\" fill=\"#4A90D9\" />\n </svg>\n </div>\n );\n}\n\n/** □ Combined margin handle (bottom rectangle, moves both) */\nfunction CombinedHandle({ positionPx, onDrag }: HandleProps) {\n const startXRef = useRef(0);\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n const onMove = (me: MouseEvent) => {};\n const onUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n const delta = me.clientX - startXRef.current;\n if (Math.abs(delta) >= 2) onDrag(delta);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"ew-resize\";\n },\n [onDrag],\n );\n\n return (\n <div\n className=\"absolute cursor-ew-resize select-none\"\n style={{ left: positionPx - 4, bottom: 8 }}\n onMouseDown={onMouseDown}\n title=\"왼쪽 여백 전체 이동\"\n >\n <svg width=\"8\" height=\"6\" viewBox=\"0 0 8 6\">\n <rect x=\"0\" y=\"0\" width=\"8\" height=\"6\" fill=\"#4A90D9\" rx=\"1\" />\n </svg>\n </div>\n );\n}\n\n// ── Main ruler ────────────────────────────────────────────────────────────\n\nexport function HorizontalRuler() {\n const viewModel = useEditorStore((s) => s.viewModel);\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const selection = useEditorStore((s) => s.selection);\n const setFirstLineIndent = useEditorStore((s) => s.setFirstLineIndent);\n const setLeftIndent = useEditorStore((s) => s.setLeftIndent);\n\n if (!viewModel || viewModel.sections.length === 0) return null;\n\n const section = viewModel.sections[0]!;\n const pageWidthPx = section.pageWidthPx;\n const marginLeftPx = section.marginLeftPx;\n const marginRightPx = section.marginRightPx;\n const contentWidthPx = pageWidthPx - marginLeftPx - marginRightPx;\n\n // Current indent values (hwpUnits) from extended format\n const firstLineIndentHwp = extendedFormat.para.firstLineIndent;\n const leftIndentHwp = extendedFormat.para.indentLeft;\n\n // Convert to px for handle positioning\n const firstLineIndentPx = (firstLineIndentHwp * 96) / 7200;\n const leftIndentPx = (leftIndentHwp * 96) / 7200;\n\n // Generate tick marks in mm (every 1mm tick, every 10mm major)\n const mmPerPx = 25.4 / 96; // px to mm\n const totalMm = contentWidthPx * mmPerPx;\n const ticks: { position: number; label: string; major: boolean; medium: boolean }[] = [];\n\n for (let mm = 0; mm <= totalMm + 0.5; mm += 1) {\n const px = mm / mmPerPx;\n const major = mm % 10 === 0;\n const medium = mm % 5 === 0 && !major;\n ticks.push({\n position: px,\n label: major ? String(Math.round(mm / 10)) : \"\",\n major,\n medium,\n });\n }\n\n const hasSelection = !!selection;\n\n const handleFirstLineDrag = useCallback(\n (deltaPx: number) => {\n const deltaHwp = pxToHwp(deltaPx);\n setFirstLineIndent(firstLineIndentHwp + deltaHwp);\n },\n [firstLineIndentHwp, setFirstLineIndent],\n );\n\n const handleLeftIndentDrag = useCallback(\n (deltaPx: number) => {\n const deltaHwp = pxToHwp(deltaPx);\n setLeftIndent(leftIndentHwp + deltaHwp);\n },\n [leftIndentHwp, setLeftIndent],\n );\n\n const handleCombinedDrag = useCallback(\n (deltaPx: number) => {\n const deltaHwp = pxToHwp(deltaPx);\n // Move both, keeping relative position\n setLeftIndent(leftIndentHwp + deltaHwp);\n // firstLineIndent moves with left indent (same delta)\n setTimeout(() => {\n setFirstLineIndent(firstLineIndentHwp + deltaHwp);\n }, 0);\n },\n [firstLineIndentHwp, leftIndentHwp, setFirstLineIndent, setLeftIndent],\n );\n\n return (\n <div className=\"bg-white border-b border-gray-200 overflow-hidden flex-shrink-0\">\n <div className=\"flex justify-center\">\n <div\n className=\"relative\"\n style={{ width: pageWidthPx, height: 28 }}\n >\n {/* Left margin area */}\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{ width: marginLeftPx }}\n />\n {/* Right margin area */}\n <div\n className=\"absolute top-0 right-0 h-full bg-gray-100\"\n style={{ width: marginRightPx }}\n />\n {/* Ruler content area with ticks */}\n <div\n className=\"absolute top-0 h-full\"\n style={{ left: marginLeftPx, width: contentWidthPx }}\n >\n {ticks.map((tick, i) => (\n <div\n key={i}\n className=\"absolute bottom-0\"\n style={{ left: tick.position }}\n >\n <div\n className={`w-px ${\n tick.major\n ? \"h-3 bg-gray-500\"\n : tick.medium\n ? \"h-2 bg-gray-400\"\n : \"h-1 bg-gray-300\"\n }`}\n />\n {tick.label && (\n <span className=\"absolute -top-0.5 left-1/2 -translate-x-1/2 text-[8px] text-gray-400 leading-none select-none\">\n {tick.label}\n </span>\n )}\n </div>\n ))}\n\n {/* Indent handles (only shown when a paragraph is selected) */}\n {hasSelection && (\n <>\n <FirstLineHandle\n positionPx={leftIndentPx + firstLineIndentPx}\n onDrag={handleFirstLineDrag}\n />\n <LeftIndentHandle\n positionPx={leftIndentPx}\n onDrag={handleLeftIndentDrag}\n />\n <CombinedHandle\n positionPx={leftIndentPx}\n onDrag={handleCombinedDrag}\n />\n </>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport type { SidebarTab } from \"@/lib/constants\";\nimport { CharFormatPanel } from \"./CharFormatPanel\";\nimport { ParaFormatPanel } from \"./ParaFormatPanel\";\nimport { PageSetupPanel } from \"./PageSetupPanel\";\nimport { ImageLayoutPanel } from \"./ImageLayoutPanel\";\nimport { ImagePropertiesPanel } from \"./ImagePropertiesPanel\";\nimport { TablePropertiesPanel } from \"./TablePropertiesPanel\";\nimport { CellPropertiesPanel } from \"./CellPropertiesPanel\";\nimport { PanelRightClose } from \"lucide-react\";\n\ntype SidebarContext = \"text\" | \"image\" | \"table\";\n\nfunction getContext(selection: { objectType?: string; type?: string } | null): SidebarContext {\n if (selection?.objectType === \"image\") return \"image\";\n if (selection?.objectType === \"table\" || selection?.type === \"cell\") return \"table\";\n return \"text\";\n}\n\nconst TEXT_TABS: { tab: SidebarTab; label: string }[] = [\n { tab: \"char\", label: \"글자 모양\" },\n { tab: \"para\", label: \"문단 모양\" },\n { tab: \"page\", label: \"편집 용지\" },\n];\n\nconst IMAGE_TABS: { tab: SidebarTab; label: string }[] = [\n { tab: \"img-layout\", label: \"배치\" },\n { tab: \"img-props\", label: \"그림\" },\n];\n\nconst TABLE_TABS: { tab: SidebarTab; label: string }[] = [\n { tab: \"table\", label: \"표\" },\n { tab: \"cell\", label: \"셀\" },\n];\n\nexport function FormatSidebar() {\n const uiState = useEditorStore((s) => s.uiState);\n const selection = useEditorStore((s) => s.selection);\n const setSidebarTab = useEditorStore((s) => s.setSidebarTab);\n const toggleSidebar = useEditorStore((s) => s.toggleSidebar);\n\n const context = getContext(selection);\n\n const tabs =\n context === \"image\" ? IMAGE_TABS :\n context === \"table\" ? TABLE_TABS :\n TEXT_TABS;\n\n // Auto-switch to first tab of current context when context changes\n useEffect(() => {\n const validTabs = tabs.map((t) => t.tab);\n if (!validTabs.includes(uiState.sidebarTab)) {\n setSidebarTab(validTabs[0]!);\n }\n }, [context]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!uiState.sidebarOpen) return null;\n\n const activeTab = uiState.sidebarTab;\n\n return (\n <div className=\"w-72 border-l border-gray-200 bg-white flex flex-col overflow-hidden flex-shrink-0\">\n {/* Tab header */}\n <div className=\"flex items-center border-b border-gray-200\">\n {tabs.map(({ tab, label }) => (\n <button\n key={tab}\n onClick={() => setSidebarTab(tab)}\n className={`flex-1 py-2 text-xs font-medium text-center transition-colors ${\n activeTab === tab\n ? \"text-blue-600 border-b-2 border-blue-600 bg-blue-50/50\"\n : \"text-gray-500 hover:text-gray-700 hover:bg-gray-50\"\n }`}\n >\n {label}\n </button>\n ))}\n <button\n onClick={toggleSidebar}\n className=\"p-1.5 mr-1 rounded text-gray-400 hover:text-gray-600 hover:bg-gray-100\"\n title=\"사이드바 닫기\"\n >\n <PanelRightClose className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Tab content */}\n <div className=\"flex-1 overflow-auto\">\n {activeTab === \"char\" && <CharFormatPanel />}\n {activeTab === \"para\" && <ParaFormatPanel />}\n {activeTab === \"page\" && <PageSetupPanel />}\n {activeTab === \"img-layout\" && <ImageLayoutPanel />}\n {activeTab === \"img-props\" && <ImagePropertiesPanel />}\n {activeTab === \"table\" && <TablePropertiesPanel />}\n {activeTab === \"cell\" && <CellPropertiesPanel />}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, type ReactNode } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\n\ninterface SidebarSectionProps {\n title: string;\n children: ReactNode;\n defaultOpen?: boolean;\n}\n\nexport function SidebarSection({\n title,\n children,\n defaultOpen = true,\n}: SidebarSectionProps) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <div className=\"border-b border-gray-100\">\n <button\n onClick={() => setOpen(!open)}\n className=\"flex items-center gap-1 w-full px-3 py-2 text-xs font-medium text-gray-700 hover:bg-gray-50\"\n >\n {open ? (\n <ChevronDown className=\"w-3.5 h-3.5 text-gray-400\" />\n ) : (\n <ChevronRight className=\"w-3.5 h-3.5 text-gray-400\" />\n )}\n {title}\n </button>\n {open && <div className=\"px-3 pb-3\">{children}</div>}\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface SidebarFieldProps {\n label: string;\n children: ReactNode;\n}\n\nexport function SidebarField({ label, children }: SidebarFieldProps) {\n return (\n <div className=\"flex items-center gap-2 mb-2\">\n <span className=\"text-[11px] text-gray-500 w-14 flex-shrink-0\">{label}</span>\n <div className=\"flex-1\">{children}</div>\n </div>\n );\n}\n","\"use client\";\n\nimport { SidebarField } from \"./SidebarField\";\n\ninterface BorderSettingsProps {\n disabled?: boolean;\n}\n\nexport function BorderSettings({ disabled }: BorderSettingsProps) {\n return (\n <div className=\"space-y-1\">\n <SidebarField label=\"종류\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"none\">없음</option>\n <option value=\"solid\">실선</option>\n <option value=\"dashed\">점선</option>\n <option value=\"double\">이중선</option>\n </select>\n </SidebarField>\n <SidebarField label=\"두께\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"0.1mm\">0.1mm</option>\n <option value=\"0.12mm\">0.12mm</option>\n <option value=\"0.3mm\">0.3mm</option>\n <option value=\"0.4mm\">0.4mm</option>\n <option value=\"0.5mm\">0.5mm</option>\n <option value=\"1.0mm\">1.0mm</option>\n </select>\n </SidebarField>\n <SidebarField label=\"색\">\n <input\n type=\"color\"\n defaultValue=\"#000000\"\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n </div>\n );\n}\n","\"use client\";\n\nimport { SidebarField } from \"./SidebarField\";\n\ninterface BackgroundSettingsProps {\n disabled?: boolean;\n}\n\nexport function BackgroundSettings({ disabled }: BackgroundSettingsProps) {\n return (\n <div className=\"space-y-1\">\n <SidebarField label=\"채우기\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n <option value=\"none\">없음</option>\n <option value=\"color\">색 채우기</option>\n <option value=\"gradient\">그라데이션</option>\n <option value=\"pattern\">무늬</option>\n </select>\n </SidebarField>\n <SidebarField label=\"배경색\">\n <input\n type=\"color\"\n defaultValue=\"#ffffff\"\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { FONT_FAMILIES, FONT_SIZES } from \"@/lib/constants\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport { BorderSettings } from \"./BorderSettings\";\nimport { BackgroundSettings } from \"./BackgroundSettings\";\n\nexport function CharFormatPanel() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const activeFormat = useEditorStore((s) => s.activeFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setFontFamily = useEditorStore((s) => s.setFontFamily);\n const setFontSize = useEditorStore((s) => s.setFontSize);\n const setTextColor = useEditorStore((s) => s.setTextColor);\n const setHighlightColor = useEditorStore((s) => s.setHighlightColor);\n\n const disabled = !doc || !selection;\n const cf = extendedFormat.char;\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"기본\">\n <SidebarField label=\"스타일\">\n <select\n disabled={disabled}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n defaultValue=\"0\"\n >\n <option value=\"0\">바탕글</option>\n <option value=\"1\">본문</option>\n <option value=\"2\">개요 1</option>\n <option value=\"3\">개요 2</option>\n </select>\n </SidebarField>\n <SidebarField label=\"글꼴\">\n <select\n disabled={disabled}\n value={cf.fontFamily || \"맑은 고딕\"}\n onChange={(e) => setFontFamily(e.target.value)}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {FONT_FAMILIES.map((f) => (\n <option key={f} value={f} style={{ fontFamily: fontFamilyCss(f) }}>\n {f}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"크기\">\n <select\n disabled={disabled}\n value={String(cf.fontSize || 10)}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {FONT_SIZES.map((s) => (\n <option key={s} value={String(s)}>\n {s}pt\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"색상\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"color\"\n value={cf.textColor && cf.textColor !== \"none\" ? cf.textColor : \"#000000\"}\n onChange={(e) => setTextColor(e.target.value)}\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n <span className=\"text-[10px] text-gray-400\">\n {cf.textColor && cf.textColor !== \"none\" ? cf.textColor : \"#000000\"}\n </span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"꾸밈\">\n <div className=\"flex flex-wrap gap-1 mb-2\">\n <FormatTag label=\"굵게\" active={activeFormat.bold} onClick={() => useEditorStore.getState().toggleBold()} disabled={disabled} />\n <FormatTag label=\"기울임\" active={activeFormat.italic} onClick={() => useEditorStore.getState().toggleItalic()} disabled={disabled} />\n <FormatTag label=\"밑줄\" active={activeFormat.underline} onClick={() => useEditorStore.getState().toggleUnderline()} disabled={disabled} />\n <FormatTag label=\"취소선\" active={activeFormat.strikethrough} onClick={() => useEditorStore.getState().toggleStrikethrough()} disabled={disabled} />\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"형광펜\">\n <SidebarField label=\"색상\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"color\"\n value={cf.highlightColor && cf.highlightColor !== \"none\" ? cf.highlightColor : \"#FFFF00\"}\n onChange={(e) => setHighlightColor(e.target.value)}\n disabled={disabled}\n className=\"w-6 h-6 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n <span className=\"text-[10px] text-gray-400\">\n {cf.highlightColor || \"없음\"}\n </span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <BorderSettings disabled={disabled} />\n </SidebarSection>\n\n <SidebarSection title=\"배경\" defaultOpen={false}>\n <BackgroundSettings disabled={disabled} />\n </SidebarSection>\n </div>\n );\n}\n\nfunction fontFamilyCss(name: string): string {\n if (name === \"Noto Sans KR\") return \"var(--font-noto-sans-kr), sans-serif\";\n if (name === \"Noto Serif KR\") return \"var(--font-noto-serif-kr), serif\";\n return `\"${name}\", sans-serif`;\n}\n\nfunction FormatTag({ label, active, onClick, disabled }: { label: string; active: boolean; onClick?: () => void; disabled?: boolean }) {\n return (\n <button\n onClick={onClick}\n disabled={disabled}\n className={`px-2 py-0.5 rounded text-[10px] border transition-colors ${\n active\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-gray-50 border-gray-200 text-gray-400 hover:bg-gray-100\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {label}\n </button>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport {\n ALIGNMENT_OPTIONS,\n LINE_SPACING_OPTIONS,\n type AlignmentType,\n} from \"@/lib/constants\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport { BorderSettings } from \"./BorderSettings\";\nimport { BackgroundSettings } from \"./BackgroundSettings\";\n\nexport function ParaFormatPanel() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const setAlignment = useEditorStore((s) => s.setAlignment);\n const setLineSpacing = useEditorStore((s) => s.setLineSpacing);\n\n const disabled = !doc || !selection;\n const pf = extendedFormat.para;\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"정렬\">\n <div className=\"flex gap-1 mb-2\">\n {ALIGNMENT_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n disabled={disabled}\n onClick={() => setAlignment(opt.value)}\n className={`flex-1 py-1 rounded text-[10px] border transition-colors ${\n pf.alignment === opt.value\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n title={opt.label}\n >\n {opt.value === \"LEFT\" && \"왼\"}\n {opt.value === \"CENTER\" && \"중\"}\n {opt.value === \"RIGHT\" && \"오\"}\n {opt.value === \"JUSTIFY\" && \"양\"}\n {opt.value === \"DISTRIBUTE\" && \"배\"}\n </button>\n ))}\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"여백\">\n <SidebarField label=\"왼쪽\">\n <input\n type=\"number\"\n value={pf.indentLeft}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <input\n type=\"number\"\n value={pf.indentRight}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"첫줄\">\n <input\n type=\"number\"\n value={pf.firstLineIndent}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"간격\">\n <SidebarField label=\"줄 간격\">\n <select\n disabled={disabled}\n value={String(\n LINE_SPACING_OPTIONS.reduce((prev, curr) =>\n Math.abs(curr.value - pf.lineSpacing) <\n Math.abs(prev.value - pf.lineSpacing)\n ? curr\n : prev,\n ).value,\n )}\n onChange={(e) => setLineSpacing(Number(e.target.value))}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n >\n {LINE_SPACING_OPTIONS.map((o) => (\n <option key={o.value} value={String(o.value)}>\n {o.label}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"문단 앞\">\n <input\n type=\"number\"\n value={pf.spacingBefore}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n <SidebarField label=\"문단 뒤\">\n <input\n type=\"number\"\n value={pf.spacingAfter}\n disabled={disabled}\n onChange={() => {}}\n className=\"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\"\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"줄 나눔\" defaultOpen={false}>\n <div className=\"space-y-1\">\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 한글 단어 잘림 허용\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 영어 단어 잘림 허용\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled={disabled} className=\"w-3 h-3\" />\n 외톨이줄 방지\n </label>\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"테두리\" defaultOpen={false}>\n <BorderSettings disabled={disabled} />\n </SidebarSection>\n\n <SidebarSection title=\"배경\" defaultOpen={false}>\n <BackgroundSettings disabled={disabled} />\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { PAGE_SIZE_PRESETS, type OrientationType } from \"@/lib/constants\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst PAGE_NUMBER_POSITIONS = [\n { value: \"none\", label: \"없음\" },\n { value: \"header-center\", label: \"머리말 가운데\" },\n { value: \"header-right\", label: \"머리말 오른쪽\" },\n { value: \"footer-center\", label: \"꼬리말 가운데\" },\n { value: \"footer-right\", label: \"꼬리말 오른쪽\" },\n] as const;\n\nexport function PageSetupPanel() {\n const doc = useEditorStore((s) => s.doc);\n const selection = useEditorStore((s) => s.selection);\n const updatePageSize = useEditorStore((s) => s.updatePageSize);\n const updatePageMargins = useEditorStore((s) => s.updatePageMargins);\n const updatePageOrientation = useEditorStore((s) => s.updatePageOrientation);\n const setPageNumbering = useEditorStore((s) => s.setPageNumbering);\n const viewModel = useEditorStore((s) => s.viewModel);\n\n const [pageNumPosition, setPageNumPosition] = useState(\"none\");\n const [pageNumStart, setPageNumStart] = useState(1);\n\n const disabled = !doc;\n const sIdx = selection?.sectionIndex ?? 0;\n const section = doc?.sections[sIdx];\n\n const pageSize = section?.properties.pageSize;\n const pageMargins = section?.properties.pageMargins;\n\n const widthMm = pageSize ? parseFloat(hwpToMm(pageSize.width).toFixed(1)) : 210;\n const heightMm = pageSize ? parseFloat(hwpToMm(pageSize.height).toFixed(1)) : 297;\n const orientation: OrientationType =\n pageSize && pageSize.width > pageSize.height ? \"LANDSCAPE\" : \"PORTRAIT\";\n\n const leftMm = pageMargins ? parseFloat(hwpToMm(pageMargins.left).toFixed(1)) : 30;\n const rightMm = pageMargins ? parseFloat(hwpToMm(pageMargins.right).toFixed(1)) : 30;\n const topMm = pageMargins ? parseFloat(hwpToMm(pageMargins.top).toFixed(1)) : 20;\n const bottomMm = pageMargins ? parseFloat(hwpToMm(pageMargins.bottom).toFixed(1)) : 15;\n const headerMm = pageMargins ? parseFloat(hwpToMm(pageMargins.header).toFixed(1)) : 15;\n const footerMm = pageMargins ? parseFloat(hwpToMm(pageMargins.footer).toFixed(1)) : 15;\n const gutterMm = pageMargins ? parseFloat(hwpToMm(pageMargins.gutter).toFixed(1)) : 0;\n\n // Find matching preset\n const matchedPreset = PAGE_SIZE_PRESETS.find(\n (p) => p.width === Math.round(widthMm) && p.height === Math.round(heightMm),\n );\n // Also check landscape match\n const matchedPresetLandscape = PAGE_SIZE_PRESETS.find(\n (p) => p.height === Math.round(widthMm) && p.width === Math.round(heightMm),\n );\n const presetValue = matchedPreset?.name ?? matchedPresetLandscape?.name ?? \"custom\";\n\n const handlePresetChange = (name: string) => {\n const preset = PAGE_SIZE_PRESETS.find((p) => p.name === name);\n if (!preset) return;\n if (orientation === \"LANDSCAPE\") {\n updatePageSize(preset.height, preset.width);\n } else {\n updatePageSize(preset.width, preset.height);\n }\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"용지 크기\">\n <SidebarField label=\"종류\">\n <select\n disabled={disabled}\n value={presetValue}\n onChange={(e) => handlePresetChange(e.target.value)}\n className={inputClass}\n >\n {PAGE_SIZE_PRESETS.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n </option>\n ))}\n {presetValue === \"custom\" && (\n <option value=\"custom\">사용자 지정</option>\n )}\n </select>\n </SidebarField>\n <SidebarField label=\"폭\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={widthMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePageSize(v, heightMm);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"길이\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={heightMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePageSize(widthMm, v);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"용지 방향\">\n <div className=\"flex gap-2 mb-2\">\n <button\n disabled={disabled}\n onClick={() => updatePageOrientation(\"PORTRAIT\")}\n className={`flex-1 py-2 rounded border text-[10px] flex flex-col items-center gap-1 transition-colors ${\n orientation === \"PORTRAIT\"\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n <svg width=\"20\" height=\"26\" viewBox=\"0 0 20 26\" fill=\"none\" className=\"mx-auto\">\n <rect x=\"1\" y=\"1\" width=\"18\" height=\"24\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.5\" fill=\"none\" />\n <line x1=\"4\" y1=\"6\" x2=\"16\" y2=\"6\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"10\" x2=\"16\" y2=\"10\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"14\" x2=\"12\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </svg>\n 세로\n </button>\n <button\n disabled={disabled}\n onClick={() => updatePageOrientation(\"LANDSCAPE\")}\n className={`flex-1 py-2 rounded border text-[10px] flex flex-col items-center gap-1 transition-colors ${\n orientation === \"LANDSCAPE\"\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n <svg width=\"26\" height=\"20\" viewBox=\"0 0 26 20\" fill=\"none\" className=\"mx-auto\">\n <rect x=\"1\" y=\"1\" width=\"24\" height=\"18\" rx=\"1\" stroke=\"currentColor\" strokeWidth=\"1.5\" fill=\"none\" />\n <line x1=\"4\" y1=\"5\" x2=\"22\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"9\" x2=\"22\" y2=\"9\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"4\" y1=\"13\" x2=\"16\" y2=\"13\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </svg>\n 가로\n </button>\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"제본\">\n <div className=\"flex gap-1 mb-2\">\n {([\"LEFT\", \"FACING\", \"TOP\"] as const).map((type) => (\n <button\n key={type}\n disabled={disabled}\n className={`flex-1 py-1 rounded text-[10px] border transition-colors ${\n \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-40 disabled:cursor-not-allowed`}\n >\n {type === \"LEFT\" && \"한쪽\"}\n {type === \"FACING\" && \"맞쪽\"}\n {type === \"TOP\" && \"위로\"}\n </button>\n ))}\n </div>\n </SidebarSection>\n\n <SidebarSection title=\"용지 여백\">\n <SidebarField label=\"왼쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={leftMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ left: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={rightMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ right: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"위쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={topMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ top: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"아래쪽\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={bottomMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ bottom: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"머리말\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={headerMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ header: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"꼬리말\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={footerMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ footer: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"제본\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={gutterMm}\n disabled={disabled}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v >= 0) updatePageMargins({ gutter: v });\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"쪽 번호\">\n <SidebarField label=\"위치\">\n <select\n disabled={disabled}\n value={pageNumPosition}\n onChange={(e) => {\n setPageNumPosition(e.target.value);\n setPageNumbering({ position: e.target.value, startNumber: pageNumStart });\n }}\n className={inputClass}\n >\n {PAGE_NUMBER_POSITIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"시작 번호\">\n <input\n type=\"number\"\n value={pageNumStart}\n disabled={disabled}\n min={1}\n step={1}\n onChange={(e) => {\n const v = parseInt(e.target.value, 10);\n if (!isNaN(v) && v >= 1) {\n setPageNumStart(v);\n }\n }}\n onBlur={() => {\n if (!disabled && pageNumPosition !== \"none\") {\n setPageNumbering({ position: pageNumPosition, startNumber: pageNumStart });\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !disabled && pageNumPosition !== \"none\") {\n setPageNumbering({ position: pageNumPosition, startNumber: pageNumStart });\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst PX_TO_MM = 25.4 / 96;\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\nexport function ImageLayoutPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const updatePictureSize = useEditorStore((s) => s.updatePictureSize);\n const setImageOutMargin = useEditorStore((s) => s.setImageOutMargin);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const imgIdx = selection?.imageIndex ?? 0;\n\n const image = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.images[imgIdx];\n const hasImage = !!image;\n\n const widthMm = image ? parseFloat((image.widthPx * PX_TO_MM).toFixed(2)) : 0;\n const heightMm = image ? parseFloat((image.heightPx * PX_TO_MM).toFixed(2)) : 0;\n\n const [omTop, setOmTop] = useState(image ? roundMm(image.outMargin.top) : 0);\n const [omBottom, setOmBottom] = useState(image ? roundMm(image.outMargin.bottom) : 0);\n const [omLeft, setOmLeft] = useState(image ? roundMm(image.outMargin.left) : 0);\n const [omRight, setOmRight] = useState(image ? roundMm(image.outMargin.right) : 0);\n\n useEffect(() => {\n if (!image) return;\n setOmTop(roundMm(image.outMargin.top));\n setOmBottom(roundMm(image.outMargin.bottom));\n setOmLeft(roundMm(image.outMargin.left));\n setOmRight(roundMm(image.outMargin.right));\n }, [image?.outMargin.top, image?.outMargin.bottom, image?.outMargin.left, image?.outMargin.right]);\n\n const applyOutMargin = () => {\n if (hasImage) setImageOutMargin({ top: omTop, bottom: omBottom, left: omLeft, right: omRight });\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"크기\">\n <SidebarField label=\"너비\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-20 flex-shrink-0\">\n <option>고정 값</option>\n </select>\n <input\n type=\"number\"\n step=\"0.01\"\n value={widthMm}\n disabled={!image}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePictureSize(v, heightMm);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"높이\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-20 flex-shrink-0\">\n <option>고정 값</option>\n </select>\n <input\n type=\"number\"\n step=\"0.01\"\n value={heightMm}\n disabled={!image}\n onChange={(e) => {\n const v = parseFloat(e.target.value);\n if (!isNaN(v) && v > 0) updatePictureSize(widthMm, v);\n }}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mt-1\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 크기 고정\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"위치\">\n <div className=\"mb-2\">\n <span className=\"text-[11px] text-gray-600 block mb-1.5\">본문과의 배치</span>\n <div className=\"flex gap-1\">\n {[\"어울림\", \"자리차지\", \"글 뒤로\", \"글 앞으로\"].map((label, i) => (\n <button\n key={label}\n disabled\n className={`flex-1 py-1.5 rounded border text-[9px] transition-colors flex flex-col items-center gap-0.5 ${\n i === 0\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500\"\n } disabled:opacity-60 disabled:cursor-not-allowed`}\n >\n <svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" className=\"mx-auto\">\n <line x1=\"2\" y1=\"2\" x2=\"18\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"5\" x2=\"18\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <rect x=\"6\" y=\"7\" width=\"8\" height=\"6\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"currentColor\" fillOpacity=\"0.15\" />\n {i === 0 && (\n <>\n <line x1=\"2\" y1=\"8\" x2=\"5\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"15\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"11\" x2=\"5\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"15\" y1=\"11\" x2=\"18\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"14\" x2=\"18\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </>\n )}\n {i === 1 && (\n <line x1=\"2\" y1=\"14\" x2=\"18\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n )}\n {i >= 2 && (\n <>\n <line x1=\"2\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"11\" x2=\"18\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n <line x1=\"2\" y1=\"14\" x2=\"18\" y2=\"14\" stroke=\"currentColor\" strokeWidth=\"1\" opacity=\"0.4\" />\n </>\n )}\n </svg>\n {label}\n </button>\n ))}\n </div>\n </div>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mb-3\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 글자처럼 취급\n </label>\n <SidebarField label=\"가로\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-16 flex-shrink-0\">\n <option>문단</option>\n </select>\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"세로\">\n <div className=\"flex items-center gap-1\">\n <select disabled className=\"h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40 w-16 flex-shrink-0\">\n <option>문단</option>\n </select>\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"개체 회전/기울이기\" defaultOpen={false}>\n <SidebarField label=\"회전각\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n </SidebarField>\n <SidebarField label=\"가로 기울이기\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n </SidebarField>\n <SidebarField label=\"세로 기울이기\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"기타\" defaultOpen={false}>\n <SidebarField label=\"번호 종류\">\n <select disabled className={inputClass}>\n <option>그림</option>\n </select>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 개체 보호\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"바깥 여백\" defaultOpen={false}>\n <SidebarField label=\"위쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omTop}\n onChange={(e) => setOmTop(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"아래쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omBottom}\n onChange={(e) => setOmBottom(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"왼쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omLeft}\n onChange={(e) => setOmLeft(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omRight}\n onChange={(e) => setOmRight(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst PX_TO_MM = 25.4 / 96;\n\nfunction getMediaType(file: File): \"image/png\" | \"image/jpeg\" | \"image/gif\" | \"image/bmp\" {\n const ext = file.name.split(\".\").pop()?.toLowerCase() ?? \"\";\n const typeMap: Record<string, \"image/png\" | \"image/jpeg\" | \"image/gif\" | \"image/bmp\"> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n };\n return typeMap[ext] ?? \"image/png\";\n}\n\nasync function getImageDimensions(data: Uint8Array, mediaType: string): Promise<{ width: number; height: number }> {\n return new Promise((resolve) => {\n const blob = new Blob([data], { type: mediaType });\n const url = URL.createObjectURL(blob);\n const img = new Image();\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve({ width: img.naturalWidth, height: img.naturalHeight });\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n resolve({ width: 100, height: 100 }); // fallback\n };\n img.src = url;\n });\n}\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\nexport function ImagePropertiesPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const doc = useEditorStore((s) => s.doc);\n const setImageOutMargin = useEditorStore((s) => s.setImageOutMargin);\n const insertImage = useEditorStore((s) => s.insertImage);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isInserting, setIsInserting] = useState(false);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const imgIdx = selection?.imageIndex ?? 0;\n\n const image = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.images[imgIdx];\n const hasImage = !!image;\n\n const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setIsInserting(true);\n try {\n const buffer = await file.arrayBuffer();\n const data = new Uint8Array(buffer);\n const mediaType = getMediaType(file);\n const dims = await getImageDimensions(data, mediaType);\n // Scale to fit max 150mm width while maintaining aspect ratio\n const maxWidth = 150;\n const scale = dims.width * PX_TO_MM > maxWidth ? maxWidth / (dims.width * PX_TO_MM) : 1;\n const widthMm = dims.width * PX_TO_MM * scale;\n const heightMm = dims.height * PX_TO_MM * scale;\n insertImage(data, mediaType, widthMm, heightMm);\n } catch (err) {\n console.error(\"Failed to insert image:\", err);\n } finally {\n setIsInserting(false);\n if (fileInputRef.current) fileInputRef.current.value = \"\";\n }\n };\n\n const widthMm = image ? parseFloat((image.widthPx * PX_TO_MM).toFixed(2)) : 0;\n const heightMm = image ? parseFloat((image.heightPx * PX_TO_MM).toFixed(2)) : 0;\n\n const [omTop, setOmTop] = useState(image ? roundMm(image.outMargin.top) : 0);\n const [omBottom, setOmBottom] = useState(image ? roundMm(image.outMargin.bottom) : 0);\n const [omLeft, setOmLeft] = useState(image ? roundMm(image.outMargin.left) : 0);\n const [omRight, setOmRight] = useState(image ? roundMm(image.outMargin.right) : 0);\n\n useEffect(() => {\n if (!image) return;\n setOmTop(roundMm(image.outMargin.top));\n setOmBottom(roundMm(image.outMargin.bottom));\n setOmLeft(roundMm(image.outMargin.left));\n setOmRight(roundMm(image.outMargin.right));\n }, [image?.outMargin.top, image?.outMargin.bottom, image?.outMargin.left, image?.outMargin.right]);\n\n const applyOutMargin = () => {\n if (hasImage) setImageOutMargin({ top: omTop, bottom: omBottom, left: omLeft, right: omRight });\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/bmp\"\n className=\"hidden\"\n onChange={handleFileSelect}\n />\n <SidebarSection title=\"그림\">\n <SidebarField label=\"파일 이름\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[11px] text-gray-600 truncate flex-1\">\n {image?.binaryItemIdRef ?? \"-\"}\n </span>\n <button\n disabled={!doc || isInserting}\n onClick={() => fileInputRef.current?.click()}\n className=\"h-6 px-2 text-[10px] border border-gray-300 rounded bg-white text-gray-600 hover:bg-gray-50 disabled:opacity-40 disabled:cursor-not-allowed flex-shrink-0\"\n >\n {isInserting ? \"삽입 중...\" : \"그림 삽입\"}\n </button>\n </div>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mt-1\">\n <input type=\"checkbox\" checked disabled className=\"w-3 h-3\" />\n 문서에 포함\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"확대/축소 비율\">\n <SidebarField label=\"가로\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.01\"\n value={100}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <SidebarField label=\"세로\">\n <div className=\"flex items-center gap-1\">\n <input\n type=\"number\"\n step=\"0.01\"\n value={100}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mt-1\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 가로 세로 같은 비율 유지\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"자르기\" defaultOpen={false}>\n {[\"왼쪽\", \"오른쪽\", \"위쪽\", \"아래쪽\"].map((label) => (\n <SidebarField key={label} label={label}>\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n ))}\n </SidebarSection>\n\n <SidebarSection title=\"바깥 여백\" defaultOpen={false}>\n <SidebarField label=\"위쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omTop}\n onChange={(e) => setOmTop(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"아래쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omBottom}\n onChange={(e) => setOmBottom(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"왼쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omLeft}\n onChange={(e) => setOmLeft(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n <SidebarField label=\"오른쪽\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" step=\"0.1\" min={0} disabled={!hasImage} value={omRight}\n onChange={(e) => setOmRight(Number(e.target.value))}\n onBlur={applyOutMargin}\n onKeyDown={(e) => { if (e.key === \"Enter\") applyOutMargin(); }}\n className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">mm</span>\n </div>\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"색 조절\" defaultOpen={false}>\n <SidebarField label=\"색조\">\n <select disabled className={inputClass}>\n <option>효과 없음</option>\n </select>\n </SidebarField>\n <SidebarField label=\"밝기\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <SidebarField label=\"대비\">\n <div className=\"flex items-center gap-1\">\n <input type=\"number\" disabled value={0} onChange={() => {}} className={inputClass} />\n <span className=\"text-[10px] text-gray-400 flex-shrink-0\">%</span>\n </div>\n </SidebarField>\n <div className=\"mt-2 space-y-1\">\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 워터마크 효과\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 그림 반전\n </label>\n </div>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\n\nconst BORDER_TYPES = [\n { value: \"NONE\", label: \"없음\" },\n { value: \"SOLID\", label: \"실선\" },\n { value: \"DASH\", label: \"점선\" },\n { value: \"DOT\", label: \"작은 점선\" },\n { value: \"DASH_DOT\", label: \"일점 쇄선\" },\n { value: \"DOUBLE_SLIM\", label: \"이중선\" },\n];\n\nconst BORDER_WIDTHS = [\n \"0.1 mm\", \"0.12 mm\", \"0.15 mm\", \"0.2 mm\", \"0.25 mm\",\n \"0.3 mm\", \"0.4 mm\", \"0.5 mm\", \"0.7 mm\", \"1.0 mm\",\n];\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\nexport function TablePropertiesPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const setTablePageBreak = useEditorStore((s) => s.setTablePageBreak);\n const setTableRepeatHeader = useEditorStore((s) => s.setTableRepeatHeader);\n const setTableSize = useEditorStore((s) => s.setTableSize);\n const setTableOutMargin = useEditorStore((s) => s.setTableOutMargin);\n const setTableInMargin = useEditorStore((s) => s.setTableInMargin);\n const setTableBorder = useEditorStore((s) => s.setTableBorder);\n const setTableBackground = useEditorStore((s) => s.setTableBackground);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const tIdx = selection?.tableIndex ?? 0;\n\n const table = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.tables[tIdx];\n const hasTable = !!table;\n\n const widthMm = table ? roundMm(table.widthHwp) : 0;\n const heightMm = table ? roundMm(table.heightHwp) : 0;\n\n const [editWidth, setEditWidth] = useState(widthMm);\n const [editHeight, setEditHeight] = useState(heightMm);\n\n // Outer margin state\n const [outTop, setOutTop] = useState(table ? roundMm(table.outMargin.top) : 0);\n const [outBottom, setOutBottom] = useState(table ? roundMm(table.outMargin.bottom) : 0);\n const [outLeft, setOutLeft] = useState(table ? roundMm(table.outMargin.left) : 0);\n const [outRight, setOutRight] = useState(table ? roundMm(table.outMargin.right) : 0);\n\n // Inner margin state\n const [inTop, setInTop] = useState(table ? roundMm(table.inMargin.top) : 0);\n const [inBottom, setInBottom] = useState(table ? roundMm(table.inMargin.bottom) : 0);\n const [inLeft, setInLeft] = useState(table ? roundMm(table.inMargin.left) : 0);\n const [inRight, setInRight] = useState(table ? roundMm(table.inMargin.right) : 0);\n\n useEffect(() => {\n setEditWidth(widthMm);\n setEditHeight(heightMm);\n }, [widthMm, heightMm]);\n\n useEffect(() => {\n if (!table) return;\n setOutTop(roundMm(table.outMargin.top));\n setOutBottom(roundMm(table.outMargin.bottom));\n setOutLeft(roundMm(table.outMargin.left));\n setOutRight(roundMm(table.outMargin.right));\n setInTop(roundMm(table.inMargin.top));\n setInBottom(roundMm(table.inMargin.bottom));\n setInLeft(roundMm(table.inMargin.left));\n setInRight(roundMm(table.inMargin.right));\n }, [table?.outMargin.top, table?.outMargin.bottom, table?.outMargin.left, table?.outMargin.right,\n table?.inMargin.top, table?.inMargin.bottom, table?.inMargin.left, table?.inMargin.right]);\n\n // Table border state\n const [tblBorderType, setTblBorderType] = useState(\"SOLID\");\n const [tblBorderWidth, setTblBorderWidth] = useState(\"0.12 mm\");\n const [tblBorderColor, setTblBorderColor] = useState(\"#000000\");\n const [tblBgColor, setTblBgColor] = useState(\"#FFFFFF\");\n const [tblNoBg, setTblNoBg] = useState(true);\n\n const applyTableBorder = useCallback(() => {\n if (!hasTable) return;\n setTableBorder(\n [\"left\", \"right\", \"top\", \"bottom\"],\n { type: tblBorderType, width: tblBorderWidth, color: tblBorderColor },\n );\n }, [hasTable, tblBorderType, tblBorderWidth, tblBorderColor, setTableBorder]);\n\n const pageBreak = table?.pageBreak ?? \"CELL\";\n const repeatHeader = table?.repeatHeader ?? false;\n\n const PAGE_BREAK_OPTIONS = [\n { value: \"CELL\" as const, label: \"나눔\", desc: \"쪽 경계에서 표를 나눕니다\" },\n { value: \"CELL\" as const, label: \"셀 단위로 나눔\", desc: \"셀 단위로 나눕니다\" },\n { value: \"NONE\" as const, label: \"나누지 않음\", desc: \"표를 나누지 않습니다\" },\n ];\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n return (\n <div className=\"text-xs\">\n <SidebarSection title=\"여러 쪽 지원\">\n <div className=\"mb-2\">\n <span className=\"text-[11px] text-gray-600 block mb-1.5\">쪽 경계에서</span>\n <div className=\"flex gap-1\">\n {PAGE_BREAK_OPTIONS.map((opt, i) => {\n const isActive =\n (i <= 1 && pageBreak === \"CELL\") ||\n (i === 2 && pageBreak === \"NONE\");\n return (\n <button\n key={opt.label}\n disabled={!hasTable}\n onClick={() => setTablePageBreak(opt.value)}\n className={`flex-1 py-2 rounded border text-[9px] flex flex-col items-center gap-1 transition-colors ${\n isActive\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-60 disabled:cursor-not-allowed`}\n title={opt.desc}\n >\n <svg width=\"22\" height=\"18\" viewBox=\"0 0 22 18\" fill=\"none\" className=\"mx-auto\">\n <rect x=\"1\" y=\"1\" width=\"20\" height=\"7\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"8\" y1=\"1\" x2=\"8\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n {i === 0 && (\n <>\n <line x1=\"1\" y1=\"4.5\" x2=\"21\" y2=\"4.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" strokeDasharray=\"2 1\" />\n <rect x=\"1\" y=\"10\" width=\"20\" height=\"7\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"8\" y1=\"10\" x2=\"8\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n </>\n )}\n {i === 1 && (\n <>\n <line x1=\"1\" y1=\"4.5\" x2=\"21\" y2=\"4.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" strokeDasharray=\"2 1\" />\n <rect x=\"1\" y=\"10\" width=\"20\" height=\"7\" rx=\"0.5\" stroke=\"currentColor\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"8\" y1=\"10\" x2=\"8\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"17\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n <line x1=\"1\" y1=\"13.5\" x2=\"21\" y2=\"13.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n </>\n )}\n {i === 2 && (\n <line x1=\"1\" y1=\"4.5\" x2=\"21\" y2=\"4.5\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n )}\n </svg>\n {opt.label}\n </button>\n );\n })}\n </div>\n </div>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600 mb-2\">\n <input\n type=\"checkbox\"\n checked={repeatHeader}\n disabled={!hasTable}\n onChange={(e) => setTableRepeatHeader(e.target.checked)}\n className=\"w-3 h-3\"\n />\n 제목 줄 자동 반복\n </label>\n <label className=\"flex items-center gap-2 text-[11px] text-gray-600\">\n <input type=\"checkbox\" disabled className=\"w-3 h-3\" />\n 자동으로 나뉜 표의 경계선 설정\n </label>\n </SidebarSection>\n\n <SidebarSection title=\"표 크기\">\n <SidebarField label=\"너비 (mm)\">\n <input\n type=\"number\"\n value={editWidth}\n disabled={!hasTable}\n step={1}\n min={10}\n onChange={(e) => setEditWidth(Number(e.target.value))}\n onBlur={() => {\n if (hasTable && editWidth > 0) setTableSize(editWidth, editHeight);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && hasTable && editWidth > 0) {\n setTableSize(editWidth, editHeight);\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"높이 (mm)\">\n <input\n type=\"number\"\n value={editHeight}\n disabled={!hasTable}\n step={1}\n min={10}\n onChange={(e) => setEditHeight(Number(e.target.value))}\n onBlur={() => {\n if (hasTable && editHeight > 0) setTableSize(editWidth, editHeight);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && hasTable && editHeight > 0) {\n setTableSize(editWidth, editHeight);\n }\n }}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"표 정보\">\n <SidebarField label=\"행\">\n <input\n type=\"number\"\n value={table?.rowCount ?? 0}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"열\">\n <input\n type=\"number\"\n value={table?.colCount ?? 0}\n disabled\n onChange={() => {}}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"바깥 여백\" defaultOpen={false}>\n <SidebarField label=\"위 (mm)\">\n <input type=\"number\" value={outTop} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutTop(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"아래 (mm)\">\n <input type=\"number\" value={outBottom} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutBottom(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"왼쪽 (mm)\">\n <input type=\"number\" value={outLeft} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutLeft(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"오른쪽 (mm)\">\n <input type=\"number\" value={outRight} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setOutRight(Number(e.target.value))}\n onBlur={() => hasTable && setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableOutMargin({ top: outTop, bottom: outBottom, left: outLeft, right: outRight }); }}\n className={inputClass} />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"안쪽 여백\" defaultOpen={false}>\n <SidebarField label=\"위 (mm)\">\n <input type=\"number\" value={inTop} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInTop(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"아래 (mm)\">\n <input type=\"number\" value={inBottom} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInBottom(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"왼쪽 (mm)\">\n <input type=\"number\" value={inLeft} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInLeft(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n <SidebarField label=\"오른쪽 (mm)\">\n <input type=\"number\" value={inRight} disabled={!hasTable} step={0.1} min={0}\n onChange={(e) => setInRight(Number(e.target.value))}\n onBlur={() => hasTable && setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight })}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasTable) setTableInMargin({ top: inTop, bottom: inBottom, left: inLeft, right: inRight }); }}\n className={inputClass} />\n </SidebarField>\n </SidebarSection>\n\n <SidebarSection title=\"테두리 (전체 셀)\" defaultOpen={false}>\n <SidebarField label=\"종류\">\n <select\n value={tblBorderType}\n disabled={!hasTable}\n onChange={(e) => setTblBorderType(e.target.value)}\n className={inputClass}\n >\n {BORDER_TYPES.map((t) => (\n <option key={t.value} value={t.value}>{t.label}</option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"굵기\">\n <select\n value={tblBorderWidth}\n disabled={!hasTable}\n onChange={(e) => setTblBorderWidth(e.target.value)}\n className={inputClass}\n >\n {BORDER_WIDTHS.map((w) => (\n <option key={w} value={w}>{w}</option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"색상\">\n <input\n type=\"color\"\n value={tblBorderColor}\n disabled={!hasTable}\n onChange={(e) => setTblBorderColor(e.target.value)}\n className=\"w-full h-6 p-0 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n <button\n disabled={!hasTable}\n onClick={applyTableBorder}\n className=\"w-full mt-1 py-1.5 rounded bg-blue-600 text-white text-[11px] font-medium hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n 전체 셀 테두리 적용\n </button>\n </SidebarSection>\n\n <SidebarSection title=\"배경 (전체 셀)\" defaultOpen={false}>\n <div className=\"flex items-center gap-2 mb-2\">\n <label className=\"flex items-center gap-1 text-[11px] text-gray-600\">\n <input\n type=\"checkbox\"\n checked={tblNoBg}\n onChange={(e) => {\n setTblNoBg(e.target.checked);\n if (e.target.checked && hasTable) setTableBackground(null);\n }}\n className=\"w-3 h-3\"\n />\n 없음\n </label>\n </div>\n {!tblNoBg && (\n <SidebarField label=\"색상\">\n <input\n type=\"color\"\n value={tblBgColor}\n disabled={!hasTable}\n onChange={(e) => {\n setTblBgColor(e.target.value);\n if (hasTable) setTableBackground(e.target.value);\n }}\n className=\"w-full h-6 p-0 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n )}\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { hwpToMm } from \"@/lib/hwp-units\";\nimport { SidebarSection } from \"./SidebarSection\";\nimport { SidebarField } from \"./SidebarField\";\nimport {\n AlignVerticalJustifyStart,\n AlignVerticalJustifyCenter,\n AlignVerticalJustifyEnd,\n} from \"lucide-react\";\n\nconst BORDER_TYPES = [\n { value: \"NONE\", label: \"없음\" },\n { value: \"SOLID\", label: \"실선\" },\n { value: \"DASH\", label: \"점선\" },\n { value: \"DOT\", label: \"작은 점선\" },\n { value: \"DASH_DOT\", label: \"일점 쇄선\" },\n { value: \"DOUBLE_SLIM\", label: \"이중선\" },\n];\n\nconst BORDER_WIDTHS = [\n \"0.1 mm\", \"0.12 mm\", \"0.15 mm\", \"0.2 mm\", \"0.25 mm\",\n \"0.3 mm\", \"0.4 mm\", \"0.5 mm\", \"0.7 mm\", \"1.0 mm\",\n];\n\ntype BorderSide = \"left\" | \"right\" | \"top\" | \"bottom\";\n\nfunction roundMm(hwp: number): number {\n return Math.round(hwpToMm(hwp) * 10) / 10;\n}\n\nexport function CellPropertiesPanel() {\n const selection = useEditorStore((s) => s.selection);\n const viewModel = useEditorStore((s) => s.viewModel);\n const setCellBorder = useEditorStore((s) => s.setCellBorder);\n const setCellBackground = useEditorStore((s) => s.setCellBackground);\n const setCellVertAlign = useEditorStore((s) => s.setCellVertAlign);\n\n const sIdx = selection?.sectionIndex ?? 0;\n const pIdx = selection?.paragraphIndex ?? 0;\n const tIdx = selection?.tableIndex ?? 0;\n const row = selection?.row ?? 0;\n const col = selection?.col ?? 0;\n\n const table = viewModel?.sections[sIdx]?.paragraphs[pIdx]?.tables[tIdx];\n const cell = table?.cells[row]?.[col];\n const hasCell = !!cell;\n\n // Border state\n const [selectedSides, setSelectedSides] = useState<Set<BorderSide>>(\n new Set([\"left\", \"right\", \"top\", \"bottom\"]),\n );\n const [borderType, setBorderType] = useState(\"SOLID\");\n const [borderWidth, setBorderWidth] = useState(\"0.12 mm\");\n const [borderColor, setBorderColor] = useState(\"#000000\");\n\n // Background state\n const [bgColor, setBgColor] = useState(\"#FFFFFF\");\n const [noBg, setNoBg] = useState(true);\n\n // Vertical align\n const vertAlign = cell?.vertAlign ?? \"CENTER\";\n\n // Cell margin state\n const doc = useEditorStore((s) => s.doc);\n const [marginTop, setMarginTop] = useState(0);\n const [marginBottom, setMarginBottom] = useState(0);\n const [marginLeft, setMarginLeft] = useState(0);\n const [marginRight, setMarginRight] = useState(0);\n\n // Load margin from cell\n useEffect(() => {\n if (!doc || !selection || selection.tableIndex == null || selection.row == null || selection.col == null) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const tbl = para.tables[selection.tableIndex];\n if (!tbl) return;\n const c = tbl.cell(selection.row, selection.col);\n const m = c.getMargin();\n setMarginTop(roundMm(m.top));\n setMarginBottom(roundMm(m.bottom));\n setMarginLeft(roundMm(m.left));\n setMarginRight(roundMm(m.right));\n } catch { /* ignore */ }\n }, [doc, selection?.sectionIndex, selection?.paragraphIndex, selection?.tableIndex, selection?.row, selection?.col]);\n\n const toggleSide = (side: BorderSide) => {\n setSelectedSides((prev) => {\n const next = new Set(prev);\n if (next.has(side)) next.delete(side);\n else next.add(side);\n return next;\n });\n };\n\n const selectPreset = (preset: \"all\" | \"outer\" | \"none\") => {\n if (preset === \"all\") setSelectedSides(new Set([\"left\", \"right\", \"top\", \"bottom\"]));\n else if (preset === \"outer\") setSelectedSides(new Set([\"left\", \"right\", \"top\", \"bottom\"]));\n else setSelectedSides(new Set());\n };\n\n const applyBorder = () => {\n if (!hasCell || selectedSides.size === 0) return;\n setCellBorder(\n Array.from(selectedSides),\n { type: borderType, width: borderWidth, color: borderColor },\n );\n };\n\n const applyBackground = () => {\n if (!hasCell) return;\n setCellBackground(noBg ? null : bgColor);\n };\n\n const applyMargin = () => {\n if (!doc || !selection || selection.tableIndex == null || selection.row == null || selection.col == null) return;\n try {\n const section = doc.sections[selection.sectionIndex];\n if (!section) return;\n const para = section.paragraphs[selection.paragraphIndex];\n if (!para) return;\n const tbl = para.tables[selection.tableIndex];\n if (!tbl) return;\n const c = tbl.cell(selection.row, selection.col);\n const mmToHwp = (mm: number) => Math.round((mm * 7200) / 25.4);\n c.setMargin({\n top: mmToHwp(marginTop),\n bottom: mmToHwp(marginBottom),\n left: mmToHwp(marginLeft),\n right: mmToHwp(marginRight),\n });\n useEditorStore.getState().rebuild();\n } catch { /* ignore */ }\n };\n\n const inputClass =\n \"w-full h-6 px-1 text-[11px] border border-gray-300 rounded bg-white disabled:opacity-40\";\n\n const sideBtn = (side: BorderSide, label: string) => (\n <button\n onClick={() => toggleSide(side)}\n className={`w-7 h-7 rounded border text-[10px] font-medium transition-colors ${\n selectedSides.has(side)\n ? \"bg-blue-100 border-blue-400 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-400 hover:bg-gray-50\"\n }`}\n >\n {label}\n </button>\n );\n\n const vertAlignBtn = (\n value: \"TOP\" | \"CENTER\" | \"BOTTOM\",\n Icon: typeof AlignVerticalJustifyStart,\n label: string,\n ) => (\n <button\n disabled={!hasCell}\n onClick={() => setCellVertAlign(value)}\n className={`flex-1 py-1.5 rounded border text-[10px] flex flex-col items-center gap-0.5 transition-colors ${\n vertAlign === value\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-200 text-gray-500 hover:bg-gray-50\"\n } disabled:opacity-60 disabled:cursor-not-allowed`}\n title={label}\n >\n <Icon className=\"w-4 h-4\" />\n {label}\n </button>\n );\n\n return (\n <div className=\"text-xs\">\n {/* Border section */}\n <SidebarSection title=\"테두리\">\n <div className=\"mb-2\">\n <span className=\"text-[11px] text-gray-600 block mb-1.5\">방향 선택</span>\n <div className=\"flex items-center gap-1 mb-1.5\">\n <div className=\"grid grid-cols-3 gap-0.5\">\n <div />\n {sideBtn(\"top\", \"T\")}\n <div />\n {sideBtn(\"left\", \"L\")}\n <button\n onClick={() => selectPreset(\"all\")}\n className=\"w-7 h-7 rounded border bg-gray-50 border-gray-300 text-[9px] text-gray-600 hover:bg-gray-100\"\n title=\"전체\"\n >\n +\n </button>\n {sideBtn(\"right\", \"R\")}\n <div />\n {sideBtn(\"bottom\", \"B\")}\n <div />\n </div>\n <div className=\"flex flex-col gap-0.5 ml-2\">\n <button\n onClick={() => selectPreset(\"all\")}\n className=\"text-[10px] px-2 py-0.5 border border-gray-200 rounded hover:bg-gray-50\"\n >\n 전체\n </button>\n <button\n onClick={() => selectPreset(\"none\")}\n className=\"text-[10px] px-2 py-0.5 border border-gray-200 rounded hover:bg-gray-50\"\n >\n 없음\n </button>\n </div>\n </div>\n </div>\n <SidebarField label=\"종류\">\n <select\n value={borderType}\n disabled={!hasCell}\n onChange={(e) => setBorderType(e.target.value)}\n className={inputClass}\n >\n {BORDER_TYPES.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"굵기\">\n <select\n value={borderWidth}\n disabled={!hasCell}\n onChange={(e) => setBorderWidth(e.target.value)}\n className={inputClass}\n >\n {BORDER_WIDTHS.map((w) => (\n <option key={w} value={w}>\n {w}\n </option>\n ))}\n </select>\n </SidebarField>\n <SidebarField label=\"색상\">\n <input\n type=\"color\"\n value={borderColor}\n disabled={!hasCell}\n onChange={(e) => setBorderColor(e.target.value)}\n className=\"w-full h-6 p-0 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n <button\n disabled={!hasCell || selectedSides.size === 0}\n onClick={applyBorder}\n className=\"w-full mt-1 py-1.5 rounded bg-blue-600 text-white text-[11px] font-medium hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n 테두리 적용\n </button>\n </SidebarSection>\n\n {/* Background section */}\n <SidebarSection title=\"배경\">\n <div className=\"flex items-center gap-2 mb-2\">\n <label className=\"flex items-center gap-1 text-[11px] text-gray-600\">\n <input\n type=\"checkbox\"\n checked={noBg}\n onChange={(e) => {\n setNoBg(e.target.checked);\n if (e.target.checked && hasCell) setCellBackground(null);\n }}\n className=\"w-3 h-3\"\n />\n 없음\n </label>\n </div>\n {!noBg && (\n <SidebarField label=\"색상\">\n <input\n type=\"color\"\n value={bgColor}\n disabled={!hasCell}\n onChange={(e) => {\n setBgColor(e.target.value);\n if (hasCell) setCellBackground(e.target.value);\n }}\n className=\"w-full h-6 p-0 border border-gray-300 rounded cursor-pointer disabled:opacity-40\"\n />\n </SidebarField>\n )}\n </SidebarSection>\n\n {/* Vertical align section */}\n <SidebarSection title=\"세로 정렬\">\n <div className=\"flex gap-1\">\n {vertAlignBtn(\"TOP\", AlignVerticalJustifyStart, \"위\")}\n {vertAlignBtn(\"CENTER\", AlignVerticalJustifyCenter, \"가운데\")}\n {vertAlignBtn(\"BOTTOM\", AlignVerticalJustifyEnd, \"아래\")}\n </div>\n </SidebarSection>\n\n {/* Cell margin section */}\n <SidebarSection title=\"셀 여백\" defaultOpen={false}>\n <SidebarField label=\"위 (mm)\">\n <input\n type=\"number\"\n value={marginTop}\n disabled={!hasCell}\n step={0.1}\n min={0}\n onChange={(e) => setMarginTop(Number(e.target.value))}\n onBlur={() => hasCell && applyMargin()}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasCell) applyMargin(); }}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"아래 (mm)\">\n <input\n type=\"number\"\n value={marginBottom}\n disabled={!hasCell}\n step={0.1}\n min={0}\n onChange={(e) => setMarginBottom(Number(e.target.value))}\n onBlur={() => hasCell && applyMargin()}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasCell) applyMargin(); }}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"왼쪽 (mm)\">\n <input\n type=\"number\"\n value={marginLeft}\n disabled={!hasCell}\n step={0.1}\n min={0}\n onChange={(e) => setMarginLeft(Number(e.target.value))}\n onBlur={() => hasCell && applyMargin()}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasCell) applyMargin(); }}\n className={inputClass}\n />\n </SidebarField>\n <SidebarField label=\"오른쪽 (mm)\">\n <input\n type=\"number\"\n value={marginRight}\n disabled={!hasCell}\n step={0.1}\n min={0}\n onChange={(e) => setMarginRight(Number(e.target.value))}\n onBlur={() => hasCell && applyMargin()}\n onKeyDown={(e) => { if (e.key === \"Enter\" && hasCell) applyMargin(); }}\n className={inputClass}\n />\n </SidebarField>\n </SidebarSection>\n </div>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback, useEffect } from \"react\";\nimport type { ParagraphVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { RunSpan } from \"./RunSpan\";\nimport { TableBlock } from \"./TableBlock\";\nimport { ImageBlock } from \"./ImageBlock\";\nimport { TextBoxBlock } from \"./TextBoxBlock\";\nimport { EquationBlock } from \"./EquationBlock\";\n\ninterface ParagraphBlockProps {\n paragraph: ParagraphVM;\n sectionIndex: number;\n /** Index of this paragraph within the section's paragraphs array */\n localIndex: number;\n /** Total number of paragraphs in this section (for merge/delete bounds) */\n paragraphCount: number;\n}\n\nfunction alignmentToCSS(alignment: string): React.CSSProperties[\"textAlign\"] {\n switch (alignment.toUpperCase()) {\n case \"CENTER\":\n return \"center\";\n case \"RIGHT\":\n return \"right\";\n case \"JUSTIFY\":\n case \"DISTRIBUTE\":\n return \"justify\";\n default:\n return \"left\";\n }\n}\n\nexport function ParagraphBlock({\n paragraph,\n sectionIndex,\n localIndex,\n paragraphCount,\n}: ParagraphBlockProps) {\n const updateParagraphText = useEditorStore((s) => s.updateParagraphText);\n const setSelection = useEditorStore((s) => s.setSelection);\n const selection = useEditorStore((s) => s.selection);\n const splitParagraph = useEditorStore((s) => s.splitParagraph);\n const mergeParagraphWithPrevious = useEditorStore((s) => s.mergeParagraphWithPrevious);\n const deleteBlock = useEditorStore((s) => s.deleteBlock);\n const ref = useRef<HTMLDivElement>(null);\n\n const revision = useEditorStore((s) => s.revision);\n const hasTables = paragraph.tables.length > 0;\n const hasImages = paragraph.images.length > 0;\n const hasTextBoxes = paragraph.textBoxes.length > 0;\n const hasEquations = paragraph.equations.length > 0;\n const hasText = paragraph.runs.length > 0;\n\n // Auto-focus when this paragraph is selected (e.g. after splitParagraph)\n useEffect(() => {\n if (\n selection &&\n selection.sectionIndex === sectionIndex &&\n selection.paragraphIndex === localIndex &&\n ref.current &&\n document.activeElement !== ref.current\n ) {\n ref.current.focus();\n // Place cursor at start\n const sel = window.getSelection();\n if (sel) {\n sel.selectAllChildren(ref.current);\n sel.collapseToStart();\n }\n }\n }, [revision, sectionIndex, localIndex, selection]);\n\n const handleBlur = useCallback(() => {\n if (!ref.current) return;\n const newText = ref.current.textContent ?? \"\";\n // Only sync text paragraphs (no tables/images)\n if (!hasTables && !hasImages) {\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (newText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, newText);\n }\n }\n }, [paragraph, sectionIndex, localIndex, hasTables, hasImages, updateParagraphText]);\n\n const handleFocus = useCallback(() => {\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n });\n }, [sectionIndex, localIndex, setSelection]);\n\n // Track text selection changes within this paragraph\n const updateTextSelection = useCallback(() => {\n if (!ref.current) return;\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0) return;\n\n // Check if selection is within this paragraph\n const range = sel.getRangeAt(0);\n if (!ref.current.contains(range.commonAncestorContainer)) return;\n\n // Calculate start and end offsets relative to the entire paragraph text\n const preRangeStart = document.createRange();\n preRangeStart.selectNodeContents(ref.current);\n preRangeStart.setEnd(range.startContainer, range.startOffset);\n const startOffset = preRangeStart.toString().length;\n\n const preRangeEnd = document.createRange();\n preRangeEnd.selectNodeContents(ref.current);\n preRangeEnd.setEnd(range.endContainer, range.endOffset);\n const endOffset = preRangeEnd.toString().length;\n\n // Only update if there's an actual selection (not just cursor)\n if (startOffset !== endOffset) {\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n textStartOffset: startOffset,\n textEndOffset: endOffset,\n });\n } else {\n // Clear text range when selection is collapsed (cursor only)\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n });\n }\n }, [sectionIndex, localIndex, setSelection]);\n\n // Listen for selection changes\n useEffect(() => {\n const handleSelectionChange = () => {\n if (document.activeElement === ref.current) {\n updateTextSelection();\n }\n };\n\n document.addEventListener(\"selectionchange\", handleSelectionChange);\n return () => {\n document.removeEventListener(\"selectionchange\", handleSelectionChange);\n };\n }, [updateTextSelection]);\n\n const insertTab = useEditorStore((s) => s.insertTab);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (hasTables || hasImages || hasTextBoxes || hasEquations) return;\n\n // Tab key: insert tab character\n if (e.key === \"Tab\" && !e.shiftKey && !e.ctrlKey && !e.metaKey) {\n e.preventDefault();\n insertTab();\n return;\n }\n\n // Block Shift+Enter (no soft line break)\n if (e.key === \"Enter\" && e.shiftKey) {\n e.preventDefault();\n return;\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n // Flush current text before split\n const currentText = ref.current?.textContent ?? \"\";\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (currentText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, currentText);\n }\n\n // Get cursor offset within the text\n const sel = window.getSelection();\n let offset = currentText.length;\n if (sel && sel.rangeCount > 0 && ref.current) {\n const range = sel.getRangeAt(0);\n const preRange = document.createRange();\n preRange.selectNodeContents(ref.current);\n preRange.setEnd(range.startContainer, range.startOffset);\n offset = preRange.toString().length;\n }\n\n splitParagraph(sectionIndex, localIndex, offset);\n return;\n }\n\n if (e.key === \"Backspace\") {\n const sel = window.getSelection();\n if (sel && sel.isCollapsed && sel.rangeCount > 0 && ref.current) {\n const range = sel.getRangeAt(0);\n const preRange = document.createRange();\n preRange.selectNodeContents(ref.current);\n preRange.setEnd(range.startContainer, range.startOffset);\n const offset = preRange.toString().length;\n\n if (offset === 0 && localIndex > 0) {\n e.preventDefault();\n // Flush current text\n const currentText = ref.current.textContent ?? \"\";\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (currentText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, currentText);\n }\n mergeParagraphWithPrevious(sectionIndex, localIndex);\n return;\n }\n }\n }\n\n if (e.key === \"Delete\") {\n const sel = window.getSelection();\n if (sel && sel.isCollapsed && sel.rangeCount > 0 && ref.current) {\n const fullText = ref.current.textContent ?? \"\";\n const range = sel.getRangeAt(0);\n const preRange = document.createRange();\n preRange.selectNodeContents(ref.current);\n preRange.setEnd(range.startContainer, range.startOffset);\n const offset = preRange.toString().length;\n\n // At end of paragraph: merge with next\n if (offset >= fullText.length && localIndex < paragraphCount - 1) {\n e.preventDefault();\n // Flush current text\n const oldText = paragraph.runs.map((r) => r.text).join(\"\");\n if (fullText !== oldText) {\n updateParagraphText(sectionIndex, localIndex, fullText);\n }\n // Merge next paragraph into this one (implemented as merging next with \"previous\" = current)\n const store = useEditorStore.getState();\n const doc = store.doc;\n if (!doc) return;\n store.pushUndo();\n const section = doc.sections[sectionIndex];\n if (!section) return;\n const nextPara = section.paragraphs[localIndex + 1];\n const currPara = section.paragraphs[localIndex];\n if (!nextPara || !currPara) return;\n const currText = currPara.text;\n const nextText = nextPara.text;\n currPara.text = currText + nextText;\n doc.removeParagraph(sectionIndex, localIndex + 1);\n store.rebuild();\n return;\n }\n }\n }\n // Arrow key navigation between paragraphs\n if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\n const sel = window.getSelection();\n if (!sel || !sel.isCollapsed || !sel.rangeCount || !ref.current) return;\n\n const range = sel.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n const containerRect = ref.current.getBoundingClientRect();\n\n const atTop = rect.top <= containerRect.top + 2;\n const atBottom = rect.bottom >= containerRect.bottom - 2;\n\n if (e.key === \"ArrowUp\" && atTop && localIndex > 0) {\n e.preventDefault();\n const prev = ref.current.parentElement\n ? ref.current.previousElementSibling as HTMLElement | null\n : null;\n // Find previous contenteditable sibling within the page\n const page = ref.current.closest(\"[data-page]\") ?? ref.current.parentElement;\n if (page) {\n const editables = page.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const arr = Array.from(editables);\n const idx = arr.indexOf(ref.current);\n if (idx > 0) {\n const target = arr[idx - 1]!;\n target.focus();\n // Place cursor at end\n const s = window.getSelection();\n if (s) { s.selectAllChildren(target); s.collapseToEnd(); }\n }\n }\n return;\n }\n\n if (e.key === \"ArrowDown\" && atBottom && localIndex < paragraphCount - 1) {\n e.preventDefault();\n const page = ref.current.closest(\"[data-page]\") ?? ref.current.parentElement;\n if (page) {\n const editables = page.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const arr = Array.from(editables);\n const idx = arr.indexOf(ref.current);\n if (idx >= 0 && idx < arr.length - 1) {\n const target = arr[idx + 1]!;\n target.focus();\n // Place cursor at start\n const s = window.getSelection();\n if (s) { s.selectAllChildren(target); s.collapseToStart(); }\n }\n }\n return;\n }\n }\n },\n [sectionIndex, localIndex, paragraph, hasTables, hasImages, hasTextBoxes, hasEquations, paragraphCount, splitParagraph, mergeParagraphWithPrevious, deleteBlock, updateParagraphText, insertTab],\n );\n\n // Common paragraph styles (includes base font for contentEditable typing)\n const paraStyle: React.CSSProperties = {\n textAlign: alignmentToCSS(paragraph.alignment),\n lineHeight: paragraph.lineSpacing,\n marginLeft: paragraph.marginLeftPx || undefined,\n marginRight: paragraph.marginRightPx || undefined,\n textIndent: paragraph.firstLineIndent || undefined,\n paddingTop: paragraph.spacingBefore || undefined,\n paddingBottom: paragraph.spacingAfter || undefined,\n fontSize: paragraph.defaultFontSize ? `${paragraph.defaultFontSize}pt` : undefined,\n fontFamily: paragraph.defaultFontFamily || undefined,\n };\n\n // If paragraph has tables, render them\n if (hasTables) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.tables.map((table) => (\n <TableBlock\n key={table.tableIndex}\n table={table}\n sectionIndex={sectionIndex}\n paragraphIndex={localIndex}\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has images, render them (possibly alongside text)\n if (hasImages) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.images.map((img, i) => (\n <ImageBlock\n key={i}\n image={img}\n selected={\n selection?.sectionIndex === sectionIndex &&\n selection?.paragraphIndex === localIndex &&\n selection?.objectType === \"image\" &&\n selection?.imageIndex === i\n }\n onClick={() =>\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n objectType: \"image\",\n imageIndex: i,\n })\n }\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has text boxes, render them\n if (hasTextBoxes) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n className=\"outline-none leading-relaxed\"\n >\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </div>\n )}\n {paragraph.textBoxes.map((tb, i) => (\n <TextBoxBlock\n key={i}\n textBox={tb}\n selected={\n selection?.sectionIndex === sectionIndex &&\n selection?.paragraphIndex === localIndex &&\n selection?.objectType === \"textBox\" &&\n selection?.textBoxIndex === i\n }\n onClick={() =>\n setSelection({\n sectionIndex,\n paragraphIndex: localIndex,\n type: \"paragraph\",\n objectType: \"textBox\",\n textBoxIndex: i,\n })\n }\n />\n ))}\n </div>\n );\n }\n\n // If paragraph has equations, render them\n if (hasEquations) {\n return (\n <div className=\"my-1\" style={paraStyle}>\n {hasText && (\n <span>\n {paragraph.runs.map((run, i) => (\n <RunSpan key={i} run={run} />\n ))}\n </span>\n )}\n {paragraph.equations.map((eq, i) => (\n <EquationBlock key={i} equation={eq} />\n ))}\n </div>\n );\n }\n\n // Normal text paragraph\n return (\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n className=\"outline-none min-h-[1.5em]\"\n style={paraStyle}\n >\n {paragraph.runs.length > 0 ? (\n paragraph.runs.map((run, i) => <RunSpan key={i} run={run} />)\n ) : (\n <br />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport type { RunVM } from \"@/lib/view-model\";\n\ninterface RunSpanProps {\n run: RunVM;\n tabWidth?: number; // Tab width in pixels, default 40\n}\n\nexport function RunSpan({ run, tabWidth = 40 }: RunSpanProps) {\n const style: React.CSSProperties = {};\n\n if (run.bold) style.fontWeight = \"bold\";\n if (run.italic) style.fontStyle = \"italic\";\n\n // Text decoration (underline + strikethrough)\n const decorations: string[] = [];\n if (run.underline) decorations.push(\"underline\");\n if (run.strikethrough) decorations.push(\"line-through\");\n if (decorations.length > 0) style.textDecoration = decorations.join(\" \");\n\n if (run.color && run.color !== \"#000000\") style.color = run.color;\n if (run.fontFamily) {\n if (run.fontFamily === \"Noto Sans KR\") {\n style.fontFamily = \"var(--font-noto-sans-kr), sans-serif\";\n } else if (run.fontFamily === \"Noto Serif KR\") {\n style.fontFamily = \"var(--font-noto-serif-kr), serif\";\n } else {\n style.fontFamily = run.fontFamily;\n }\n }\n if (run.fontSize) style.fontSize = `${run.fontSize}pt`;\n if (run.highlightColor) style.backgroundColor = run.highlightColor;\n if (run.letterSpacing) {\n // hwp letter spacing units -> px approximation\n style.letterSpacing = `${run.letterSpacing / 100}px`;\n }\n\n // Render tab as fixed-width space\n if (run.hasTab) {\n return (\n <span\n style={{ display: \"inline-block\", width: tabWidth, ...style }}\n data-tab=\"true\"\n />\n );\n }\n\n // Render full-width space\n if (run.hasFwSpace) {\n return (\n <span style={style} data-fwspace=\"true\">\n {\"\\u3000\"}\n </span>\n );\n }\n\n // Render line break\n if (run.hasLineBreak) {\n return <br data-linebreak=\"true\" />;\n }\n\n // Render hyperlink\n if (run.hyperlink) {\n return (\n <a\n href={run.hyperlink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ ...style, color: style.color || \"#0066cc\", textDecoration: \"underline\" }}\n onClick={(e) => e.stopPropagation()}\n >\n {run.text}\n </a>\n );\n }\n\n return <span style={style}>{run.text}</span>;\n}\n","\"use client\";\n\nimport { useRef, useCallback } from \"react\";\nimport type { TableVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { pxToHwp, hwpToPx } from \"@/lib/hwp-units\";\nimport { TableCell } from \"./TableCell\";\n\ninterface TableBlockProps {\n table: TableVM;\n sectionIndex: number;\n paragraphIndex: number;\n}\n\n/** Invisible drag handle for column boundary. */\nfunction ColumnResizeHandle({\n colIdx,\n tableHeight,\n sectionIndex,\n paragraphIndex,\n tableIndex,\n}: {\n colIdx: number;\n tableHeight: number;\n sectionIndex: number;\n paragraphIndex: number;\n tableIndex: number;\n}) {\n const resizeTableColumn = useEditorStore((s) => s.resizeTableColumn);\n const startXRef = useRef(0);\n\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startXRef.current = e.clientX;\n\n const onMouseMove = (me: MouseEvent) => {\n // visual feedback is handled by cursor; actual resize on mouseup\n };\n\n const onMouseUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"\";\n const deltaX = me.clientX - startXRef.current;\n if (Math.abs(deltaX) < 2) return;\n const deltaHwp = pxToHwp(deltaX);\n resizeTableColumn(sectionIndex, paragraphIndex, tableIndex, colIdx, deltaHwp);\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"col-resize\";\n },\n [colIdx, sectionIndex, paragraphIndex, tableIndex, resizeTableColumn],\n );\n\n return (\n <div\n onMouseDown={onMouseDown}\n className=\"absolute top-0 z-10\"\n style={{\n width: 6,\n height: tableHeight || \"100%\",\n cursor: \"col-resize\",\n marginLeft: -3,\n }}\n />\n );\n}\n\nexport function TableBlock({ table, sectionIndex, paragraphIndex }: TableBlockProps) {\n const tableRef = useRef<HTMLDivElement>(null);\n const setSelection = useEditorStore((s) => s.setSelection);\n const selection = useEditorStore((s) => s.selection);\n\n // Check if this table is selected\n const isTableSelected =\n selection?.type === \"table\" &&\n selection.sectionIndex === sectionIndex &&\n selection.paragraphIndex === paragraphIndex &&\n selection.tableIndex === table.tableIndex;\n\n // Compute cumulative column positions for handle placement using columnWidths\n const colPositions: number[] = [];\n let cumX = 0;\n for (let c = 0; c < table.colCount; c++) {\n const widthHwp = table.columnWidths[c] ?? 0;\n cumX += hwpToPx(widthHwp);\n colPositions.push(cumX);\n }\n\n const tableHeightPx = tableRef.current?.offsetHeight ?? 0;\n\n const handleTableClick = useCallback(\n (e: React.MouseEvent) => {\n // Only select table if clicking on the table border area (not inside cells)\n const target = e.target as HTMLElement;\n if (target.tagName === \"TABLE\" || target.closest(\".table-select-area\")) {\n e.stopPropagation();\n setSelection({\n sectionIndex,\n paragraphIndex,\n type: \"table\",\n tableIndex: table.tableIndex,\n objectType: \"table\",\n });\n }\n },\n [sectionIndex, paragraphIndex, table.tableIndex, setSelection],\n );\n\n // Apply outMargin as margin around the table\n const marginTop = hwpToPx(table.outMargin.top) || 8;\n const marginBottom = hwpToPx(table.outMargin.bottom) || 8;\n const marginLeft = hwpToPx(table.outMargin.left) || 0;\n const marginRight = hwpToPx(table.outMargin.right) || 0;\n\n return (\n <div\n className=\"overflow-x-auto relative\"\n ref={tableRef}\n style={{ marginTop, marginBottom, marginLeft, marginRight }}\n >\n {/* Table selection handle - click to select entire table */}\n <div\n className=\"table-select-area absolute -left-6 top-0 w-5 h-5 cursor-pointer flex items-center justify-center hover:bg-blue-100 rounded\"\n onClick={handleTableClick}\n title=\"표 전체 선택\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" stroke=\"#666\" strokeWidth=\"1\" fill=\"none\" />\n <line x1=\"1\" y1=\"4\" x2=\"11\" y2=\"4\" stroke=\"#666\" strokeWidth=\"0.5\" />\n <line x1=\"1\" y1=\"8\" x2=\"11\" y2=\"8\" stroke=\"#666\" strokeWidth=\"0.5\" />\n <line x1=\"4\" y1=\"1\" x2=\"4\" y2=\"11\" stroke=\"#666\" strokeWidth=\"0.5\" />\n <line x1=\"8\" y1=\"1\" x2=\"8\" y2=\"11\" stroke=\"#666\" strokeWidth=\"0.5\" />\n </svg>\n </div>\n <table\n className={`border-collapse border border-gray-400 ${isTableSelected ? \"outline outline-2 outline-blue-500\" : \"\"}`}\n onClick={handleTableClick}\n >\n <tbody>\n {table.cells.map((row, rIdx) => (\n <tr key={rIdx}>\n {row.map((cell) =>\n cell.isAnchor ? (\n <TableCell\n key={`${cell.row}-${cell.col}`}\n cell={cell}\n sectionIndex={sectionIndex}\n paragraphIndex={paragraphIndex}\n tableIndex={table.tableIndex}\n inMargin={table.inMargin}\n />\n ) : null,\n )}\n </tr>\n ))}\n </tbody>\n </table>\n {/* Column resize handles at each column boundary */}\n {colPositions.map((pos, idx) => (\n <div\n key={idx}\n className=\"absolute top-0\"\n style={{ left: pos }}\n >\n <ColumnResizeHandle\n colIdx={idx}\n tableHeight={tableHeightPx}\n sectionIndex={sectionIndex}\n paragraphIndex={paragraphIndex}\n tableIndex={table.tableIndex}\n />\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useMemo, useRef, useCallback } from \"react\";\nimport type { TableCellVM, CellBorderStyleVM, MarginVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\n\ninterface TableCellProps {\n cell: TableCellVM;\n sectionIndex: number;\n paragraphIndex: number;\n tableIndex: number;\n inMargin?: MarginVM;\n}\n\nfunction borderToCss(b: CellBorderStyleVM | null | undefined): string {\n if (!b || b.type === \"NONE\") return \"1px solid #d1d5db\"; // fallback gray-300\n const widthStr = b.width.replace(/ /g, \"\");\n const mm = parseFloat(widthStr);\n const px = Math.max(Math.round(mm * 3.78), 1); // mm to px approx\n let cssStyle = \"solid\";\n switch (b.type) {\n case \"DASH\": cssStyle = \"dashed\"; break;\n case \"DOT\": cssStyle = \"dotted\"; break;\n case \"DASH_DOT\": cssStyle = \"dashed\"; break;\n case \"DOUBLE_SLIM\": case \"DOUBLE\": cssStyle = \"double\"; break;\n }\n return `${px}px ${cssStyle} ${b.color}`;\n}\n\nfunction vertAlignToCss(va: string): string {\n switch (va) {\n case \"TOP\": return \"top\";\n case \"BOTTOM\": return \"bottom\";\n default: return \"middle\";\n }\n}\n\nfunction isInRange(\n row: number, col: number, rowSpan: number, colSpan: number,\n r1: number, c1: number, r2: number, c2: number,\n): boolean {\n const minR = Math.min(r1, r2);\n const maxR = Math.max(r1, r2);\n const minC = Math.min(c1, c2);\n const maxC = Math.max(c1, c2);\n // Cell occupies rows [row, row+rowSpan-1] and cols [col, col+colSpan-1]\n return row + rowSpan - 1 >= minR && row <= maxR && col + colSpan - 1 >= minC && col <= maxC;\n}\n\nexport function TableCell({\n cell,\n sectionIndex,\n paragraphIndex,\n tableIndex,\n}: TableCellProps) {\n const updateCellText = useEditorStore((s) => s.updateCellText);\n const setSelection = useEditorStore((s) => s.setSelection);\n const selection = useEditorStore((s) => s.selection);\n const ref = useRef<HTMLTableCellElement>(null);\n\n const handleBlur = useCallback(() => {\n if (!ref.current) return;\n const newText = ref.current.textContent ?? \"\";\n if (newText !== cell.text) {\n updateCellText(\n sectionIndex,\n paragraphIndex,\n tableIndex,\n cell.row,\n cell.col,\n newText,\n );\n }\n }, [cell, sectionIndex, paragraphIndex, tableIndex, updateCellText]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (e.shiftKey && selection && selection.tableIndex === tableIndex && selection.row != null && selection.col != null) {\n // Shift+click: extend selection range\n e.preventDefault();\n setSelection({\n ...selection,\n endRow: cell.row,\n endCol: cell.col,\n });\n } else {\n // Normal click: single cell selection\n setSelection({\n sectionIndex,\n paragraphIndex,\n type: \"cell\",\n tableIndex,\n row: cell.row,\n col: cell.col,\n objectType: \"table\",\n });\n }\n }, [sectionIndex, paragraphIndex, tableIndex, cell.row, cell.col, setSelection, selection]);\n\n const handleFocus = useCallback(() => {\n if (!selection || selection.tableIndex !== tableIndex || selection.row !== cell.row || selection.col !== cell.col) {\n setSelection({\n sectionIndex,\n paragraphIndex,\n type: \"cell\",\n tableIndex,\n row: cell.row,\n col: cell.col,\n objectType: \"table\",\n });\n }\n }, [sectionIndex, paragraphIndex, tableIndex, cell.row, cell.col, setSelection, selection]);\n\n if (!cell.isAnchor) return null;\n\n // Determine if this cell is in the selected range\n const inRange = selection?.tableIndex === tableIndex\n && selection.row != null && selection.col != null\n && selection.endRow != null && selection.endCol != null\n && isInRange(cell.row, cell.col, cell.rowSpan, cell.colSpan, selection.row, selection.col, selection.endRow, selection.endCol);\n\n const cellBorders = cell.style;\n const hasCustomStyle = !!cellBorders;\n\n const tdStyle: React.CSSProperties = useMemo(() => {\n const s: React.CSSProperties = {\n minWidth: cell.widthPx > 0 ? cell.widthPx : 40,\n minHeight: cell.heightPx > 0 ? cell.heightPx : 24,\n verticalAlign: vertAlignToCss(cell.vertAlign),\n };\n if (hasCustomStyle) {\n s.borderLeft = borderToCss(cellBorders.borderLeft);\n s.borderRight = borderToCss(cellBorders.borderRight);\n s.borderTop = borderToCss(cellBorders.borderTop);\n s.borderBottom = borderToCss(cellBorders.borderBottom);\n if (cellBorders.backgroundColor && !inRange) {\n s.backgroundColor = cellBorders.backgroundColor;\n }\n }\n return s;\n }, [cell, cellBorders, hasCustomStyle, inRange]);\n\n return (\n <td\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n colSpan={cell.colSpan > 1 ? cell.colSpan : undefined}\n rowSpan={cell.rowSpan > 1 ? cell.rowSpan : undefined}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onMouseDown={handleMouseDown}\n className={`px-2 py-1 text-sm outline-none ${\n !hasCustomStyle ? \"border border-gray-300\" : \"\"\n } ${\n inRange ? \"bg-blue-100\" : (!hasCustomStyle || !cellBorders?.backgroundColor) ? \"focus:bg-blue-50\" : \"\"\n }`}\n style={tdStyle}\n >\n {cell.text}\n </td>\n );\n}\n","\"use client\";\n\nimport { useRef, useCallback, useState } from \"react\";\nimport type { ImageVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { pxToHwp } from \"@/lib/hwp-units\";\n\ninterface ImageBlockProps {\n image: ImageVM;\n selected?: boolean;\n onClick?: () => void;\n}\n\ntype HandlePosition = \"nw\" | \"n\" | \"ne\" | \"e\" | \"se\" | \"s\" | \"sw\" | \"w\";\n\nconst HANDLE_CURSORS: Record<HandlePosition, string> = {\n nw: \"nwse-resize\",\n n: \"ns-resize\",\n ne: \"nesw-resize\",\n e: \"ew-resize\",\n se: \"nwse-resize\",\n s: \"ns-resize\",\n sw: \"nesw-resize\",\n w: \"ew-resize\",\n};\n\nfunction ResizeHandle({\n position,\n onResize,\n}: {\n position: HandlePosition;\n onResize: (deltaW: number, deltaH: number) => void;\n}) {\n const startRef = useRef({ x: 0, y: 0 });\n\n const onMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startRef.current = { x: e.clientX, y: e.clientY };\n\n const onMouseUp = (me: MouseEvent) => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"\";\n\n let dx = me.clientX - startRef.current.x;\n let dy = me.clientY - startRef.current.y;\n\n // Map handle position to delta\n let dw = 0;\n let dh = 0;\n if (position.includes(\"e\")) dw = dx;\n if (position.includes(\"w\")) dw = -dx;\n if (position.includes(\"s\")) dh = dy;\n if (position.includes(\"n\")) dh = -dy;\n\n // Corner handles: maintain aspect ratio\n if (position === \"nw\" || position === \"ne\" || position === \"sw\" || position === \"se\") {\n // Use the larger delta as driver\n if (Math.abs(dw) > Math.abs(dh)) {\n dh = dw; // rough 1:1 aspect\n } else {\n dw = dh;\n }\n }\n\n if (Math.abs(dw) >= 2 || Math.abs(dh) >= 2) {\n onResize(pxToHwp(dw), pxToHwp(dh));\n }\n };\n\n const onMouseMove = (_me: MouseEvent) => {\n // visual feedback via cursor only\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = HANDLE_CURSORS[position];\n },\n [position, onResize],\n );\n\n // Position styles for each handle\n const posStyles: React.CSSProperties = { position: \"absolute\" };\n const SIZE = 8;\n const HALF = -SIZE / 2;\n\n switch (position) {\n case \"nw\": posStyles.top = HALF; posStyles.left = HALF; break;\n case \"n\": posStyles.top = HALF; posStyles.left = \"50%\"; posStyles.marginLeft = HALF; break;\n case \"ne\": posStyles.top = HALF; posStyles.right = HALF; break;\n case \"e\": posStyles.top = \"50%\"; posStyles.marginTop = HALF; posStyles.right = HALF; break;\n case \"se\": posStyles.bottom = HALF; posStyles.right = HALF; break;\n case \"s\": posStyles.bottom = HALF; posStyles.left = \"50%\"; posStyles.marginLeft = HALF; break;\n case \"sw\": posStyles.bottom = HALF; posStyles.left = HALF; break;\n case \"w\": posStyles.top = \"50%\"; posStyles.marginTop = HALF; posStyles.left = HALF; break;\n }\n\n return (\n <div\n onMouseDown={onMouseDown}\n className=\"bg-white border border-blue-500 z-20\"\n style={{\n ...posStyles,\n width: SIZE,\n height: SIZE,\n cursor: HANDLE_CURSORS[position],\n }}\n />\n );\n}\n\nconst HANDLES: HandlePosition[] = [\"nw\", \"n\", \"ne\", \"e\", \"se\", \"s\", \"sw\", \"w\"];\n\nexport function ImageBlock({ image, selected, onClick }: ImageBlockProps) {\n const resizeImage = useEditorStore((s) => s.resizeImage);\n\n const handleResize = useCallback(\n (dw: number, dh: number) => {\n resizeImage(dw, dh);\n },\n [resizeImage],\n );\n\n return (\n <div\n className=\"my-2 flex justify-center cursor-pointer\"\n onClick={(e) => {\n e.stopPropagation();\n onClick?.();\n }}\n >\n <div className=\"relative inline-block\">\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={image.dataUrl}\n alt=\"\"\n draggable={false}\n className={selected ? \"ring-2 ring-blue-500\" : \"\"}\n style={{\n width: image.widthPx > 0 ? image.widthPx : undefined,\n height: image.heightPx > 0 ? image.heightPx : undefined,\n maxWidth: \"100%\",\n display: \"block\",\n }}\n />\n {selected && HANDLES.map((pos) => (\n <ResizeHandle key={pos} position={pos} onResize={handleResize} />\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { TextBoxVM } from \"@/lib/view-model\";\n\ninterface TextBoxBlockProps {\n textBox: TextBoxVM;\n selected?: boolean;\n onClick?: () => void;\n}\n\nexport function TextBoxBlock({ textBox, selected, onClick }: TextBoxBlockProps) {\n return (\n <div\n className={`inline-block relative cursor-pointer ${selected ? \"ring-2 ring-blue-500\" : \"\"}`}\n style={{\n width: textBox.widthPx,\n minHeight: textBox.heightPx,\n backgroundColor: textBox.fillColor,\n border: `1px solid ${textBox.borderColor}`,\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n }}\n onClick={onClick}\n >\n <div className=\"whitespace-pre-wrap break-words text-sm\">\n {textBox.text || \"\\u00A0\"}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { EquationVM } from \"@/lib/view-model\";\n\ninterface EquationBlockProps {\n equation: EquationVM;\n}\n\n/**\n * Parse HWP equation script and convert to displayable text.\n * HWP equation language uses special syntax:\n * - _{x} for subscript\n * - ^{x} for superscript\n * - {A} over {B} for fraction\n * - root {n} of {x} for nth root\n * - int _{a} ^{b} for integral\n * - sum _{a} ^{b} for summation\n * - Special symbols: ALPHA, alpha, ohm, INF, etc.\n */\nfunction parseEquationScript(script: string): string {\n if (!script) return \"\";\n\n // Symbol replacements\n const symbols: Record<string, string> = {\n \"ALPHA\": \"\\u0391\", // Greek Alpha\n \"alpha\": \"\\u03B1\", // Greek alpha\n \"BETA\": \"\\u0392\",\n \"beta\": \"\\u03B2\",\n \"GAMMA\": \"\\u0393\",\n \"gamma\": \"\\u03B3\",\n \"DELTA\": \"\\u0394\",\n \"delta\": \"\\u03B4\",\n \"ohm\": \"\\u03A9\",\n \"INF\": \"\\u221E\",\n \"+-\": \"\\u00B1\",\n \"rarrow\": \"\\u2192\",\n \"larrow\": \"\\u2190\",\n \"LRARROW\": \"\\u2194\",\n \"CDOTS\": \"\\u22EF\",\n \"BOT\": \"\\u22A5\",\n \"RTANGLE\": \"\\u221F\",\n \"MSANGLE\": \"\\u2220\",\n \"SMALLSUM\": \"\\u2211\",\n \"vec\": \"\\u20D7\", // combining vector\n \"bar\": \"\\u0305\", // combining overline\n };\n\n let result = script;\n\n // Replace special symbols\n for (const [key, value] of Object.entries(symbols)) {\n result = result.replace(new RegExp(`\\\\b${key}\\\\b`, \"g\"), value);\n }\n\n // Handle subscripts: _{x} -> _x (simplified display)\n result = result.replace(/\\s*_\\s*\\{([^}]*)\\}/g, \"\\u2080$1\"); // Approximation\n\n // Handle superscripts: ^{x} -> ^x\n result = result.replace(/\\s*\\^\\s*\\{([^}]*)\\}/g, \"\\u00B2\"); // Approximation\n\n // Handle fractions: {A} over {B} -> A/B\n result = result.replace(/\\{([^}]*)\\}\\s*over\\s*\\{([^}]*)\\}/g, \"($1)/($2)\");\n\n // Handle roots: root {n} of {x} -> n√x\n result = result.replace(/root\\s*\\{([^}]*)\\}\\s*of\\s*\\{([^}]*)\\}/g, \"$1\\u221A$2\");\n\n // Handle integrals: int _{a} ^{b} -> ∫\n result = result.replace(/\\bint\\b/g, \"\\u222B\");\n result = result.replace(/\\bdint\\b/g, \"\\u222C\"); // double integral\n result = result.replace(/\\boint\\b/g, \"\\u222E\"); // contour integral\n\n // Handle sum\n result = result.replace(/\\bsum\\b/g, \"\\u2211\");\n\n // Handle lim\n result = result.replace(/\\blim\\b/g, \"lim\");\n\n // Remove remaining braces\n result = result.replace(/\\{([^}]*)\\}/g, \"$1\");\n\n // Handle line breaks in equation (# is line break in HWP equations)\n result = result.replace(/#/g, \"\\n\");\n\n // Clean up whitespace\n result = result.replace(/\\s+/g, \" \").trim();\n\n return result;\n}\n\nexport function EquationBlock({ equation }: EquationBlockProps) {\n const displayText = parseEquationScript(equation.script);\n\n return (\n <span\n className=\"inline-block font-serif italic\"\n style={{\n color: equation.textColor,\n minWidth: equation.widthPx,\n minHeight: equation.heightPx,\n verticalAlign: \"middle\",\n whiteSpace: \"pre-wrap\",\n }}\n title={equation.script}\n >\n {displayText || equation.script}\n </span>\n );\n}\n","\"use client\";\n\nimport type { SectionVM } from \"@/lib/view-model\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { ParagraphBlock } from \"./ParagraphBlock\";\n\ninterface PageProps {\n section: SectionVM;\n}\n\nexport function Page({ section }: PageProps) {\n const addParagraph = useEditorStore((s) => s.addParagraph);\n const revision = useEditorStore((s) => s.revision);\n const watermarkText = useEditorStore((s) => s.viewModel?.watermarkText ?? \"\");\n\n /** Clicking empty area of the page focuses or creates a paragraph */\n const handlePageClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Only react to clicks directly on the page container (not on child elements)\n if (e.target !== e.currentTarget) return;\n // If no paragraphs exist, create one\n if (section.paragraphs.length === 0) {\n addParagraph(\"\");\n return;\n }\n // Otherwise, focus the last paragraph's contenteditable\n const container = e.currentTarget;\n const editables = container.querySelectorAll<HTMLElement>(\"[contenteditable]\");\n const last = editables[editables.length - 1];\n if (last) {\n last.focus();\n // Place cursor at end\n const sel = window.getSelection();\n if (sel) {\n sel.selectAllChildren(last);\n sel.collapseToEnd();\n }\n }\n };\n\n const hasHeader = section.headerText.length > 0;\n const hasFooter = section.footerText.length > 0;\n const hasFootnotes = section.footnotes.length > 0;\n const hasEndnotes = section.endnotes.length > 0;\n const hasMultiColumn = section.columnLayout.colCount > 1;\n const pageNum = section.pageNum;\n\n // Format page number based on pageNum settings\n const formatPageNum = (num: number): string => {\n if (!pageNum) return String(num);\n let formatted = String(num);\n if (pageNum.formatType === \"ROMAN\") {\n // Convert to Roman numerals (simplified)\n const romanNumerals = [\"\", \"I\", \"II\", \"III\", \"IV\", \"V\", \"VI\", \"VII\", \"VIII\", \"IX\", \"X\"];\n formatted = romanNumerals[num] ?? String(num);\n }\n if (pageNum.sideChar) {\n formatted = `${pageNum.sideChar} ${formatted} ${pageNum.sideChar}`;\n }\n return formatted;\n };\n\n // Determine page number position\n const pageNumAtTop = pageNum?.pos?.startsWith(\"TOP\");\n const pageNumAtBottom = pageNum?.pos?.startsWith(\"BOTTOM\") || (pageNum && !pageNumAtTop);\n\n // Page border styling\n const hasPageBorder = section.pageBorderFill !== null;\n const pageBorderStyle: React.CSSProperties = hasPageBorder ? {\n border: \"1px solid #cccccc\",\n } : {};\n\n return (\n <div\n className=\"bg-white shadow-lg mx-auto mb-8 cursor-text relative overflow-hidden\"\n data-page\n onClick={handlePageClick}\n style={{\n width: section.pageWidthPx,\n minHeight: section.pageHeightPx,\n ...pageBorderStyle,\n }}\n >\n {/* Watermark overlay */}\n {watermarkText && (\n <div\n className=\"absolute inset-0 flex items-center justify-center pointer-events-none select-none z-0\"\n aria-hidden=\"true\"\n >\n <span\n className=\"text-gray-200 font-bold whitespace-nowrap\"\n style={{\n fontSize: Math.min(section.pageWidthPx * 0.12, 120),\n transform: \"rotate(-35deg)\",\n letterSpacing: \"0.15em\",\n opacity: 0.35,\n }}\n >\n {watermarkText}\n </span>\n </div>\n )}\n\n {/* Header area */}\n {(hasHeader || pageNumAtTop) && (\n <div\n className=\"text-center text-[10px] text-gray-400 border-b border-gray-100 relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingTop: Math.max(section.headerHeightPx, 8),\n paddingBottom: 4,\n }}\n >\n {hasHeader ? section.headerText.replace(\"{{page}}\", \"1\") : null}\n {pageNumAtTop && !hasHeader && formatPageNum(1)}\n </div>\n )}\n\n {/* Main content area */}\n <div\n className=\"relative z-10\"\n style={{\n paddingTop: hasHeader ? 4 : section.marginTopPx,\n paddingBottom: hasFooter || hasFootnotes || hasEndnotes ? 4 : section.marginBottomPx,\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n minHeight: section.pageHeightPx - section.marginTopPx - section.marginBottomPx,\n // Multi-column CSS\n ...(hasMultiColumn ? {\n columnCount: section.columnLayout.colCount,\n columnGap: section.columnLayout.sameGap || 20,\n columnRule: \"1px solid #e5e7eb\",\n } : {}),\n }}\n >\n {section.paragraphs.map((para, idx) => (\n <ParagraphBlock\n key={`${section.sectionIndex}-${idx}-r${revision}`}\n paragraph={para}\n sectionIndex={section.sectionIndex}\n localIndex={idx}\n paragraphCount={section.paragraphs.length}\n />\n ))}\n </div>\n\n {/* Footnotes area */}\n {hasFootnotes && (\n <div\n className=\"relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingBottom: 4,\n }}\n >\n <div className=\"border-t border-gray-300 pt-2 mt-2\" style={{ width: \"40%\" }}>\n {section.footnotes.map((fn) => (\n <div key={fn.marker} className=\"text-[9px] text-gray-500 leading-relaxed mb-0.5\">\n <sup className=\"text-[8px] font-medium mr-0.5\">{fn.marker}</sup>\n {fn.text}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Endnotes area (rendered at section end) */}\n {hasEndnotes && (\n <div\n className=\"relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingBottom: 4,\n }}\n >\n <div className=\"border-t-2 border-gray-300 pt-2 mt-4\">\n <div className=\"text-[9px] text-gray-400 font-medium mb-1\">미주</div>\n {section.endnotes.map((en) => (\n <div key={en.marker} className=\"text-[9px] text-gray-500 leading-relaxed mb-0.5\">\n <sup className=\"text-[8px] font-medium mr-0.5\">{en.marker}</sup>\n {en.text}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Footer area */}\n {(hasFooter || pageNumAtBottom) && (\n <div\n className=\"text-center text-[10px] text-gray-400 border-t border-gray-100 relative z-10\"\n style={{\n paddingLeft: section.marginLeftPx,\n paddingRight: section.marginRightPx,\n paddingTop: 4,\n paddingBottom: Math.max(section.footerHeightPx, 8),\n }}\n >\n {hasFooter ? section.footerText.replace(\"{{page}}\", \"1\") : null}\n {pageNumAtBottom && !hasFooter && formatPageNum(1)}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEditorStore } from \"@/lib/store\";\nimport { Page } from \"./Page\";\n\nexport function PageView() {\n const viewModel = useEditorStore((s) => s.viewModel);\n // Subscribe to revision to trigger re-render\n useEditorStore((s) => s.revision);\n\n if (!viewModel) {\n return (\n <div className=\"flex-1 flex items-center justify-center text-gray-400\">\n 문서를 열거나 새 문서를 만드세요.\n </div>\n );\n }\n\n return (\n <div className=\"flex-1 overflow-auto bg-gray-200 py-8\">\n {viewModel.sections.map((section) => (\n <Page key={section.sectionIndex} section={section} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\n\nexport function SaveDialog() {\n const saveDialogOpen = useEditorStore((s) => s.uiState.saveDialogOpen);\n const closeSaveDialog = useEditorStore((s) => s.closeSaveDialog);\n const saveDocumentAs = useEditorStore((s) => s.saveDocumentAs);\n const [filename, setFilename] = useState(\"document\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (saveDialogOpen) {\n setFilename(\"document\");\n // Focus and select text after modal opens\n setTimeout(() => {\n inputRef.current?.focus();\n inputRef.current?.select();\n }, 0);\n }\n }, [saveDialogOpen]);\n\n if (!saveDialogOpen) return null;\n\n const handleSave = () => {\n const name = filename.trim();\n if (!name) return;\n saveDocumentAs(name);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleSave();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n closeSaveDialog();\n }\n };\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40\"\n onClick={(e) => {\n if (e.target === e.currentTarget) closeSaveDialog();\n }}\n >\n <div className=\"bg-white rounded-lg shadow-xl w-96 p-5\">\n <h2 className=\"text-sm font-semibold text-gray-800 mb-4\">\n 다른 이름으로 저장\n </h2>\n\n <label className=\"block text-xs text-gray-600 mb-1.5\">파일 이름</label>\n <div className=\"flex items-center gap-0 mb-5\">\n <input\n ref={inputRef}\n type=\"text\"\n value={filename}\n onChange={(e) => setFilename(e.target.value)}\n onKeyDown={handleKeyDown}\n className=\"flex-1 h-8 px-2 text-sm border border-gray-300 rounded-l focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500\"\n placeholder=\"파일 이름 입력\"\n />\n <span className=\"h-8 px-2 flex items-center text-sm text-gray-500 bg-gray-100 border border-l-0 border-gray-300 rounded-r\">\n .hwpx\n </span>\n </div>\n\n <div className=\"flex justify-end gap-2\">\n <button\n onClick={closeSaveDialog}\n className=\"px-4 py-1.5 text-xs rounded border border-gray-300 text-gray-600 hover:bg-gray-50\"\n >\n 취소\n </button>\n <button\n onClick={handleSave}\n disabled={!filename.trim()}\n className=\"px-4 py-1.5 text-xs rounded bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed\"\n >\n 저장\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useState, useRef } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport { HwpxDocument } from \"@ubermensch1218/hwpxcore\";\nimport { useEditorStore } from \"@/lib/store\";\n\nexport function FileUpload() {\n const setDocument = useEditorStore((s) => s.setDocument);\n const setLoading = useEditorStore((s) => s.setLoading);\n const setError = useEditorStore((s) => s.setError);\n\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const openFile = useCallback(\n async (file: File) => {\n setLoading(true);\n setError(null);\n try {\n const buffer = await file.arrayBuffer();\n const doc = await HwpxDocument.open(buffer);\n setDocument(doc);\n } catch (e) {\n console.error(\"Failed to open file:\", e);\n setError(\"파일을 열 수 없습니다. HWPX 파일인지 확인하세요.\");\n } finally {\n setLoading(false);\n }\n },\n [setDocument, setLoading, setError],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const file = e.dataTransfer.files[0];\n if (file) openFile(file);\n },\n [openFile],\n );\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setDragging(true);\n }, []);\n\n const handleDragLeave = useCallback(() => {\n setDragging(false);\n }, []);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) openFile(file);\n e.target.value = \"\";\n },\n [openFile],\n );\n\n return (\n <div\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onClick={() => inputRef.current?.click()}\n className={`cursor-pointer border-2 border-dashed rounded-lg p-8 text-center transition-colors ${\n dragging\n ? \"border-blue-400 bg-blue-50\"\n : \"border-gray-300 hover:border-gray-400\"\n }`}\n >\n <Upload className=\"w-10 h-10 mx-auto mb-3 text-gray-400\" />\n <p className=\"text-gray-600 font-medium\">\n HWPX 파일을 드래그하거나 클릭하여 선택\n </p>\n <p className=\"text-sm text-gray-400 mt-1\">.hwpx 파일만 지원</p>\n <input\n ref={inputRef}\n type=\"file\"\n accept=\".hwpx\"\n className=\"hidden\"\n onChange={handleChange}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { FilePlus } from \"lucide-react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { createNewDocument } from \"@/lib/skeleton-loader\";\n\nexport function NewDocumentButton() {\n const setDocument = useEditorStore((s) => s.setDocument);\n const setLoading = useEditorStore((s) => s.setLoading);\n const setError = useEditorStore((s) => s.setError);\n\n const handleClick = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const doc = await createNewDocument();\n setDocument(doc);\n } catch (e) {\n console.error(\"Failed to create new document:\", e);\n setError(\"새 문서를 만들 수 없습니다.\");\n } finally {\n setLoading(false);\n }\n }, [setDocument, setLoading, setError]);\n\n return (\n <button\n onClick={handleClick}\n className=\"flex items-center gap-2 px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors\"\n >\n <FilePlus className=\"w-5 h-5\" />\n 새 문서\n </button>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { FONT_FAMILIES, COLOR_PRESETS } from \"@/lib/constants\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TABS = [\"기본\", \"확장\", \"테두리/배경\"];\n\n// ── Tab 1: 기본 (Basic) ──────────────────────────────────────────────────────\n\nfunction BasicTab() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const cf = extendedFormat.char;\n\n const [fontSize, setFontSize] = useState(cf.fontSize ?? 10);\n const [fontFamily, setFontFamily] = useState(cf.fontFamily ?? \"함초롬바탕\");\n const [relativeSize, setRelativeSize] = useState(100);\n const [charWidth, setCharWidth] = useState(100);\n const [charPosition, setCharPosition] = useState(0);\n const [letterSpacing, setLetterSpacing] = useState(cf.letterSpacing ?? 0);\n const [textColor, setTextColor] = useState(cf.textColor ?? \"#000000\");\n const [highlightColor, setHighlightColor] = useState(cf.highlightColor ?? \"\");\n\n const [bold, setBold] = useState(cf.bold);\n const [italic, setItalic] = useState(cf.italic);\n const [underline, setUnderline] = useState(cf.underline);\n const [strikethrough, setStrikethrough] = useState(cf.strikethrough);\n\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 기준 크기 */}\n <div className=\"flex items-center gap-2 mb-4\">\n <span className=\"text-xs text-gray-700 w-16\">기준 크기</span>\n <input\n type=\"number\"\n step=\"0.5\"\n min={1}\n max={200}\n value={fontSize}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className={`${inputClass} w-20`}\n />\n <select className={`${selectClass} w-14`} defaultValue=\"pt\">\n <option value=\"pt\">pt</option>\n </select>\n </div>\n\n {/* 언어별 설정 */}\n <DialogSection title=\"언어별 설정\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-14\">언어</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"대표\">\n <option>대표</option>\n <option>한글</option>\n <option>영어</option>\n <option>한자</option>\n <option>일어</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">글꼴</span>\n <select\n className={`${selectClass} flex-1`}\n value={fontFamily}\n onChange={(e) => setFontFamily(e.target.value)}\n >\n {FONT_FAMILIES.map((f) => (\n <option key={f} value={f}>{f}</option>\n ))}\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-14\">상대 크기</span>\n <input type=\"number\" value={relativeSize} onChange={(e) => setRelativeSize(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">장평</span>\n <input type=\"number\" value={charWidth} onChange={(e) => setCharWidth(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-14\">글자 위치</span>\n <input type=\"number\" value={charPosition} onChange={(e) => setCharPosition(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">자간</span>\n <input type=\"number\" value={letterSpacing} onChange={(e) => setLetterSpacing(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n </div>\n </DialogSection>\n\n {/* 속성 */}\n <DialogSection title=\"속성\">\n {/* Attribute buttons - styled A buttons */}\n <div className=\"flex gap-1.5 mb-3 flex-wrap\">\n {[\n { label: \"A\", style: \"font-bold\", title: \"굵게\", active: bold, toggle: () => setBold(!bold) },\n { label: \"A\", style: \"italic\", title: \"기울임\", active: italic, toggle: () => setItalic(!italic) },\n { label: \"A\", style: \"underline\", title: \"밑줄\", active: underline, toggle: () => setUnderline(!underline) },\n { label: \"A\", style: \"line-through\", title: \"취소선\", active: strikethrough, toggle: () => setStrikethrough(!strikethrough) },\n { label: \"A\", style: \"font-outline\", title: \"외곽선\", active: false, toggle: () => {} },\n { label: \"A\", style: \"text-shadow\", title: \"그림자\", active: false, toggle: () => {} },\n { label: \"A\", style: \"tracking-wider\", title: \"양각\", active: false, toggle: () => {} },\n { label: \"A\", style: \"tracking-tighter\", title: \"음각\", active: false, toggle: () => {} },\n ].map((attr, i) => (\n <button\n key={i}\n onClick={attr.toggle}\n title={attr.title}\n className={`w-10 h-10 rounded border text-lg flex items-center justify-center transition-colors ${\n attr.active\n ? \"bg-blue-50 border-blue-300 text-blue-700\"\n : \"bg-white border-gray-300 text-gray-700 hover:bg-gray-50\"\n }`}\n >\n <span className={attr.active ? attr.style : \"\"}>{attr.label}</span>\n </button>\n ))}\n {/* Spacer */}\n <div className=\"w-2\" />\n {/* Additional attribute buttons (위 첨자, 아래 첨자, etc.) */}\n {[\"위첨자\", \"아래첨자\", \"보통\"].map((title, i) => (\n <button\n key={`extra-${i}`}\n title={title}\n className=\"w-10 h-10 rounded border bg-white border-gray-300 text-gray-700 hover:bg-gray-50 flex items-center justify-center\"\n >\n <span className=\"text-[9px]\">{title.slice(0, 2)}</span>\n </button>\n ))}\n </div>\n\n {/* Color pickers */}\n <div className=\"flex items-center gap-6\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">글자 색</span>\n <div className=\"relative\">\n <input\n type=\"color\"\n value={textColor}\n onChange={(e) => setTextColor(e.target.value)}\n className=\"w-24 h-7 rounded border border-gray-300 cursor-pointer\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">음영 색</span>\n <select\n className={`${selectClass} w-28`}\n value={highlightColor}\n onChange={(e) => setHighlightColor(e.target.value)}\n >\n <option value=\"\">색 없음</option>\n {COLOR_PRESETS.map((c) => (\n <option key={c} value={c}>{c}</option>\n ))}\n </select>\n </div>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 2: 확장 (Extended) ────────────────────────────────────────────────────\n\nfunction ExtendedTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 그림자 */}\n <DialogSection title=\"그림자\">\n <div className=\"flex items-center gap-6 mb-2\">\n {[\"없음\", \"비연속\", \"연속\"].map((label, i) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"shadow\" defaultChecked={i === 0} className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-12\">X 방향</span>\n <input type=\"number\" disabled className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-12\">Y 방향</span>\n <input type=\"number\" disabled className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n </div>\n <div className=\"flex items-center gap-2 mt-2\">\n <span className=\"text-xs text-gray-400 w-12\">색</span>\n <select disabled className={`${selectClass} flex-1`}>\n <option>검정</option>\n </select>\n </div>\n </DialogSection>\n\n {/* 밑줄 */}\n <DialogSection title=\"밑줄\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">위치</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"없음\">\n <option>없음</option>\n <option>글자 아래</option>\n <option>글자 가운데</option>\n <option>글자 위</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-10\">색</span>\n <select disabled className={`${selectClass} flex-1`}>\n <option>검정</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-400 w-10\">종류</span>\n <select disabled className={`${selectClass} flex-1`}>\n <option>실선</option>\n </select>\n </div>\n </div>\n </DialogSection>\n\n {/* 취소선 */}\n <DialogSection title=\"취소선\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">모양</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>실선</option>\n <option>이중선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">색</span>\n <input type=\"color\" defaultValue=\"#000000\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n </div>\n </DialogSection>\n\n {/* 기타 */}\n <DialogSection title=\"기타\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">외곽선</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"없음\">\n <option>없음</option>\n <option>실선</option>\n <option>이중선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">강조점</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"없음\">\n <option>없음</option>\n <option>점</option>\n <option>원</option>\n </select>\n </div>\n </div>\n <div className=\"flex items-center gap-6 mt-2\">\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 글꼴에 어울리는 빈 칸\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 커닝\n </label>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 3: 테두리/배경 (Border/Background) ────────────────────────────────────\n\nfunction BorderBackgroundTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 테두리 */}\n <DialogSection title=\"테두리\">\n <div className=\"flex gap-4\">\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">종류</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>실선</option>\n <option>점선</option>\n <option>파선</option>\n <option>이중선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">굵기</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"0.1 mm\">\n <option>0.1 mm</option>\n <option>0.12 mm</option>\n <option>0.15 mm</option>\n <option>0.2 mm</option>\n <option>0.3 mm</option>\n <option>0.4 mm</option>\n <option>0.5 mm</option>\n <option>1.0 mm</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">색</span>\n <input type=\"color\" defaultValue=\"#000000\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n </div>\n {/* Preview */}\n <div className=\"w-44 h-28 border border-gray-300 rounded bg-white flex items-center justify-center\">\n <span className=\"text-[10px] text-gray-300\">미리보기</span>\n </div>\n </div>\n </DialogSection>\n\n {/* 배경 */}\n <DialogSection title=\"배경\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">면 색</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"색 없음\">\n <option>색 없음</option>\n <option>흰색</option>\n <option>검정</option>\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2 mt-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 색</span>\n <input type=\"color\" defaultValue=\"#c0c0c0\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 모양</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"\">\n <option value=\"\">없음</option>\n </select>\n </div>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Main Dialog ───────────────────────────────────────────────────────────────\n\nexport function CharFormatDialog() {\n const open = useEditorStore((s) => s.uiState.charFormatDialogOpen);\n const closeCharFormatDialog = useEditorStore((s) => s.closeCharFormatDialog);\n const [activeTab, setActiveTab] = useState(0);\n\n const handleApply = useCallback(() => {\n // Apply changes from the dialog\n // For now, close the dialog (values are already applied via sidebar)\n closeCharFormatDialog();\n }, [closeCharFormatDialog]);\n\n return (\n <Dialog title=\"글자 모양\" open={open} onClose={closeCharFormatDialog} onApply={handleApply} width={580}>\n <DialogTabs tabs={TABS} activeTab={activeTab} onTabChange={setActiveTab} />\n {activeTab === 0 && <BasicTab />}\n {activeTab === 1 && <ExtendedTab />}\n {activeTab === 2 && <BorderBackgroundTab />}\n\n {/* 미리보기 */}\n <div className=\"mt-4\">\n <div className=\"text-xs font-bold text-gray-800 mb-1.5\">미리보기</div>\n <div className=\"bg-white border border-gray-200 rounded-md p-4 min-h-[60px] flex items-end\">\n <span className=\"text-sm text-gray-600\">한글Eng123漢字あいう※☉</span>\n </div>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, type ReactNode } from \"react\";\n\ninterface DialogProps {\n title: string;\n open: boolean;\n onClose: () => void;\n onApply?: () => void;\n children: ReactNode;\n width?: number;\n}\n\nexport function Dialog({ title, open, onClose, onApply, children, width = 560 }: DialogProps) {\n const dialogRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-[100] flex items-center justify-center bg-black/30\">\n <div\n ref={dialogRef}\n className=\"bg-[#f0f0f0] rounded-lg shadow-2xl flex flex-col max-h-[90vh]\"\n style={{ width }}\n >\n {/* Title bar */}\n <div className=\"text-center py-2.5 text-sm font-medium text-gray-800 border-b border-gray-300/50\">\n {title}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto px-5 py-3\">\n {children}\n </div>\n\n {/* Footer with buttons */}\n <div className=\"flex justify-end gap-2 px-5 py-3 border-t border-gray-300/50\">\n <button\n onClick={onClose}\n className=\"px-6 py-1.5 text-sm bg-white border border-gray-300 rounded hover:bg-gray-50 text-gray-700\"\n >\n 취소\n </button>\n {onApply && (\n <button\n onClick={onApply}\n className=\"px-6 py-1.5 text-sm bg-blue-500 border border-blue-600 rounded hover:bg-blue-600 text-white font-medium\"\n >\n 설정\n </button>\n )}\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\ninterface DialogTabsProps {\n tabs: string[];\n activeTab: number;\n onTabChange: (index: number) => void;\n}\n\nexport function DialogTabs({ tabs, activeTab, onTabChange }: DialogTabsProps) {\n return (\n <div className=\"flex justify-center gap-0 mb-4\">\n {tabs.map((label, idx) => (\n <button\n key={label}\n onClick={() => onTabChange(idx)}\n className={`px-4 py-1.5 text-xs border transition-colors ${\n activeTab === idx\n ? \"bg-white border-gray-300 font-semibold text-gray-900 shadow-sm\"\n : \"bg-transparent border-transparent text-gray-500 hover:text-gray-700\"\n } ${idx === 0 ? \"rounded-l\" : \"\"} ${idx === tabs.length - 1 ? \"rounded-r\" : \"\"}`}\n >\n {label}\n </button>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\ninterface DialogSectionProps {\n title: string;\n children: ReactNode;\n}\n\nexport function DialogSection({ title, children }: DialogSectionProps) {\n return (\n <div className=\"mb-4\">\n <div className=\"text-xs font-bold text-gray-800 mb-1.5\">{title}</div>\n <div className=\"bg-gray-100 border border-gray-200 rounded-md p-3\">\n {children}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TABS = [\"기본\", \"확장\", \"탭 설정\", \"테두리/배경\"];\n\n// ── Tab 1: 기본 (Basic) ──────────────────────────────────────────────────────\n\nfunction BasicTab() {\n const extendedFormat = useEditorStore((s) => s.extendedFormat);\n const pf = extendedFormat.para;\n\n const [alignment, setAlignment] = useState<string>(pf.alignment);\n const [marginLeft, setMarginLeft] = useState(pf.indentLeft);\n const [marginRight, setMarginRight] = useState(pf.indentRight);\n const [firstLineMode, setFirstLineMode] = useState<\"보통\" | \"들여쓰기\" | \"내어쓰기\">(\"보통\");\n const [firstLineValue, setFirstLineValue] = useState(pf.firstLineIndent);\n const [lineSpacingType] = useState(\"글자에 따라\");\n const [lineSpacingValue, setLineSpacingValue] = useState(Math.round(pf.lineSpacing * 100));\n const [spacingBefore, setSpacingBefore] = useState(pf.spacingBefore);\n const [spacingAfter, setSpacingAfter] = useState(pf.spacingAfter);\n\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n const alignments: { value: string; label: string }[] = [\n { value: \"LEFT\", label: \"왼쪽 정렬\" },\n { value: \"CENTER\", label: \"가운데 정렬\" },\n { value: \"RIGHT\", label: \"오른쪽 정렬\" },\n { value: \"JUSTIFY\", label: \"양쪽 정렬\" },\n { value: \"DISTRIBUTE\", label: \"배분 정렬\" },\n { value: \"BOTH\", label: \"나눠쓰기\" },\n ];\n\n return (\n <>\n {/* 정렬 방식 */}\n <DialogSection title=\"정렬 방식\">\n <div className=\"flex gap-1.5\">\n {alignments.map((a) => (\n <button\n key={a.value}\n onClick={() => setAlignment(a.value)}\n title={a.label}\n className={`w-12 h-9 rounded border flex items-center justify-center transition-colors ${\n alignment === a.value\n ? \"bg-blue-50 border-blue-300\"\n : \"bg-white border-gray-300 hover:bg-gray-50\"\n }`}\n >\n <svg width=\"20\" height=\"14\" viewBox=\"0 0 20 14\" fill=\"none\">\n {a.value === \"LEFT\" && (\n <>\n <line x1=\"2\" y1=\"2\" x2=\"16\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"5\" x2=\"12\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"11\" x2=\"10\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n {a.value === \"CENTER\" && (\n <>\n <line x1=\"3\" y1=\"2\" x2=\"17\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"5\" y1=\"5\" x2=\"15\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"4\" y1=\"8\" x2=\"16\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"6\" y1=\"11\" x2=\"14\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n {a.value === \"RIGHT\" && (\n <>\n <line x1=\"4\" y1=\"2\" x2=\"18\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"8\" y1=\"5\" x2=\"18\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"6\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"10\" y1=\"11\" x2=\"18\" y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n {(a.value === \"JUSTIFY\" || a.value === \"DISTRIBUTE\" || a.value === \"BOTH\") && (\n <>\n <line x1=\"2\" y1=\"2\" x2=\"18\" y2=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"5\" x2=\"18\" y2=\"5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"8\" x2=\"18\" y2=\"8\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <line x1=\"2\" y1=\"11\" x2={a.value === \"JUSTIFY\" ? \"14\" : \"18\"} y2=\"11\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </>\n )}\n </svg>\n </button>\n ))}\n </div>\n </DialogSection>\n\n {/* 여백 + 첫 줄 */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <DialogSection title=\"여백\">\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">왼쪽</span>\n <input type=\"number\" step=\"0.1\" value={marginLeft} onChange={(e) => setMarginLeft(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">오른쪽</span>\n <input type=\"number\" step=\"0.1\" value={marginRight} onChange={(e) => setMarginRight(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n </div>\n </DialogSection>\n </div>\n <div className=\"flex-1\">\n <DialogSection title=\"첫 줄\">\n <div className=\"space-y-1.5\">\n {[\"보통\", \"들여쓰기\", \"내어쓰기\"].map((label) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input\n type=\"radio\"\n name=\"firstLine\"\n checked={firstLineMode === label}\n onChange={() => setFirstLineMode(label as typeof firstLineMode)}\n className=\"w-3.5 h-3.5\"\n />\n {label}\n </label>\n ))}\n <div className=\"flex items-center gap-1 mt-1\">\n <input\n type=\"number\"\n step=\"0.1\"\n value={firstLineValue}\n onChange={(e) => setFirstLineValue(Number(e.target.value))}\n disabled={firstLineMode === \"보통\"}\n className={`${inputClass} w-24 disabled:opacity-40`}\n />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n </div>\n </DialogSection>\n </div>\n </div>\n\n {/* 간격 */}\n <DialogSection title=\"간격\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">줄 간격</span>\n <select className={`${selectClass} flex-1`} defaultValue={lineSpacingType}>\n <option>글자에 따라</option>\n <option>고정 값</option>\n <option>최소</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">문단 위</span>\n <input type=\"number\" step=\"0.1\" value={spacingBefore} onChange={(e) => setSpacingBefore(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\" />\n <input type=\"number\" value={lineSpacingValue} onChange={(e) => setLineSpacingValue(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">문단 아래</span>\n <input type=\"number\" step=\"0.1\" value={spacingAfter} onChange={(e) => setSpacingAfter(Number(e.target.value))} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n </div>\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600 mt-2\">\n <input type=\"checkbox\" defaultChecked className=\"w-3.5 h-3.5\" />\n 편집 용지의 줄 격자 사용\n </label>\n </DialogSection>\n\n {/* 줄 나눔 기준 */}\n <DialogSection title=\"줄 나눔 기준\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">한글 단위</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"글자\">\n <option>글자</option>\n <option>어절</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">최소 공백</span>\n <input type=\"number\" defaultValue={100} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">%</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">영어 단위</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"단어\">\n <option>단어</option>\n <option>하이픈</option>\n </select>\n </div>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 2: 확장 (Extended) ────────────────────────────────────────────────────\n\nfunction ExtendedTab() {\n return (\n <>\n {/* 문단 종류 */}\n <DialogSection title=\"문단 종류\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-1.5\">\n {[\"없음\", \"글머리표 문단\", \"개요 문단\", \"번호 문단\"].map((label, i) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"paraType\" defaultChecked={i === 0} className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"flex items-center gap-2 mt-2\">\n <span className=\"text-xs text-gray-400 w-10\">수준</span>\n <select disabled className=\"h-7 px-2 text-xs border border-gray-300 rounded bg-white flex-1 disabled:opacity-40\">\n <option>1 수준</option>\n </select>\n </div>\n </DialogSection>\n\n {/* 기타 */}\n <DialogSection title=\"기타\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-1.5\">\n {[\n \"외톨이줄 보호\", \"다음 문단과 함께\",\n \"문단 보호\", \"문단 앞에서 항상 쪽 나눔\",\n \"글꼴에 어울리는 줄 높이\", \"한 줄로 입력\",\n \"한글과 영어 간격을 자동 조절\", \"한글과 숫자 간격을 자동 조절\",\n ].map((label) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"flex items-center gap-2 mt-3 pt-2 border-t border-gray-200\">\n <span className=\"text-xs text-gray-600 w-14\">세로 정렬</span>\n <select className=\"h-7 px-2 text-xs border border-gray-300 rounded bg-white flex-1\" defaultValue=\"글꼴 기준\">\n <option>글꼴 기준</option>\n <option>위쪽</option>\n <option>가운데</option>\n <option>아래쪽</option>\n </select>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 3: 탭 설정 (Tab Settings) ─────────────────────────────────────────────\n\nfunction TabSettingsTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 탭 종류 */}\n <DialogSection title=\"탭 종류\">\n <div className=\"flex items-center gap-4 mb-2\">\n {[\"왼쪽\", \"오른쪽\", \"가운데\", \"소수점\"].map((label, i) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"tabType\" defaultChecked={i === 0} className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">채울 모양</span>\n <select className={`${selectClass} w-28`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>점선</option>\n <option>실선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">탭 위치</span>\n <input type=\"number\" step=\"0.1\" defaultValue={5.0} className={`${inputClass} w-20`} />\n <span className=\"text-[10px] text-gray-400\">pt</span>\n <button className=\"h-7 px-3 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50\">\n 추가\n </button>\n </div>\n </div>\n </DialogSection>\n\n {/* 탭 목록 + 지운 탭 목록 */}\n <div className=\"flex gap-4\">\n <div className=\"flex-1\">\n <DialogSection title=\"탭 목록\">\n <div className=\"border border-gray-200 rounded bg-white min-h-[100px]\">\n <div className=\"grid grid-cols-2 text-[10px] text-gray-500 border-b border-gray-200 px-2 py-1\">\n <span>위치</span>\n <span>종류</span>\n </div>\n <div className=\"px-2 py-1 text-[10px] text-gray-400\">\n (없음)\n </div>\n </div>\n </DialogSection>\n </div>\n <div className=\"flex flex-col justify-center gap-1 pt-6\">\n <button className=\"w-7 h-7 rounded border border-gray-300 bg-white text-red-500 hover:bg-red-50 flex items-center justify-center text-sm\">\n ×\n </button>\n <button className=\"w-7 h-7 rounded border border-gray-300 bg-white text-red-500 hover:bg-red-50 flex items-center justify-center text-sm\">\n ×\n </button>\n </div>\n <div className=\"flex-1\">\n <DialogSection title=\"지운 탭 목록\">\n <div className=\"border border-gray-200 rounded bg-white min-h-[100px]\">\n <div className=\"px-2 py-1 text-[10px] text-gray-400\">\n (없음)\n </div>\n </div>\n </DialogSection>\n </div>\n </div>\n\n {/* 편집 + 기본 탭 */}\n <DialogSection title=\"편집\">\n <div className=\"flex items-center gap-6\">\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 내어쓰기용 자동 탭\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 문단 오른쪽 끝 자동 탭\n </label>\n </div>\n </DialogSection>\n <DialogSection title=\"기본 탭\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600\">구역 기본 탭 간격 :</span>\n <span className=\"text-xs text-gray-800 font-medium\">40.0 pt</span>\n <button className=\"h-7 px-3 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 ml-2\">\n 변경\n </button>\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 4: 테두리/배경 ─────────────────────────────────────────────────────────\n\nfunction ParaBorderBackgroundTab() {\n const selectClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n const inputClass = \"h-7 px-2 text-xs border border-gray-300 rounded bg-white\";\n\n return (\n <>\n {/* 테두리 */}\n <DialogSection title=\"테두리\">\n <div className=\"flex gap-4\">\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">종류</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"선 없음\">\n <option>선 없음</option>\n <option>실선</option>\n <option>점선</option>\n <option>파선</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">굵기</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"0.1 mm\">\n <option>0.1 mm</option>\n <option>0.3 mm</option>\n <option>0.5 mm</option>\n <option>1.0 mm</option>\n </select>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">색</span>\n <input type=\"color\" defaultValue=\"#000000\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600 mt-1\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 문단 테두리 연결\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input type=\"checkbox\" defaultChecked className=\"w-3.5 h-3.5\" />\n 선 모양 바로 적용\n </label>\n </div>\n <div className=\"w-44 h-28 border border-gray-300 rounded bg-white flex items-center justify-center\">\n <span className=\"text-[10px] text-gray-300\">미리보기</span>\n </div>\n </div>\n </DialogSection>\n\n {/* 배경 */}\n <DialogSection title=\"배경\">\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">면 색</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"색 없음\">\n <option>색 없음</option>\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-2 mt-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 색</span>\n <input type=\"color\" defaultValue=\"#c0c0c0\" className=\"w-24 h-7 rounded border border-gray-300\" />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-12\">무늬 모양</span>\n <select className={`${selectClass} flex-1`} defaultValue=\"\">\n <option value=\"\">없음</option>\n </select>\n </div>\n </div>\n </DialogSection>\n\n {/* 간격 */}\n <DialogSection title=\"간격\">\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-2\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">왼쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">오른쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">위쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-gray-600 w-10\">아래쪽</span>\n <input type=\"number\" step=\"0.01\" defaultValue={0} className={`${inputClass} flex-1`} />\n <span className=\"text-[10px] text-gray-400\">mm</span>\n </div>\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600 mt-2\">\n <input type=\"checkbox\" className=\"w-3.5 h-3.5\" />\n 문단 여백 무시\n </label>\n </DialogSection>\n </>\n );\n}\n\n// ── Main Dialog ───────────────────────────────────────────────────────────────\n\nexport function ParaFormatDialog() {\n const open = useEditorStore((s) => s.uiState.paraFormatDialogOpen);\n const closeParaFormatDialog = useEditorStore((s) => s.closeParaFormatDialog);\n const [activeTab, setActiveTab] = useState(0);\n\n const handleApply = useCallback(() => {\n closeParaFormatDialog();\n }, [closeParaFormatDialog]);\n\n return (\n <Dialog title=\"문단 모양\" open={open} onClose={closeParaFormatDialog} onApply={handleApply} width={580}>\n <DialogTabs tabs={TABS} activeTab={activeTab} onTabChange={setActiveTab} />\n {activeTab === 0 && <BasicTab />}\n {activeTab === 1 && <ExtendedTab />}\n {activeTab === 2 && <TabSettingsTab />}\n {activeTab === 3 && <ParaBorderBackgroundTab />}\n\n {/* 미리보기 (only for basic tab) */}\n {activeTab === 0 && (\n <div className=\"mt-4\">\n <div className=\"text-xs font-bold text-gray-800 mb-1.5\">미리보기</div>\n <div className=\"bg-white border border-gray-200 rounded-md p-3 min-h-[70px]\">\n <div className=\"text-[9px] text-gray-500 leading-relaxed\">\n 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단 이전 문단\n </div>\n <div className=\"text-[9px] text-gray-700 leading-relaxed mt-1\">\n 가나다라AaBbCc12345 가나다라AaBbCc12345 가나다라AaBbCc12345\n </div>\n </div>\n </div>\n )}\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TABS = [\"문단 번호\", \"글머리표\", \"그림 글머리표\"];\n\n// Numbering style definitions\nconst NUMBERING_STYLES = [\n { id: \"none\", level: 0, lines: [\"\", \"\", \"\", \"\"], label: \"없음\" },\n { id: \"1a\", level: 1, lines: [\"1.\", \"가.\", \"1)\", \"가)\"], label: \"1.가.1)가)\" },\n { id: \"1b\", level: 1, lines: [\"(1)\", \"(가)\", \"(a)\", \"1)\"], label: \"(1)(가)(a)1)\" },\n { id: \"1c\", level: 1, lines: [\"1)\", \"가)\", \"a)\", \"(1)\"], label: \"1)가)a)(1)\" },\n { id: \"1d\", level: 1, lines: [\"①\", \"(ㄱ)\", \"(a)\", \"1)\"], label: \"①(ㄱ)(a)1)\" },\n { id: \"1e\", level: 1, lines: [\"가)\", \"a)\", \"(1)\", \"(가)\"], label: \"가)a)(1)(가)\" },\n { id: \"1f\", level: 1, lines: [\"(ㄱ)\", \"(1)\", \"(a)\", \"1)\"], label: \"(ㄱ)(1)(a)1)\" },\n { id: \"1g\", level: 1, lines: [\"I.\", \"A.\", \"1.\", \"i)\"], label: \"I.A.1.i)\" },\n];\n\nconst BULLET_STYLES = [\n { char: \"●\", id: \"1\" },\n { char: \"•\", id: \"2\" },\n { char: \"■\", id: \"3\" },\n { char: \"▪\", id: \"4\" },\n { char: \"◆\", id: \"5\" },\n { char: \"◇\", id: \"6\" },\n { char: \"▶\", id: \"7\" },\n { char: \"▷\", id: \"8\" },\n { char: \"○\", id: \"9\" },\n { char: \"□\", id: \"10\" },\n { char: \"◇\", id: \"11\" },\n { char: \"▷\", id: \"12\" },\n { char: \"◎\", id: \"13\" },\n { char: \"☑\", id: \"14\" },\n { char: \"✓\", id: \"15\" },\n { char: \"★\", id: \"16\" },\n];\n\n// ── Tab 1: 문단 번호 ─────────────────────────────────────────────────────────\n\nfunction NumberingTab({ selected, onSelect }: { selected: number; onSelect: (idx: number) => void }) {\n return (\n <>\n <DialogSection title=\"각주 내용 번호 속성\">\n <div className=\"flex items-center gap-4 mb-2\">\n {[\"앞 번호 목록에 이어\", \"이전 번호 목록에 이어\"].map((label) => (\n <label key={label} className=\"flex items-center gap-1.5 text-xs text-gray-400\">\n <input type=\"radio\" name=\"numCont\" disabled className=\"w-3.5 h-3.5\" />\n {label}\n </label>\n ))}\n </div>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-700\">\n <input type=\"radio\" name=\"numCont\" defaultChecked className=\"w-3.5 h-3.5\" />\n 새 번호 목록 시작\n </label>\n <div className=\"flex items-center gap-2 mt-1.5 ml-5\">\n <span className=\"text-xs text-gray-600\">1 수준 시작 번호</span>\n <input type=\"number\" defaultValue={1} className=\"h-7 px-2 text-xs border border-gray-300 rounded bg-white w-28\" />\n </div>\n </DialogSection>\n\n <DialogSection title=\"문단 번호 모양\">\n <div className=\"grid grid-cols-4 gap-2\">\n {NUMBERING_STYLES.map((style, idx) => (\n <button\n key={style.id}\n onClick={() => onSelect(idx)}\n className={`p-2 rounded border text-left min-h-[80px] transition-colors ${\n selected === idx\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n {idx === 0 ? (\n <div className=\"flex items-center justify-center h-full\">\n <div className=\"w-8 h-8 border border-gray-300 rounded flex items-center justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">\n <line x1=\"2\" y1=\"14\" x2=\"14\" y2=\"2\" stroke=\"#dc2626\" strokeWidth=\"1.5\" />\n </svg>\n </div>\n </div>\n ) : (\n <div className=\"space-y-0.5\">\n {style.lines.map((line, li) => (\n <div key={li} className=\"flex items-center gap-1\">\n <span className=\"text-[9px] text-gray-700 w-6\">{line}</span>\n <div className=\"flex-1 h-[1px] bg-gray-300\" />\n </div>\n ))}\n </div>\n )}\n </button>\n ))}\n </div>\n </DialogSection>\n </>\n );\n}\n\n// ── Tab 2: 글머리표 ──────────────────────────────────────────────────────────\n\nfunction BulletTab({ selected, onSelect }: { selected: number; onSelect: (idx: number) => void }) {\n return (\n <DialogSection title=\"글머리표 모양\">\n <div className=\"grid grid-cols-4 gap-2\">\n {/* \"None\" option */}\n <button\n onClick={() => onSelect(0)}\n className={`p-3 rounded border min-h-[80px] flex items-center justify-center transition-colors ${\n selected === 0\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"w-8 h-8 border border-gray-300 rounded flex items-center justify-center\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">\n <line x1=\"2\" y1=\"14\" x2=\"14\" y2=\"2\" stroke=\"#dc2626\" strokeWidth=\"1.5\" />\n </svg>\n </div>\n </button>\n {/* Bullet styles */}\n {BULLET_STYLES.map((bullet, idx) => (\n <button\n key={idx}\n onClick={() => onSelect(idx + 1)}\n className={`p-2 rounded border min-h-[80px] transition-colors ${\n selected === idx + 1\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm\">{bullet.char}</span>\n <div className=\"flex-1 h-[1px] bg-gray-300\" />\n </div>\n <div className=\"flex items-center gap-1 ml-3\">\n <div className=\"flex-1 h-[1px] bg-gray-200\" />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-sm\">{bullet.char}</span>\n <div className=\"flex-1 h-[1px] bg-gray-300\" />\n </div>\n <div className=\"flex items-center gap-1 ml-3\">\n <div className=\"flex-1 h-[1px] bg-gray-200\" />\n </div>\n </div>\n </button>\n ))}\n </div>\n </DialogSection>\n );\n}\n\n// ── Tab 3: 그림 글머리표 ──────────────────────────────────────────────────────\n\nfunction PictureBulletTab() {\n return (\n <DialogSection title=\"그림 글머리표\">\n <div className=\"text-xs text-gray-400 text-center py-8\">\n 그림 글머리표를 선택하세요. (미지원)\n </div>\n </DialogSection>\n );\n}\n\n// ── Main Dialog ───────────────────────────────────────────────────────────────\n\nexport function BulletNumberDialog() {\n const open = useEditorStore((s) => s.uiState.bulletNumberDialogOpen);\n const closeBulletNumberDialog = useEditorStore((s) => s.closeBulletNumberDialog);\n const applyBullet = useEditorStore((s) => s.applyBullet);\n const applyNumbering = useEditorStore((s) => s.applyNumbering);\n const removeBulletNumbering = useEditorStore((s) => s.removeBulletNumbering);\n\n const [activeTab, setActiveTab] = useState(0);\n const [numberingSelected, setNumberingSelected] = useState(0);\n const [bulletSelected, setBulletSelected] = useState(0);\n\n const handleApply = useCallback(() => {\n if (activeTab === 0) {\n // Numbering tab\n if (numberingSelected === 0) {\n removeBulletNumbering();\n } else {\n const style = NUMBERING_STYLES[numberingSelected];\n if (style) {\n applyNumbering(style.level);\n }\n }\n } else if (activeTab === 1) {\n // Bullet tab\n if (bulletSelected === 0) {\n removeBulletNumbering();\n } else {\n const bullet = BULLET_STYLES[bulletSelected - 1];\n if (bullet) {\n applyBullet(bullet.id);\n }\n }\n }\n closeBulletNumberDialog();\n }, [activeTab, numberingSelected, bulletSelected, applyBullet, applyNumbering, removeBulletNumbering, closeBulletNumberDialog]);\n\n return (\n <Dialog title=\"문단 번호/글머리표\" open={open} onClose={closeBulletNumberDialog} onApply={handleApply} width={620}>\n <DialogTabs tabs={TABS} activeTab={activeTab} onTabChange={setActiveTab} />\n {activeTab === 0 && <NumberingTab selected={numberingSelected} onSelect={setNumberingSelected} />}\n {activeTab === 1 && <BulletTab selected={bulletSelected} onSelect={setBulletSelected} />}\n {activeTab === 2 && <PictureBulletTab />}\n\n <div className=\"flex items-center gap-2 mt-3\">\n <button disabled className=\"h-7 px-3 text-xs border border-gray-300 rounded bg-white text-gray-400\">\n 사용자 정의...\n </button>\n <button\n onClick={() => { removeBulletNumbering(); closeBulletNumberDialog(); }}\n className=\"w-7 h-7 rounded border border-gray-300 bg-white text-red-500 hover:bg-red-50 flex items-center justify-center text-sm\"\n title=\"서식 제거\"\n >\n ×\n </button>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useCallback, useMemo } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\n\n// ── Character categories ─────────────────────────────────────────────────────\n\ninterface CharCategory {\n label: string;\n chars: string[];\n}\n\nconst CATEGORIES: CharCategory[] = [\n {\n label: \"특수 문자\",\n chars: [\n \"※\", \"☆\", \"★\", \"○\", \"●\", \"◎\", \"◇\", \"◆\", \"□\", \"■\", \"△\", \"▲\", \"▽\", \"▼\", \"◁\", \"◀\", \"▷\", \"▶\",\n \"♤\", \"♠\", \"♡\", \"♥\", \"♧\", \"♣\", \"♢\", \"♦\", \"☎\", \"☏\", \"☜\", \"☞\", \"♨\", \"☀\", \"☁\", \"☂\",\n \"♬\", \"♪\", \"♩\", \"♭\", \"♯\", \"†\", \"‡\", \"¶\", \"§\", \"©\", \"®\", \"™\", \"℃\", \"℉\", \"㎜\", \"㎝\",\n \"㎞\", \"㎡\", \"㎥\", \"㏄\", \"㎏\", \"㎎\", \"㎍\", \"㎖\", \"㎗\", \"ℓ\", \"㎐\", \"㎑\", \"㎒\", \"㎓\", \"㎔\", \"㏊\",\n \"㏘\", \"㏗\", \"㎴\", \"㎵\", \"㎶\", \"㎷\", \"㎸\", \"㎹\", \"㎺\", \"㎻\", \"㎼\", \"㎽\", \"㎾\", \"㎿\", \"㎀\", \"㎁\",\n \"㎂\", \"㎃\", \"㎄\", \"㎈\", \"㎉\", \"㎊\", \"㎋\", \"㎌\", \"㎕\", \"㎙\", \"㎚\", \"㎛\", \"㎟\", \"㎠\", \"㎢\", \"㎣\",\n ],\n },\n {\n label: \"원/괄호 문자\",\n chars: [\n \"①\", \"②\", \"③\", \"④\", \"⑤\", \"⑥\", \"⑦\", \"⑧\", \"⑨\", \"⑩\", \"⑪\", \"⑫\", \"⑬\", \"⑭\", \"⑮\",\n \"⑴\", \"⑵\", \"⑶\", \"⑷\", \"⑸\", \"⑹\", \"⑺\", \"⑻\", \"⑼\", \"⑽\", \"⑾\", \"⑿\", \"⒀\", \"⒁\", \"⒂\",\n \"Ⓐ\", \"Ⓑ\", \"Ⓒ\", \"Ⓓ\", \"Ⓔ\", \"Ⓕ\", \"Ⓖ\", \"Ⓗ\", \"Ⓘ\", \"Ⓙ\", \"Ⓚ\", \"Ⓛ\", \"Ⓜ\", \"Ⓝ\", \"Ⓞ\",\n \"Ⓟ\", \"Ⓠ\", \"Ⓡ\", \"Ⓢ\", \"Ⓣ\", \"Ⓤ\", \"Ⓥ\", \"Ⓦ\", \"Ⓧ\", \"Ⓨ\", \"Ⓩ\",\n \"ⓐ\", \"ⓑ\", \"ⓒ\", \"ⓓ\", \"ⓔ\", \"ⓕ\", \"ⓖ\", \"ⓗ\", \"ⓘ\", \"ⓙ\", \"ⓚ\", \"ⓛ\", \"ⓜ\", \"ⓝ\", \"ⓞ\",\n \"ⓟ\", \"ⓠ\", \"ⓡ\", \"ⓢ\", \"ⓣ\", \"ⓤ\", \"ⓥ\", \"ⓦ\", \"ⓧ\", \"ⓨ\", \"ⓩ\",\n \"㉠\", \"㉡\", \"㉢\", \"㉣\", \"㉤\", \"㉥\", \"㉦\", \"㉧\", \"㉨\", \"㉩\", \"㉪\", \"㉫\", \"㉬\", \"㉭\",\n \"㈀\", \"㈁\", \"㈂\", \"㈃\", \"㈄\", \"㈅\", \"㈆\", \"㈇\", \"㈈\", \"㈉\", \"㈊\", \"㈋\", \"㈌\", \"㈍\",\n ],\n },\n {\n label: \"수학 기호\",\n chars: [\n \"±\", \"×\", \"÷\", \"≠\", \"≤\", \"≥\", \"∞\", \"∴\", \"∵\", \"∈\", \"∋\", \"⊂\", \"⊃\", \"⊆\", \"⊇\", \"∪\",\n \"∩\", \"∧\", \"∨\", \"¬\", \"⇒\", \"⇔\", \"∀\", \"∃\", \"∅\", \"∇\", \"∂\", \"∫\", \"∬\", \"∮\", \"√\", \"∑\",\n \"∏\", \"≡\", \"≒\", \"≪\", \"≫\", \"∝\", \"∠\", \"⊥\", \"⌒\", \"∥\", \"∼\", \"≈\", \"⊙\", \"∘\", \"⊕\", \"⊗\",\n \"⁰\", \"¹\", \"²\", \"³\", \"⁴\", \"⁵\", \"⁶\", \"⁷\", \"⁸\", \"⁹\", \"⁺\", \"⁻\", \"⁼\", \"⁽\", \"⁾\", \"ⁿ\",\n \"₀\", \"₁\", \"₂\", \"₃\", \"₄\", \"₅\", \"₆\", \"₇\", \"₈\", \"₉\", \"₊\", \"₋\", \"₌\", \"₍\", \"₎\",\n \"¼\", \"½\", \"¾\", \"⅓\", \"⅔\", \"⅕\", \"⅖\", \"⅗\", \"⅘\", \"⅙\", \"⅚\", \"⅛\", \"⅜\", \"⅝\", \"⅞\",\n ],\n },\n {\n label: \"화살표\",\n chars: [\n \"←\", \"→\", \"↑\", \"↓\", \"↔\", \"↕\", \"↖\", \"↗\", \"↘\", \"↙\", \"⇐\", \"⇒\", \"⇑\", \"⇓\", \"⇔\", \"⇕\",\n \"↠\", \"↣\", \"↦\", \"↩\", \"↪\", \"↰\", \"↱\", \"↲\", \"↳\", \"↴\", \"↵\", \"↶\", \"↷\", \"↺\", \"↻\",\n \"⟵\", \"⟶\", \"⟷\", \"⟸\", \"⟹\", \"⟺\",\n \"➔\", \"➘\", \"➙\", \"➚\", \"➛\", \"➜\", \"➝\", \"➞\", \"➟\", \"➠\", \"➡\", \"➢\", \"➣\", \"➤\", \"➥\", \"➦\",\n ],\n },\n {\n label: \"도형\",\n chars: [\n \"■\", \"□\", \"▢\", \"▣\", \"▤\", \"▥\", \"▦\", \"▧\", \"▨\", \"▩\", \"▪\", \"▫\", \"▬\", \"▭\", \"▮\", \"▯\",\n \"▰\", \"▱\", \"▲\", \"△\", \"▴\", \"▵\", \"▶\", \"▷\", \"▸\", \"▹\", \"►\", \"▻\", \"▼\", \"▽\", \"▾\", \"▿\",\n \"◀\", \"◁\", \"◂\", \"◃\", \"◄\", \"◅\", \"◆\", \"◇\", \"◈\", \"◉\", \"◊\", \"○\", \"◌\", \"◍\", \"◎\", \"●\",\n \"◐\", \"◑\", \"◒\", \"◓\", \"◔\", \"◕\", \"◖\", \"◗\", \"◘\", \"◙\", \"◚\", \"◛\", \"◜\", \"◝\", \"◞\", \"◟\",\n \"◠\", \"◡\", \"◢\", \"◣\", \"◤\", \"◥\", \"◦\", \"◧\", \"◨\", \"◩\", \"◪\", \"◫\", \"◬\", \"◭\", \"◮\", \"◯\",\n ],\n },\n {\n label: \"선 그리기\",\n chars: [\n \"─\", \"━\", \"│\", \"┃\", \"┄\", \"┅\", \"┆\", \"┇\", \"┈\", \"┉\", \"┊\", \"┋\",\n \"┌\", \"┍\", \"┎\", \"┏\", \"┐\", \"┑\", \"┒\", \"┓\", \"└\", \"┕\", \"┖\", \"┗\",\n \"┘\", \"┙\", \"┚\", \"┛\", \"├\", \"┝\", \"┞\", \"┟\", \"┠\", \"┡\", \"┢\", \"┣\",\n \"┤\", \"┥\", \"┦\", \"┧\", \"┨\", \"┩\", \"┪\", \"┫\", \"┬\", \"┭\", \"┮\", \"┯\",\n \"┰\", \"┱\", \"┲\", \"┳\", \"┴\", \"┵\", \"┶\", \"┷\", \"┸\", \"┹\", \"┺\", \"┻\",\n \"┼\", \"┽\", \"┾\", \"┿\", \"╀\", \"╁\", \"╂\", \"╃\", \"╄\", \"╅\", \"╆\", \"╇\",\n \"╈\", \"╉\", \"╊\", \"╋\", \"╌\", \"╍\", \"╎\", \"╏\",\n \"═\", \"║\", \"╒\", \"╓\", \"╔\", \"╕\", \"╖\", \"╗\", \"╘\", \"╙\", \"╚\", \"╛\",\n \"╜\", \"╝\", \"╞\", \"╟\", \"╠\", \"╡\", \"╢\", \"╣\", \"╤\", \"╥\", \"╦\", \"╧\",\n \"╨\", \"╩\", \"╪\", \"╫\", \"╬\",\n ],\n },\n {\n label: \"그리스/라틴\",\n chars: [\n \"Α\", \"Β\", \"Γ\", \"Δ\", \"Ε\", \"Ζ\", \"Η\", \"Θ\", \"Ι\", \"Κ\", \"Λ\", \"Μ\", \"Ν\", \"Ξ\", \"Ο\", \"Π\",\n \"Ρ\", \"Σ\", \"Τ\", \"Υ\", \"Φ\", \"Χ\", \"Ψ\", \"Ω\",\n \"α\", \"β\", \"γ\", \"δ\", \"ε\", \"ζ\", \"η\", \"θ\", \"ι\", \"κ\", \"λ\", \"μ\", \"ν\", \"ξ\", \"ο\", \"π\",\n \"ρ\", \"σ\", \"τ\", \"υ\", \"φ\", \"χ\", \"ψ\", \"ω\",\n \"À\", \"Á\", \"Â\", \"Ã\", \"Ä\", \"Å\", \"Æ\", \"Ç\", \"È\", \"É\", \"Ê\", \"Ë\", \"Ì\", \"Í\", \"Î\", \"Ï\",\n \"Ð\", \"Ñ\", \"Ò\", \"Ó\", \"Ô\", \"Õ\", \"Ö\", \"Ø\", \"Ù\", \"Ú\", \"Û\", \"Ü\", \"Ý\", \"Þ\", \"ß\",\n \"à\", \"á\", \"â\", \"ã\", \"ä\", \"å\", \"æ\", \"ç\", \"è\", \"é\", \"ê\", \"ë\", \"ì\", \"í\", \"î\", \"ï\",\n \"ð\", \"ñ\", \"ò\", \"ó\", \"ô\", \"õ\", \"ö\", \"ø\", \"ù\", \"ú\", \"û\", \"ü\", \"ý\", \"þ\", \"ÿ\",\n ],\n },\n {\n label: \"한글 자모\",\n chars: [\n \"ㄱ\", \"ㄲ\", \"ㄳ\", \"ㄴ\", \"ㄵ\", \"ㄶ\", \"ㄷ\", \"ㄸ\", \"ㄹ\", \"ㄺ\", \"ㄻ\", \"ㄼ\", \"ㄽ\", \"ㄾ\", \"ㄿ\", \"ㅀ\",\n \"ㅁ\", \"ㅂ\", \"ㅃ\", \"ㅄ\", \"ㅅ\", \"ㅆ\", \"ㅇ\", \"ㅈ\", \"ㅉ\", \"ㅊ\", \"ㅋ\", \"ㅌ\", \"ㅍ\", \"ㅎ\",\n \"ㅏ\", \"ㅐ\", \"ㅑ\", \"ㅒ\", \"ㅓ\", \"ㅔ\", \"ㅕ\", \"ㅖ\", \"ㅗ\", \"ㅘ\", \"ㅙ\", \"ㅚ\", \"ㅛ\", \"ㅜ\", \"ㅝ\", \"ㅞ\",\n \"ㅟ\", \"ㅠ\", \"ㅡ\", \"ㅢ\", \"ㅣ\",\n \"ㆍ\", \"ㆎ\",\n ],\n },\n {\n label: \"일본어\",\n chars: [\n \"ぁ\", \"あ\", \"ぃ\", \"い\", \"ぅ\", \"う\", \"ぇ\", \"え\", \"ぉ\", \"お\", \"か\", \"が\", \"き\", \"ぎ\", \"く\", \"ぐ\",\n \"け\", \"げ\", \"こ\", \"ご\", \"さ\", \"ざ\", \"し\", \"じ\", \"す\", \"ず\", \"せ\", \"ぜ\", \"そ\", \"ぞ\", \"た\", \"だ\",\n \"ち\", \"ぢ\", \"っ\", \"つ\", \"づ\", \"て\", \"で\", \"と\", \"ど\", \"な\", \"に\", \"ぬ\", \"ね\", \"の\", \"は\", \"ば\",\n \"ァ\", \"ア\", \"ィ\", \"イ\", \"ゥ\", \"ウ\", \"ェ\", \"エ\", \"ォ\", \"オ\", \"カ\", \"ガ\", \"キ\", \"ギ\", \"ク\", \"グ\",\n \"ケ\", \"ゲ\", \"コ\", \"ゴ\", \"サ\", \"ザ\", \"シ\", \"ジ\", \"ス\", \"ズ\", \"セ\", \"ゼ\", \"ソ\", \"ゾ\", \"タ\", \"ダ\",\n \"チ\", \"ヂ\", \"ッ\", \"ツ\", \"ヅ\", \"テ\", \"デ\", \"ト\", \"ド\", \"ナ\", \"ニ\", \"ヌ\", \"ネ\", \"ノ\", \"ハ\", \"バ\",\n ],\n },\n {\n label: \"기타 기호\",\n chars: [\n \"、\", \"。\", \"〃\", \"〈\", \"〉\", \"《\", \"》\", \"「\", \"」\", \"『\", \"』\", \"【\", \"】\", \"〔\", \"〕\", \"〖\",\n \"〗\", \"〘\", \"〙\", \"〚\", \"〛\", \"〜\", \"〝\", \"〞\", \"〟\", \"〰\",\n \"✁\", \"✂\", \"✃\", \"✄\", \"✆\", \"✇\", \"✈\", \"✉\", \"✌\", \"✍\", \"✎\", \"✏\", \"✐\", \"✑\", \"✒\", \"✓\",\n \"✔\", \"✕\", \"✖\", \"✗\", \"✘\", \"✙\", \"✚\", \"✛\", \"✜\", \"✝\", \"✞\", \"✟\", \"✠\", \"✡\", \"✢\", \"✣\",\n \"✤\", \"✥\", \"✦\", \"✧\", \"✩\", \"✪\", \"✫\", \"✬\", \"✭\", \"✮\", \"✯\", \"✰\", \"✱\", \"✲\", \"✳\", \"✴\",\n \"✵\", \"✶\", \"✷\", \"✸\", \"✹\", \"✺\", \"✻\", \"✼\", \"✽\", \"✾\", \"✿\", \"❀\", \"❁\", \"❂\", \"❃\", \"❄\",\n ],\n },\n];\n\nconst TAB_LABELS = CATEGORIES.map((c) => c.label);\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction charCodeInfo(ch: string): string {\n const cp = ch.codePointAt(0);\n if (cp === undefined) return \"\";\n return `U+${cp.toString(16).toUpperCase().padStart(4, \"0\")}`;\n}\n\n// ── Main Dialog ──────────────────────────────────────────────────────────────\n\nexport function CharMapDialog() {\n const open = useEditorStore((s) => s.uiState.charMapDialogOpen);\n const closeCharMapDialog = useEditorStore((s) => s.closeCharMapDialog);\n const insertTextAtCursor = useEditorStore((s) => s.insertTextAtCursor);\n\n const [activeTab, setActiveTab] = useState(0);\n const [selected, setSelected] = useState<string | null>(null);\n const [recentChars, setRecentChars] = useState<string[]>([]);\n\n const category = CATEGORIES[activeTab]!;\n\n const handleCharClick = useCallback((ch: string) => {\n setSelected(ch);\n }, []);\n\n const handleCharDoubleClick = useCallback((ch: string) => {\n insertTextAtCursor(ch);\n setRecentChars((prev) => {\n const next = [ch, ...prev.filter((c) => c !== ch)];\n return next.slice(0, 32);\n });\n }, [insertTextAtCursor]);\n\n const handleInsert = useCallback(() => {\n if (!selected) return;\n insertTextAtCursor(selected);\n setRecentChars((prev) => {\n const next = [selected, ...prev.filter((c) => c !== selected)];\n return next.slice(0, 32);\n });\n }, [selected, insertTextAtCursor]);\n\n const selectedInfo = useMemo(() => {\n if (!selected) return \"\";\n return charCodeInfo(selected);\n }, [selected]);\n\n return (\n <Dialog title=\"문자표\" open={open} onClose={closeCharMapDialog} onApply={handleInsert} width={640}>\n {/* Category tabs — use a compact horizontal scroll instead of DialogTabs for many categories */}\n <div className=\"flex gap-0 mb-3 overflow-x-auto border-b border-gray-200 pb-0\">\n {TAB_LABELS.map((label, idx) => (\n <button\n key={label}\n onClick={() => { setActiveTab(idx); setSelected(null); }}\n className={`px-3 py-1.5 text-xs whitespace-nowrap border-b-2 transition-colors ${\n activeTab === idx\n ? \"border-blue-500 text-blue-700 font-semibold\"\n : \"border-transparent text-gray-500 hover:text-gray-700\"\n }`}\n >\n {label}\n </button>\n ))}\n </div>\n\n {/* Character grid */}\n <div className=\"grid gap-0 border border-gray-300 rounded bg-white overflow-hidden\"\n style={{ gridTemplateColumns: \"repeat(16, 1fr)\" }}\n >\n {category.chars.map((ch, idx) => (\n <button\n key={`${ch}-${idx}`}\n onClick={() => handleCharClick(ch)}\n onDoubleClick={() => handleCharDoubleClick(ch)}\n className={`aspect-square flex items-center justify-center text-sm border border-gray-100 hover:bg-blue-50 transition-colors ${\n selected === ch\n ? \"bg-blue-100 ring-2 ring-blue-400 ring-inset font-bold\"\n : \"bg-white\"\n }`}\n title={`${ch} (${charCodeInfo(ch)})`}\n >\n {ch}\n </button>\n ))}\n </div>\n\n {/* Info bar */}\n <div className=\"flex items-center justify-between mt-3\">\n <div className=\"flex items-center gap-3\">\n {selected && (\n <>\n <span className=\"text-2xl\">{selected}</span>\n <span className=\"text-xs text-gray-500\">{selectedInfo}</span>\n </>\n )}\n {!selected && (\n <span className=\"text-xs text-gray-400\">문자를 선택하세요. 더블 클릭으로 바로 입력합니다.</span>\n )}\n </div>\n <button\n onClick={handleInsert}\n disabled={!selected}\n className={`px-4 py-1.5 text-xs rounded border ${\n selected\n ? \"bg-blue-500 text-white border-blue-600 hover:bg-blue-600\"\n : \"bg-gray-100 text-gray-400 border-gray-200 cursor-default\"\n }`}\n >\n 넣기\n </button>\n </div>\n\n {/* Recent characters */}\n {recentChars.length > 0 && (\n <div className=\"mt-3\">\n <div className=\"text-xs font-bold text-gray-700 mb-1\">최근 사용</div>\n <div className=\"flex flex-wrap gap-0.5\">\n {recentChars.map((ch, idx) => (\n <button\n key={`recent-${idx}`}\n onClick={() => handleCharClick(ch)}\n onDoubleClick={() => handleCharDoubleClick(ch)}\n className=\"w-7 h-7 flex items-center justify-center text-sm border border-gray-200 rounded hover:bg-blue-50 bg-white\"\n title={`${ch} (${charCodeInfo(ch)})`}\n >\n {ch}\n </button>\n ))}\n </div>\n </div>\n )}\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { X, Plus, Trash2, FileText } from \"lucide-react\";\n\nexport function TemplateDialog() {\n const isOpen = useEditorStore((s) => s.uiState.templateDialogOpen);\n const closeDialog = useEditorStore((s) => s.closeTemplateDialog);\n const templates = useEditorStore((s) => s.templates);\n const addTemplate = useEditorStore((s) => s.addTemplate);\n const removeTemplate = useEditorStore((s) => s.removeTemplate);\n const loadTemplates = useEditorStore((s) => s.loadTemplates);\n\n const [newName, setNewName] = useState(\"\");\n const [newPath, setNewPath] = useState(\"\");\n const [newDesc, setNewDesc] = useState(\"\");\n const [showAddForm, setShowAddForm] = useState(false);\n\n useEffect(() => {\n if (isOpen) loadTemplates();\n }, [isOpen, loadTemplates]);\n\n const handleAdd = useCallback(() => {\n if (newName.trim() && newPath.trim()) {\n addTemplate(newName.trim(), newPath.trim(), newDesc.trim() || undefined);\n setNewName(\"\");\n setNewPath(\"\");\n setNewDesc(\"\");\n setShowAddForm(false);\n }\n }, [newName, newPath, newDesc, addTemplate]);\n\n const handleFileSelect = useCallback(async () => {\n // Use file input for path selection\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \".hwp,.hwpx\";\n input.onchange = (e) => {\n const file = (e.target as HTMLInputElement).files?.[0];\n if (file) {\n // For web, we store the file name. In Electron, this would be the full path.\n setNewPath(file.name);\n if (!newName) {\n setNewName(file.name.replace(/\\.(hwpx?|hwp)$/i, \"\"));\n }\n }\n };\n input.click();\n }, [newName]);\n\n if (!isOpen) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\">\n <div className=\"bg-white rounded-lg shadow-xl w-[500px] max-h-[80vh] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b\">\n <h2 className=\"text-sm font-semibold\">문서 템플릿</h2>\n <button\n onClick={closeDialog}\n className=\"p-1 hover:bg-gray-100 rounded\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-auto p-4\">\n {/* Template List */}\n <div className=\"space-y-2 mb-4\">\n {templates.length === 0 ? (\n <div className=\"text-center py-8 text-gray-500 text-sm\">\n 저장된 템플릿이 없습니다.\n <br />\n 자주 사용하는 문서를 템플릿으로 추가하세요.\n </div>\n ) : (\n templates.map((tpl) => (\n <div\n key={tpl.id}\n className=\"flex items-center gap-3 p-3 border rounded hover:bg-gray-50 group\"\n >\n <FileText className=\"w-5 h-5 text-blue-500 flex-shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-sm truncate\">{tpl.name}</div>\n <div className=\"text-xs text-gray-500 truncate\">{tpl.path}</div>\n {tpl.description && (\n <div className=\"text-xs text-gray-400 truncate\">{tpl.description}</div>\n )}\n </div>\n <button\n onClick={() => removeTemplate(tpl.id)}\n className=\"p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded opacity-0 group-hover:opacity-100 transition-opacity\"\n title=\"삭제\"\n >\n <Trash2 className=\"w-4 h-4\" />\n </button>\n </div>\n ))\n )}\n </div>\n\n {/* Add Form */}\n {showAddForm ? (\n <div className=\"border rounded p-3 space-y-2 bg-gray-50\">\n <div className=\"text-xs font-medium text-gray-600 mb-2\">새 템플릿 추가</div>\n <div>\n <label className=\"text-xs text-gray-500\">이름</label>\n <input\n type=\"text\"\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n placeholder=\"예: 외주용역계약서\"\n className=\"w-full px-2 py-1.5 text-sm border rounded mt-0.5\"\n />\n </div>\n <div>\n <label className=\"text-xs text-gray-500\">파일 경로</label>\n <div className=\"flex gap-2 mt-0.5\">\n <input\n type=\"text\"\n value={newPath}\n onChange={(e) => setNewPath(e.target.value)}\n placeholder=\"/path/to/template.hwp\"\n className=\"flex-1 px-2 py-1.5 text-sm border rounded\"\n />\n <button\n onClick={handleFileSelect}\n className=\"px-3 py-1.5 text-sm bg-gray-100 hover:bg-gray-200 rounded\"\n >\n 찾기\n </button>\n </div>\n </div>\n <div>\n <label className=\"text-xs text-gray-500\">설명 (선택)</label>\n <input\n type=\"text\"\n value={newDesc}\n onChange={(e) => setNewDesc(e.target.value)}\n placeholder=\"간단한 설명\"\n className=\"w-full px-2 py-1.5 text-sm border rounded mt-0.5\"\n />\n </div>\n <div className=\"flex justify-end gap-2 pt-2\">\n <button\n onClick={() => setShowAddForm(false)}\n className=\"px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 rounded\"\n >\n 취소\n </button>\n <button\n onClick={handleAdd}\n disabled={!newName.trim() || !newPath.trim()}\n className=\"px-3 py-1.5 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50\"\n >\n 추가\n </button>\n </div>\n </div>\n ) : (\n <button\n onClick={() => setShowAddForm(true)}\n className=\"flex items-center justify-center gap-2 w-full py-2 text-sm text-blue-600 hover:bg-blue-50 border border-dashed border-blue-300 rounded\"\n >\n <Plus className=\"w-4 h-4\" />\n 템플릿 추가\n </button>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"px-4 py-3 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={closeDialog}\n className=\"px-4 py-1.5 text-sm bg-gray-200 hover:bg-gray-300 rounded\"\n >\n 닫기\n </button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\nimport { DialogTabs } from \"./DialogTabs\";\n\nexport function HeaderFooterDialog() {\n const doc = useEditorStore((s) => s.doc);\n const viewModel = useEditorStore((s) => s.viewModel);\n const selection = useEditorStore((s) => s.selection);\n const uiState = useEditorStore((s) => s.uiState);\n const closeHeaderFooterDialog = useEditorStore((s) => s.closeHeaderFooterDialog);\n const setHeaderFooter = useEditorStore((s) => s.setHeaderFooter);\n\n const sectionIdx = selection?.sectionIndex ?? 0;\n const section = viewModel?.sections[sectionIdx];\n\n const [activeTab, setActiveTab] = useState<\"header\" | \"footer\">(\"header\");\n const [headerText, setHeaderText] = useState(section?.headerText ?? \"\");\n const [footerText, setFooterText] = useState(section?.footerText ?? \"\");\n const [headerPosition, setHeaderPosition] = useState<\"left\" | \"center\" | \"right\">(\"center\");\n const [footerPosition, setFooterPosition] = useState<\"left\" | \"center\" | \"right\">(\"center\");\n\n useEffect(() => {\n if (uiState.headerFooterDialogOpen && section) {\n setHeaderText(section.headerText);\n setFooterText(section.footerText);\n }\n }, [uiState.headerFooterDialogOpen, section?.headerText, section?.footerText]);\n\n const handleApply = () => {\n setHeaderFooter({ headerText, footerText });\n closeHeaderFooterDialog();\n };\n\n const insertPlaceholder = (placeholder: string) => {\n if (activeTab === \"header\") {\n setHeaderText((prev) => prev + placeholder);\n } else {\n setFooterText((prev) => prev + placeholder);\n }\n };\n\n const inputClass =\n \"w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:border-blue-400\";\n const btnClass =\n \"px-2 py-1 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-gray-700\";\n\n return (\n <Dialog\n title=\"머리말/꼬리말\"\n open={uiState.headerFooterDialogOpen}\n onClose={closeHeaderFooterDialog}\n onApply={handleApply}\n width={480}\n >\n <DialogTabs\n tabs={[\n { id: \"header\", label: \"머리말\" },\n { id: \"footer\", label: \"꼬리말\" },\n ]}\n activeTab={activeTab}\n onTabChange={(id) => setActiveTab(id as \"header\" | \"footer\")}\n />\n\n {activeTab === \"header\" && (\n <DialogSection title=\"머리말 내용\">\n <textarea\n value={headerText}\n onChange={(e) => setHeaderText(e.target.value)}\n placeholder=\"머리말 내용을 입력하세요\"\n className={`${inputClass} h-20 resize-none`}\n />\n <div className=\"flex gap-2 mt-2\">\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{page}}\")}>\n 쪽 번호\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{total}}\")}>\n 총 쪽 수\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{date}}\")}>\n 날짜\n </button>\n </div>\n <div className=\"flex items-center gap-4 mt-3\">\n <span className=\"text-xs text-gray-600\">정렬:</span>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"headerPos\"\n checked={headerPosition === \"left\"}\n onChange={() => setHeaderPosition(\"left\")}\n />\n 왼쪽\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"headerPos\"\n checked={headerPosition === \"center\"}\n onChange={() => setHeaderPosition(\"center\")}\n />\n 가운데\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"headerPos\"\n checked={headerPosition === \"right\"}\n onChange={() => setHeaderPosition(\"right\")}\n />\n 오른쪽\n </label>\n </div>\n </DialogSection>\n )}\n\n {activeTab === \"footer\" && (\n <DialogSection title=\"꼬리말 내용\">\n <textarea\n value={footerText}\n onChange={(e) => setFooterText(e.target.value)}\n placeholder=\"꼬리말 내용을 입력하세요\"\n className={`${inputClass} h-20 resize-none`}\n />\n <div className=\"flex gap-2 mt-2\">\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{page}}\")}>\n 쪽 번호\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{total}}\")}>\n 총 쪽 수\n </button>\n <button className={btnClass} onClick={() => insertPlaceholder(\"{{date}}\")}>\n 날짜\n </button>\n </div>\n <div className=\"flex items-center gap-4 mt-3\">\n <span className=\"text-xs text-gray-600\">정렬:</span>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"footerPos\"\n checked={footerPosition === \"left\"}\n onChange={() => setFooterPosition(\"left\")}\n />\n 왼쪽\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"footerPos\"\n checked={footerPosition === \"center\"}\n onChange={() => setFooterPosition(\"center\")}\n />\n 가운데\n </label>\n <label className=\"flex items-center gap-1 text-xs\">\n <input\n type=\"radio\"\n name=\"footerPos\"\n checked={footerPosition === \"right\"}\n onChange={() => setFooterPosition(\"right\")}\n />\n 오른쪽\n </label>\n </div>\n </DialogSection>\n )}\n\n <div className=\"text-xs text-gray-500 mt-3\">\n <p>사용 가능한 변수:</p>\n <ul className=\"list-disc pl-4 mt-1 space-y-0.5\">\n <li><code className=\"bg-gray-100 px-1 rounded\">{\"{{page}}\"}</code> - 현재 쪽 번호</li>\n <li><code className=\"bg-gray-100 px-1 rounded\">{\"{{total}}\"}</code> - 총 쪽 수</li>\n <li><code className=\"bg-gray-100 px-1 rounded\">{\"{{date}}\"}</code> - 오늘 날짜</li>\n </ul>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogTabs } from \"./DialogTabs\";\n\nexport function FindReplaceDialog() {\n const doc = useEditorStore((s) => s.doc);\n const uiState = useEditorStore((s) => s.uiState);\n const closeFindReplaceDialog = useEditorStore((s) => s.closeFindReplaceDialog);\n const findAndReplace = useEditorStore((s) => s.findAndReplace);\n\n const [activeTab, setActiveTab] = useState<\"find\" | \"replace\">(\"find\");\n const [findText, setFindText] = useState(\"\");\n const [replaceText, setReplaceText] = useState(\"\");\n const [matchCase, setMatchCase] = useState(false);\n const [wholeWord, setWholeWord] = useState(false);\n const [resultMessage, setResultMessage] = useState<string | null>(null);\n\n // Reset result message when find text changes\n useEffect(() => {\n setResultMessage(null);\n }, [findText]);\n\n const handleFind = useCallback(() => {\n if (!doc || !findText) return;\n // Simple find by checking if text exists\n const text = doc.text;\n const searchText = matchCase ? findText : findText.toLowerCase();\n const docText = matchCase ? text : text.toLowerCase();\n\n if (docText.includes(searchText)) {\n const count = (docText.match(new RegExp(escapeRegex(searchText), \"g\")) || []).length;\n setResultMessage(`\"${findText}\"을(를) ${count}개 찾았습니다.`);\n } else {\n setResultMessage(`\"${findText}\"을(를) 찾을 수 없습니다.`);\n }\n }, [doc, findText, matchCase]);\n\n const handleReplace = useCallback(() => {\n if (!doc || !findText) return;\n const count = findAndReplace(findText, replaceText, 1);\n setResultMessage(count > 0 ? `1개를 바꿨습니다.` : `\"${findText}\"을(를) 찾을 수 없습니다.`);\n }, [doc, findText, replaceText, findAndReplace]);\n\n const handleReplaceAll = useCallback(() => {\n if (!doc || !findText) return;\n const count = findAndReplace(findText, replaceText);\n setResultMessage(count > 0 ? `${count}개를 모두 바꿨습니다.` : `\"${findText}\"을(를) 찾을 수 없습니다.`);\n }, [doc, findText, replaceText, findAndReplace]);\n\n const inputClass =\n \"w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:border-blue-400\";\n const btnClass =\n \"px-3 py-1.5 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-gray-700 disabled:opacity-40 disabled:cursor-not-allowed\";\n const primaryBtnClass =\n \"px-3 py-1.5 text-xs border border-blue-500 rounded bg-blue-500 hover:bg-blue-600 text-white disabled:opacity-40 disabled:cursor-not-allowed\";\n\n return (\n <Dialog\n title=\"찾기/바꾸기\"\n open={uiState.findReplaceDialogOpen}\n onClose={closeFindReplaceDialog}\n width={420}\n >\n <DialogTabs\n tabs={[\n { id: \"find\", label: \"찾기\" },\n { id: \"replace\", label: \"바꾸기\" },\n ]}\n activeTab={activeTab}\n onTabChange={(id) => setActiveTab(id as \"find\" | \"replace\")}\n />\n\n <div className=\"space-y-3 mt-3\">\n <div>\n <label className=\"block text-xs text-gray-600 mb-1\">찾을 내용</label>\n <input\n type=\"text\"\n value={findText}\n onChange={(e) => setFindText(e.target.value)}\n placeholder=\"찾을 텍스트를 입력하세요\"\n className={inputClass}\n autoFocus\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n if (activeTab === \"find\") handleFind();\n else handleReplace();\n }\n }}\n />\n </div>\n\n {activeTab === \"replace\" && (\n <div>\n <label className=\"block text-xs text-gray-600 mb-1\">바꿀 내용</label>\n <input\n type=\"text\"\n value={replaceText}\n onChange={(e) => setReplaceText(e.target.value)}\n placeholder=\"바꿀 텍스트를 입력하세요\"\n className={inputClass}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleReplace();\n }\n }}\n />\n </div>\n )}\n\n <div className=\"flex gap-4\">\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input\n type=\"checkbox\"\n checked={matchCase}\n onChange={(e) => setMatchCase(e.target.checked)}\n className=\"w-3.5 h-3.5\"\n />\n 대/소문자 구분\n </label>\n <label className=\"flex items-center gap-1.5 text-xs text-gray-600\">\n <input\n type=\"checkbox\"\n checked={wholeWord}\n onChange={(e) => setWholeWord(e.target.checked)}\n className=\"w-3.5 h-3.5\"\n disabled\n />\n 온전한 낱말\n </label>\n </div>\n\n {resultMessage && (\n <div className={`text-xs px-2 py-1.5 rounded ${\n resultMessage.includes(\"찾을 수 없\")\n ? \"bg-yellow-50 text-yellow-700 border border-yellow-200\"\n : \"bg-green-50 text-green-700 border border-green-200\"\n }`}>\n {resultMessage}\n </div>\n )}\n\n <div className=\"flex gap-2 pt-2\">\n {activeTab === \"find\" ? (\n <>\n <button\n className={primaryBtnClass}\n disabled={!findText}\n onClick={handleFind}\n >\n 찾기\n </button>\n <button className={btnClass} disabled>\n 다음 찾기\n </button>\n </>\n ) : (\n <>\n <button\n className={primaryBtnClass}\n disabled={!findText}\n onClick={handleReplace}\n >\n 바꾸기\n </button>\n <button\n className={btnClass}\n disabled={!findText}\n onClick={handleReplaceAll}\n >\n 모두 바꾸기\n </button>\n </>\n )}\n <button className={btnClass} onClick={closeFindReplaceDialog}>\n 닫기\n </button>\n </div>\n </div>\n </Dialog>\n );\n}\n\nfunction escapeRegex(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\n\ninterface WordCountStats {\n characters: number;\n charactersNoSpaces: number;\n words: number;\n paragraphs: number;\n lines: number;\n pages: number;\n}\n\nfunction countStats(text: string, pageCount: number): WordCountStats {\n const lines = text.split(\"\\n\");\n const paragraphs = lines.filter((line) => line.trim().length > 0);\n const characters = text.length;\n const charactersNoSpaces = text.replace(/\\s/g, \"\").length;\n\n // Count words (Korean: treat each character as a word, English: split by spaces)\n let words = 0;\n const segments = text.split(/\\s+/).filter((s) => s.length > 0);\n for (const segment of segments) {\n // Count Korean characters individually\n const koreanChars = (segment.match(/[\\uAC00-\\uD7AF]/g) || []).length;\n // Count English words (sequences of non-Korean characters)\n const nonKorean = segment.replace(/[\\uAC00-\\uD7AF]/g, \" \").split(/\\s+/).filter((s) => s.length > 0);\n words += koreanChars + nonKorean.length;\n }\n\n return {\n characters,\n charactersNoSpaces,\n words,\n paragraphs: paragraphs.length,\n lines: lines.length,\n pages: pageCount,\n };\n}\n\nexport function WordCountDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closeWordCountDialog = useEditorStore((s) => s.closeWordCountDialog);\n const doc = useEditorStore((s) => s.doc);\n const viewModel = useEditorStore((s) => s.viewModel);\n\n const [stats, setStats] = useState<WordCountStats | null>(null);\n\n useEffect(() => {\n if (uiState.wordCountDialogOpen && doc && viewModel) {\n const text = doc.text;\n const sectionCount = viewModel.sections.length;\n setStats(countStats(text, sectionCount));\n }\n }, [uiState.wordCountDialogOpen, doc, viewModel]);\n\n const statItems = stats\n ? [\n { label: \"글자 수 (공백 제외)\", value: stats.charactersNoSpaces.toLocaleString(), highlight: true },\n { label: \"글자 수 (공백 포함)\", value: stats.characters.toLocaleString() },\n { label: \"낱말 수\", value: stats.words.toLocaleString() },\n { label: \"문단 수\", value: stats.paragraphs.toLocaleString() },\n { label: \"줄 수\", value: stats.lines.toLocaleString() },\n { label: \"쪽 수\", value: stats.pages.toLocaleString() },\n ]\n : [];\n\n return (\n <Dialog\n title=\"글자 수 세기\"\n open={uiState.wordCountDialogOpen}\n onClose={closeWordCountDialog}\n width={320}\n >\n <div className=\"space-y-1.5\">\n {statItems.map((item, idx) => (\n <div\n key={item.label}\n className={`flex justify-between items-center py-1.5 px-2 rounded ${\n idx === 0 ? \"bg-blue-50 border border-blue-200\" : \"bg-gray-50\"\n }`}\n >\n <span className={`text-xs ${idx === 0 ? \"text-blue-700 font-medium\" : \"text-gray-600\"}`}>\n {item.label}\n </span>\n <span className={`text-sm font-medium ${idx === 0 ? \"text-blue-800\" : \"text-gray-800\"}`}>\n {item.value}\n </span>\n </div>\n ))}\n </div>\n\n <div className=\"flex justify-end mt-4\">\n <button\n onClick={closeWordCountDialog}\n className=\"px-4 py-1.5 text-xs border border-gray-300 rounded bg-white hover:bg-gray-50 text-gray-700\"\n >\n 닫기\n </button>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\n\nexport function PageNumberDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closePageNumberDialog = useEditorStore((s) => s.closePageNumberDialog);\n const setPageNumbering = useEditorStore((s) => s.setPageNumbering);\n\n const [position, setPosition] = useState<string>(\"footer-center\");\n const [startNumber, setStartNumber] = useState(1);\n const [format, setFormat] = useState<string>(\"arabic\");\n\n const handleApply = () => {\n setPageNumbering({ position, startNumber });\n closePageNumberDialog();\n };\n\n const inputClass =\n \"w-full px-2 py-1.5 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:border-blue-400\";\n\n return (\n <Dialog\n title=\"쪽 번호 매기기\"\n open={uiState.pageNumberDialogOpen}\n onClose={closePageNumberDialog}\n onApply={handleApply}\n width={400}\n >\n <DialogSection title=\"위치\">\n <div className=\"space-y-2\">\n <div className=\"text-xs text-gray-600 mb-2\">머리말</div>\n <div className=\"flex gap-2\">\n <label className=\"flex items-center gap-1 text-xs flex-1\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"header-left\"\n checked={position === \"header-left\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 왼쪽\n </label>\n <label className=\"flex items-center gap-1 text-xs flex-1\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"header-center\"\n checked={position === \"header-center\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 가운데\n </label>\n <label className=\"flex items-center gap-1 text-xs flex-1\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"header-right\"\n checked={position === \"header-right\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 오른쪽\n </label>\n </div>\n\n <div className=\"text-xs text-gray-600 mb-2 mt-3\">꼬리말</div>\n <div className=\"flex gap-2\">\n <label className=\"flex items-center gap-1 text-xs flex-1\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"footer-left\"\n checked={position === \"footer-left\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 왼쪽\n </label>\n <label className=\"flex items-center gap-1 text-xs flex-1\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"footer-center\"\n checked={position === \"footer-center\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 가운데\n </label>\n <label className=\"flex items-center gap-1 text-xs flex-1\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"footer-right\"\n checked={position === \"footer-right\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 오른쪽\n </label>\n </div>\n\n <label className=\"flex items-center gap-1 text-xs mt-3\">\n <input\n type=\"radio\"\n name=\"pageNumPos\"\n value=\"none\"\n checked={position === \"none\"}\n onChange={(e) => setPosition(e.target.value)}\n />\n 쪽 번호 없음\n </label>\n </div>\n </DialogSection>\n\n <DialogSection title=\"번호 형식\">\n <select\n value={format}\n onChange={(e) => setFormat(e.target.value)}\n className={inputClass}\n >\n <option value=\"arabic\">1, 2, 3, ...</option>\n <option value=\"roman-lower\">i, ii, iii, ...</option>\n <option value=\"roman-upper\">I, II, III, ...</option>\n <option value=\"alpha-lower\">a, b, c, ...</option>\n <option value=\"alpha-upper\">A, B, C, ...</option>\n <option value=\"korean\">가, 나, 다, ...</option>\n <option value=\"hanja\">一, 二, 三, ...</option>\n </select>\n </DialogSection>\n\n <DialogSection title=\"시작 번호\">\n <input\n type=\"number\"\n min={1}\n value={startNumber}\n onChange={(e) => setStartNumber(Math.max(1, parseInt(e.target.value) || 1))}\n className={`${inputClass} w-24`}\n />\n </DialogSection>\n\n <div className=\"text-xs text-gray-500 mt-3\">\n <p>미리보기: <span className=\"font-mono bg-gray-100 px-2 py-0.5 rounded\">- {startNumber} -</span></p>\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\n\ninterface StyleItem {\n id: string;\n name: string;\n type: string;\n}\n\nexport function StyleDialog() {\n const doc = useEditorStore((s) => s.doc);\n const uiState = useEditorStore((s) => s.uiState);\n const closeStyleDialog = useEditorStore((s) => s.closeStyleDialog);\n const applyStyle = useEditorStore((s) => s.applyStyle);\n\n const [styles, setStyles] = useState<StyleItem[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n useEffect(() => {\n if (uiState.styleDialogOpen && doc) {\n try {\n const headers = doc.oxml.headers;\n const styleList: StyleItem[] = [];\n for (const header of headers) {\n const refList = header.refList;\n if (refList?.styles?.styles) {\n for (const style of refList.styles.styles) {\n if (style.id != null && style.name) {\n styleList.push({\n id: String(style.id),\n name: style.name,\n type: style.type ?? \"para\",\n });\n }\n }\n }\n }\n setStyles(styleList);\n if (styleList.length > 0 && !selectedId) {\n setSelectedId(styleList[0]?.id ?? null);\n }\n } catch (e) {\n console.error(\"Failed to load styles:\", e);\n }\n }\n }, [uiState.styleDialogOpen, doc]);\n\n const handleApply = () => {\n if (selectedId) {\n applyStyle(selectedId);\n }\n closeStyleDialog();\n };\n\n const paraStyles = styles.filter((s) => s.type === \"para\" || s.type === \"Paragraph\");\n const charStyles = styles.filter((s) => s.type === \"char\" || s.type === \"Character\");\n\n return (\n <Dialog\n title=\"스타일\"\n open={uiState.styleDialogOpen}\n onClose={closeStyleDialog}\n onApply={handleApply}\n width={400}\n >\n <DialogSection title=\"문단 스타일\">\n <div className=\"max-h-48 overflow-y-auto border border-gray-200 rounded\">\n {paraStyles.length === 0 ? (\n <div className=\"p-2 text-xs text-gray-400\">스타일 없음</div>\n ) : (\n paraStyles.map((style) => (\n <button\n key={style.id}\n onClick={() => setSelectedId(style.id)}\n className={`w-full text-left px-3 py-2 text-sm border-b border-gray-100 last:border-0 ${\n selectedId === style.id\n ? \"bg-blue-50 text-blue-700\"\n : \"hover:bg-gray-50\"\n }`}\n >\n {style.name}\n </button>\n ))\n )}\n </div>\n </DialogSection>\n\n {charStyles.length > 0 && (\n <DialogSection title=\"글자 스타일\">\n <div className=\"max-h-32 overflow-y-auto border border-gray-200 rounded\">\n {charStyles.map((style) => (\n <button\n key={style.id}\n onClick={() => setSelectedId(style.id)}\n className={`w-full text-left px-3 py-2 text-sm border-b border-gray-100 last:border-0 ${\n selectedId === style.id\n ? \"bg-blue-50 text-blue-700\"\n : \"hover:bg-gray-50\"\n }`}\n >\n {style.name}\n </button>\n ))}\n </div>\n </DialogSection>\n )}\n\n <div className=\"text-xs text-gray-500 mt-3\">\n 선택한 스타일을 현재 문단에 적용합니다.\n </div>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\nimport { autoCorrectManager, type AutoCorrectRule } from \"@/lib/autocorrect\";\n\nexport function AutoCorrectDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closeAutoCorrectDialog = useEditorStore((s) => s.closeAutoCorrectDialog);\n\n const [enabled, setEnabled] = useState(true);\n const [rules, setRules] = useState<AutoCorrectRule[]>([]);\n const [newFrom, setNewFrom] = useState(\"\");\n const [newTo, setNewTo] = useState(\"\");\n\n useEffect(() => {\n if (uiState.autoCorrectDialogOpen) {\n setEnabled(autoCorrectManager.isEnabled());\n setRules(autoCorrectManager.getRules());\n }\n }, [uiState.autoCorrectDialogOpen]);\n\n const handleApply = () => {\n autoCorrectManager.setEnabled(enabled);\n autoCorrectManager.setRules(rules);\n closeAutoCorrectDialog();\n };\n\n const handleToggleRule = (from: string) => {\n setRules((prev) =>\n prev.map((r) =>\n r.from === from ? { ...r, enabled: !r.enabled } : r\n )\n );\n };\n\n const handleDeleteRule = (from: string) => {\n setRules((prev) => prev.filter((r) => r.from !== from));\n };\n\n const handleAddRule = () => {\n if (!newFrom.trim() || !newTo.trim()) return;\n const existing = rules.find((r) => r.from === newFrom);\n if (existing) {\n setRules((prev) =>\n prev.map((r) =>\n r.from === newFrom ? { ...r, to: newTo, enabled: true } : r\n )\n );\n } else {\n setRules((prev) => [...prev, { from: newFrom, to: newTo, enabled: true }]);\n }\n setNewFrom(\"\");\n setNewTo(\"\");\n };\n\n const handleReset = () => {\n autoCorrectManager.resetToDefaults();\n setRules(autoCorrectManager.getRules());\n setEnabled(true);\n };\n\n const inputClass =\n \"px-2 py-1.5 text-sm border border-gray-300 rounded bg-white focus:outline-none focus:border-blue-400\";\n\n return (\n <Dialog\n title=\"자동 고침\"\n open={uiState.autoCorrectDialogOpen}\n onClose={closeAutoCorrectDialog}\n onApply={handleApply}\n width={500}\n >\n <div className=\"flex items-center gap-2 mb-4\">\n <input\n type=\"checkbox\"\n id=\"autocorrect-enabled\"\n checked={enabled}\n onChange={(e) => setEnabled(e.target.checked)}\n className=\"w-4 h-4\"\n />\n <label htmlFor=\"autocorrect-enabled\" className=\"text-sm\">\n 자동 고침 사용\n </label>\n </div>\n\n <DialogSection title=\"새 규칙 추가\">\n <div className=\"flex gap-2 items-end\">\n <div className=\"flex-1\">\n <label className=\"text-xs text-gray-600 block mb-1\">입력</label>\n <input\n type=\"text\"\n value={newFrom}\n onChange={(e) => setNewFrom(e.target.value)}\n placeholder=\"예: (c)\"\n className={`${inputClass} w-full`}\n />\n </div>\n <div className=\"text-gray-400 pb-2\">→</div>\n <div className=\"flex-1\">\n <label className=\"text-xs text-gray-600 block mb-1\">변환</label>\n <input\n type=\"text\"\n value={newTo}\n onChange={(e) => setNewTo(e.target.value)}\n placeholder=\"예: ©\"\n className={`${inputClass} w-full`}\n />\n </div>\n <button\n onClick={handleAddRule}\n disabled={!newFrom.trim() || !newTo.trim()}\n className=\"px-3 py-1.5 text-sm bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-gray-300 disabled:cursor-not-allowed\"\n >\n 추가\n </button>\n </div>\n </DialogSection>\n\n <DialogSection title=\"규칙 목록\">\n <div className=\"max-h-48 overflow-y-auto border border-gray-200 rounded\">\n {rules.length === 0 ? (\n <div className=\"p-3 text-sm text-gray-400 text-center\">\n 등록된 규칙이 없습니다.\n </div>\n ) : (\n rules.map((rule) => (\n <div\n key={rule.from}\n className=\"flex items-center gap-2 px-3 py-2 border-b border-gray-100 last:border-0 hover:bg-gray-50\"\n >\n <input\n type=\"checkbox\"\n checked={rule.enabled}\n onChange={() => handleToggleRule(rule.from)}\n className=\"w-4 h-4\"\n />\n <span className={`text-sm flex-1 ${!rule.enabled ? \"text-gray-400\" : \"\"}`}>\n <span className=\"font-mono bg-gray-100 px-1 rounded\">{rule.from}</span>\n {\" → \"}\n <span className=\"font-mono bg-gray-100 px-1 rounded\">{rule.to}</span>\n </span>\n <button\n onClick={() => handleDeleteRule(rule.from)}\n className=\"text-red-500 hover:text-red-700 text-sm px-2\"\n >\n 삭제\n </button>\n </div>\n ))\n )}\n </div>\n </DialogSection>\n\n <div className=\"flex justify-end mt-3\">\n <button\n onClick={handleReset}\n className=\"text-xs text-gray-500 hover:text-gray-700\"\n >\n 기본값으로 초기화\n </button>\n </div>\n </Dialog>\n );\n}\n","/**\n * Auto-correct system for common typos and text replacements.\n */\n\nexport interface AutoCorrectRule {\n from: string;\n to: string;\n enabled: boolean;\n}\n\n// Default auto-correct rules for Korean and common symbols\nconst DEFAULT_RULES: AutoCorrectRule[] = [\n // Common Korean typos\n { from: \"ㅇㅇ\", to: \"응\", enabled: true },\n { from: \"ㄴㄴ\", to: \"노노\", enabled: true },\n { from: \"ㅎㅎ\", to: \"하하\", enabled: true },\n { from: \"ㄱㄱ\", to: \"고고\", enabled: true },\n { from: \"ㅋㅋ\", to: \"크크\", enabled: false },\n\n // Common symbol replacements\n { from: \"(c)\", to: \"©\", enabled: true },\n { from: \"(C)\", to: \"©\", enabled: true },\n { from: \"(r)\", to: \"®\", enabled: true },\n { from: \"(R)\", to: \"®\", enabled: true },\n { from: \"(tm)\", to: \"™\", enabled: true },\n { from: \"(TM)\", to: \"™\", enabled: true },\n { from: \"...\", to: \"…\", enabled: true },\n { from: \"->\", to: \"→\", enabled: true },\n { from: \"<-\", to: \"←\", enabled: true },\n { from: \"<->\", to: \"↔\", enabled: true },\n { from: \"=>\", to: \"⇒\", enabled: true },\n { from: \"<=\", to: \"⇐\", enabled: true },\n { from: \"1/2\", to: \"½\", enabled: true },\n { from: \"1/4\", to: \"¼\", enabled: true },\n { from: \"3/4\", to: \"¾\", enabled: true },\n { from: \"+-\", to: \"±\", enabled: true },\n { from: \"!=\", to: \"≠\", enabled: true },\n { from: \">=\", to: \"≥\", enabled: true },\n { from: \"<=\", to: \"≤\", enabled: true },\n\n // Common text expansions\n { from: \"btw\", to: \"by the way\", enabled: false },\n { from: \"fyi\", to: \"for your information\", enabled: false },\n { from: \"asap\", to: \"as soon as possible\", enabled: false },\n];\n\nconst STORAGE_KEY = \"hwpx-autocorrect-rules\";\n\nexport class AutoCorrectManager {\n private rules: AutoCorrectRule[] = [];\n private enabled: boolean = true;\n\n constructor() {\n this.loadRules();\n }\n\n loadRules(): void {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const parsed = JSON.parse(stored);\n this.rules = parsed.rules ?? DEFAULT_RULES;\n this.enabled = parsed.enabled ?? true;\n } else {\n this.rules = [...DEFAULT_RULES];\n this.enabled = true;\n }\n } catch {\n this.rules = [...DEFAULT_RULES];\n this.enabled = true;\n }\n }\n\n saveRules(): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify({\n rules: this.rules,\n enabled: this.enabled,\n }));\n } catch (e) {\n console.error(\"Failed to save autocorrect rules:\", e);\n }\n }\n\n getRules(): AutoCorrectRule[] {\n return [...this.rules];\n }\n\n setRules(rules: AutoCorrectRule[]): void {\n this.rules = [...rules];\n this.saveRules();\n }\n\n addRule(from: string, to: string): void {\n const existing = this.rules.find((r) => r.from === from);\n if (existing) {\n existing.to = to;\n existing.enabled = true;\n } else {\n this.rules.push({ from, to, enabled: true });\n }\n this.saveRules();\n }\n\n removeRule(from: string): void {\n this.rules = this.rules.filter((r) => r.from !== from);\n this.saveRules();\n }\n\n toggleRule(from: string): void {\n const rule = this.rules.find((r) => r.from === from);\n if (rule) {\n rule.enabled = !rule.enabled;\n this.saveRules();\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n this.saveRules();\n }\n\n /**\n * Apply auto-correct to the given text.\n * Returns the corrected text and whether any corrections were made.\n */\n apply(text: string): { text: string; corrected: boolean } {\n if (!this.enabled) {\n return { text, corrected: false };\n }\n\n let result = text;\n let corrected = false;\n\n for (const rule of this.rules) {\n if (!rule.enabled) continue;\n if (result.includes(rule.from)) {\n result = result.split(rule.from).join(rule.to);\n corrected = true;\n }\n }\n\n return { text: result, corrected };\n }\n\n /**\n * Check if the text ends with a pattern that should trigger auto-correct.\n * Used for real-time correction as user types.\n */\n checkEndOfText(text: string): { replacement: string; length: number } | null {\n if (!this.enabled) return null;\n\n for (const rule of this.rules) {\n if (!rule.enabled) continue;\n if (text.endsWith(rule.from)) {\n return {\n replacement: rule.to,\n length: rule.from.length,\n };\n }\n }\n\n return null;\n }\n\n resetToDefaults(): void {\n this.rules = [...DEFAULT_RULES];\n this.enabled = true;\n this.saveRules();\n }\n}\n\n// Singleton instance\nexport const autoCorrectManager = new AutoCorrectManager();\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst OUTLINE_STYLES = [\n {\n id: \"none\",\n name: \"없음\",\n levels: [],\n },\n {\n id: \"numeric\",\n name: \"숫자 (1, 1.1, 1.1.1)\",\n levels: [\"1.\", \"1.1.\", \"1.1.1.\", \"1.1.1.1.\"],\n },\n {\n id: \"korean\",\n name: \"가나다 (가, 나, 다)\",\n levels: [\"가.\", \"나.\", \"다.\", \"라.\"],\n },\n {\n id: \"roman\",\n name: \"로마자 (I, II, III)\",\n levels: [\"I.\", \"II.\", \"III.\", \"IV.\"],\n },\n {\n id: \"alpha\",\n name: \"알파벳 (A, B, C)\",\n levels: [\"A.\", \"B.\", \"C.\", \"D.\"],\n },\n {\n id: \"mixed1\",\n name: \"혼합1 (1, 가, 1), (1))\",\n levels: [\"1.\", \"가.\", \"1)\", \"(1)\"],\n },\n {\n id: \"mixed2\",\n name: \"혼합2 (I, A, 1, a)\",\n levels: [\"I.\", \"A.\", \"1.\", \"a.\"],\n },\n {\n id: \"circle\",\n name: \"원문자 (①, ②, ③)\",\n levels: [\"①\", \"②\", \"③\", \"④\"],\n },\n];\n\nexport function OutlineDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closeOutlineDialog = useEditorStore((s) => s.closeOutlineDialog);\n const applyOutlineLevel = useEditorStore((s) => s.applyOutlineLevel);\n\n const [selectedStyle, setSelectedStyle] = useState(0);\n const [selectedLevel, setSelectedLevel] = useState(1);\n\n const handleApply = () => {\n if (selectedStyle === 0) {\n // Remove outline\n applyOutlineLevel(0);\n } else {\n applyOutlineLevel(selectedLevel);\n }\n closeOutlineDialog();\n };\n\n const currentStyle = OUTLINE_STYLES[selectedStyle];\n\n return (\n <Dialog\n title=\"개요 번호 모양\"\n open={uiState.outlineDialogOpen}\n onClose={closeOutlineDialog}\n onApply={handleApply}\n width={480}\n >\n <DialogSection title=\"개요 스타일\">\n <div className=\"grid grid-cols-2 gap-2\">\n {OUTLINE_STYLES.map((style, idx) => (\n <button\n key={style.id}\n onClick={() => setSelectedStyle(idx)}\n className={`p-3 rounded border text-left transition-colors ${\n selectedStyle === idx\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"text-sm font-medium\">{style.name}</div>\n {style.levels.length > 0 && (\n <div className=\"text-xs text-gray-500 mt-1\">\n {style.levels.slice(0, 3).join(\" → \")}\n </div>\n )}\n </button>\n ))}\n </div>\n </DialogSection>\n\n {selectedStyle !== 0 && (\n <DialogSection title=\"개요 수준\">\n <div className=\"flex gap-2\">\n {[1, 2, 3, 4, 5, 6, 7].map((level) => (\n <button\n key={level}\n onClick={() => setSelectedLevel(level)}\n className={`w-10 h-10 rounded border text-sm font-medium transition-colors ${\n selectedLevel === level\n ? \"border-blue-500 bg-blue-500 text-white\"\n : \"border-gray-300 bg-white hover:bg-gray-50\"\n }`}\n >\n {level}\n </button>\n ))}\n </div>\n <div className=\"text-xs text-gray-500 mt-2\">\n 선택한 수준: {selectedLevel} (들여쓰기 {(selectedLevel - 1) * 10}mm)\n </div>\n </DialogSection>\n )}\n\n <DialogSection title=\"미리보기\">\n <div className=\"border border-gray-200 rounded p-3 bg-gray-50 min-h-[100px]\">\n {currentStyle && currentStyle.levels.length > 0 ? (\n <div className=\"space-y-1\">\n {currentStyle.levels.map((prefix, idx) => (\n <div\n key={idx}\n className=\"flex items-center text-sm\"\n style={{ paddingLeft: `${idx * 16}px` }}\n >\n <span className=\"text-blue-600 font-medium mr-2\">{prefix}</span>\n <span className=\"text-gray-600\">\n {idx + 1}수준 개요 항목\n </span>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"text-gray-400 text-sm text-center py-4\">\n 개요 없음\n </div>\n )}\n </div>\n </DialogSection>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\nimport { Square, Circle, Minus, ArrowRight } from \"lucide-react\";\nimport type { ShapeType } from \"@/lib/store/types\";\n\nconst SHAPE_OPTIONS: { type: ShapeType; label: string; icon: React.ReactNode }[] = [\n { type: \"rectangle\", label: \"직사각형\", icon: <Square className=\"w-8 h-8\" /> },\n { type: \"ellipse\", label: \"원/타원\", icon: <Circle className=\"w-8 h-8\" /> },\n { type: \"line\", label: \"선\", icon: <Minus className=\"w-8 h-8\" /> },\n { type: \"arrow\", label: \"화살표\", icon: <ArrowRight className=\"w-8 h-8\" /> },\n];\n\nexport function ShapeDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closeShapeDialog = useEditorStore((s) => s.closeShapeDialog);\n const insertShape = useEditorStore((s) => s.insertShape);\n\n const [selectedShape, setSelectedShape] = useState<ShapeType>(\"rectangle\");\n const [width, setWidth] = useState(50);\n const [height, setHeight] = useState(30);\n\n const handleApply = () => {\n insertShape(selectedShape, width, height);\n closeShapeDialog();\n };\n\n const isLineType = selectedShape === \"line\" || selectedShape === \"arrow\";\n\n return (\n <Dialog\n title=\"도형 삽입\"\n open={uiState.shapeDialogOpen}\n onClose={closeShapeDialog}\n onApply={handleApply}\n width={420}\n >\n <DialogSection title=\"도형 종류\">\n <div className=\"grid grid-cols-4 gap-3\">\n {SHAPE_OPTIONS.map((shape) => (\n <button\n key={shape.type}\n onClick={() => setSelectedShape(shape.type)}\n className={`flex flex-col items-center justify-center p-4 rounded-lg border-2 transition-colors ${\n selectedShape === shape.type\n ? \"border-blue-500 bg-blue-50 text-blue-700\"\n : \"border-gray-200 bg-white hover:border-gray-300 text-gray-600\"\n }`}\n >\n {shape.icon}\n <span className=\"text-xs mt-2\">{shape.label}</span>\n </button>\n ))}\n </div>\n </DialogSection>\n\n <DialogSection title=\"크기 (mm)\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-xs text-gray-600 mb-1\">\n {isLineType ? \"길이\" : \"너비\"}\n </label>\n <input\n type=\"number\"\n value={width}\n onChange={(e) => setWidth(Number(e.target.value))}\n min={5}\n max={200}\n className=\"w-full px-3 py-2 border border-gray-300 rounded text-sm\"\n />\n </div>\n {!isLineType && (\n <div>\n <label className=\"block text-xs text-gray-600 mb-1\">높이</label>\n <input\n type=\"number\"\n value={height}\n onChange={(e) => setHeight(Number(e.target.value))}\n min={5}\n max={200}\n className=\"w-full px-3 py-2 border border-gray-300 rounded text-sm\"\n />\n </div>\n )}\n </div>\n </DialogSection>\n\n <DialogSection title=\"미리보기\">\n <div className=\"border border-gray-200 rounded p-4 bg-gray-50 flex items-center justify-center min-h-[120px]\">\n <div\n className=\"relative\"\n style={{\n width: `${Math.min(width, 100)}px`,\n height: isLineType ? \"2px\" : `${Math.min(height, 80)}px`,\n }}\n >\n {selectedShape === \"rectangle\" && (\n <div className=\"w-full h-full border-2 border-gray-700 bg-white rounded\" />\n )}\n {selectedShape === \"ellipse\" && (\n <div className=\"w-full h-full border-2 border-gray-700 bg-white rounded-full\" />\n )}\n {selectedShape === \"line\" && (\n <div className=\"w-full h-0.5 bg-gray-700\" />\n )}\n {selectedShape === \"arrow\" && (\n <div className=\"w-full flex items-center\">\n <div className=\"flex-1 h-0.5 bg-gray-700\" />\n <div className=\"w-0 h-0 border-l-[8px] border-l-gray-700 border-y-[4px] border-y-transparent\" />\n </div>\n )}\n </div>\n </div>\n </DialogSection>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { useEditorStore } from \"@/lib/store\";\nimport { Dialog } from \"./Dialog\";\nimport { DialogSection } from \"./DialogSection\";\n\nconst TAB_LEADER_STYLES = [\n { id: \"DOT\", name: \"점선 (.....)\", preview: \"제목 ..... 페이지\" },\n { id: \"HYPHEN\", name: \"하이픈 (-----)\", preview: \"제목 ----- 페이지\" },\n { id: \"UNDERLINE\", name: \"밑줄 (_____)\", preview: \"제목 _____ 페이지\" },\n { id: \"NONE\", name: \"없음\", preview: \"제목 페이지\" },\n];\n\nconst TOC_TITLES = [\n { id: \"차례\", name: \"차례\" },\n { id: \"목차\", name: \"목차\" },\n { id: \"TABLE_OF_CONTENTS\", name: \"TABLE OF CONTENTS\" },\n { id: \"CONTENTS\", name: \"CONTENTS\" },\n];\n\nexport function TocDialog() {\n const uiState = useEditorStore((s) => s.uiState);\n const closeTocDialog = useEditorStore((s) => s.closeTocDialog);\n const applyOutlineLevel = useEditorStore((s) => s.applyOutlineLevel);\n const insertToc = useEditorStore((s) => s.insertToc);\n\n const [selectedTitle, setSelectedTitle] = useState(\"차례\");\n const [tabLeader, setTabLeader] = useState<\"DOT\" | \"HYPHEN\" | \"UNDERLINE\" | \"NONE\">(\"DOT\");\n const [tabWidth, setTabWidth] = useState(12000);\n const [maxLevel, setMaxLevel] = useState(9);\n const [showPageNumbers, setShowPageNumbers] = useState(true);\n\n const handleApply = () => {\n // Generate TOC with selected options\n insertToc({\n title: selectedTitle,\n tabLeader,\n tabWidth,\n maxLevel,\n showPageNumbers,\n });\n closeTocDialog();\n };\n\n return (\n <Dialog\n title=\"차례 만들기\"\n open={uiState.tocDialogOpen}\n onClose={closeTocDialog}\n onApply={handleApply}\n width={500}\n >\n <DialogSection title=\"차례 제목\">\n <div className=\"grid grid-cols-2 gap-2\">\n {TOC_TITLES.map((title) => (\n <button\n key={title.id}\n onClick={() => setSelectedTitle(title.name)}\n className={`p-3 rounded border text-left transition-colors ${\n selectedTitle === title.name\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"text-sm font-medium\">{title.name}</div>\n </button>\n ))}\n </div>\n <input\n type=\"text\"\n value={selectedTitle}\n onChange={(e) => setSelectedTitle(e.target.value)}\n className=\"mt-2 w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500\"\n placeholder=\"직접 입력...\"\n />\n </DialogSection>\n\n <DialogSection title=\"탭 리더 (점선 스타일)\">\n <div className=\"grid grid-cols-2 gap-2\">\n {TAB_LEADER_STYLES.map((style) => (\n <button\n key={style.id}\n onClick={() => setTabLeader(style.id as any)}\n className={`p-3 rounded border text-left transition-colors ${\n tabLeader === style.id\n ? \"border-blue-500 bg-blue-50 ring-2 ring-blue-200\"\n : \"border-gray-200 bg-white hover:border-gray-300\"\n }`}\n >\n <div className=\"text-sm font-medium\">{style.name}</div>\n <div className=\"text-xs text-gray-500 mt-1 font-mono\">\n {style.preview}\n </div>\n </button>\n ))}\n </div>\n </DialogSection>\n\n <DialogSection title=\"옵션\">\n <div className=\"space-y-4\">\n {/* 최대 레벨 */}\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-2\">\n 최대 레벨: {maxLevel}\n </label>\n <input\n type=\"range\"\n min=\"1\"\n max=\"9\"\n value={maxLevel}\n onChange={(e) => setMaxLevel(Number(e.target.value))}\n className=\"w-full\"\n />\n <div className=\"flex justify-between text-xs text-gray-500 mt-1\">\n <span>1</span>\n <span>9</span>\n </div>\n </div>\n\n {/* 탭 너비 */}\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-2\">\n 탭 위치: {tabWidth} hwpUnit\n </label>\n <input\n type=\"range\"\n min=\"5000\"\n max=\"20000\"\n step=\"500\"\n value={tabWidth}\n onChange={(e) => setTabWidth(Number(e.target.value))}\n className=\"w-full\"\n />\n <div className=\"flex justify-between text-xs text-gray-500 mt-1\">\n <span>5000</span>\n <span>20000</span>\n </div>\n </div>\n\n {/* 페이지 번호 표시 */}\n <div className=\"flex items-center justify-between\">\n <label className=\"text-sm font-medium text-gray-700\">\n 페이지 번호 표시\n </label>\n <button\n onClick={() => setShowPageNumbers(!showPageNumbers)}\n className={`w-12 h-6 rounded-full transition-colors ${\n showPageNumbers\n ? \"bg-blue-500 text-white\"\n : \"bg-gray-300 text-gray-600\"\n }`}\n >\n {showPageNumbers ? \"ON\" : \"OFF\"}\n </button>\n </div>\n </div>\n </DialogSection>\n\n <DialogSection title=\"미리보기\">\n <div className=\"border border-gray-200 rounded p-4 bg-gray-50\">\n <div className=\"text-center font-bold mb-3\">{selectedTitle}</div>\n <div className=\"space-y-2\">\n {[1, 2, 3].slice(0, maxLevel).map((level) => (\n <div\n key={level}\n className=\"flex items-center text-sm\"\n style={{ paddingLeft: `${(level - 1) * 20}px` }}\n >\n <span className=\"text-gray-700\">\n {level}수준 제목\n </span>\n {tabLeader !== \"NONE\" && (\n <span className=\"flex-1 border-b border-gray-400 mx-2\" style={{\n borderBottomStyle: tabLeader === \"DOT\" ? \"dotted\" :\n tabLeader === \"HYPHEN\" ? \"dashed\" : \"solid\",\n }} />\n )}\n {showPageNumbers && (\n <span className=\"text-gray-500\">{level * 10}</span>\n )}\n </div>\n ))}\n </div>\n </div>\n </DialogSection>\n </Dialog>\n );\n}\n"],"mappings":"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","names":["import_react","import_hwpxcore","_a","_b","import_hwpxcore","section","para","import_hwpxcore","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_react","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","PX_TO_MM","roundMm","_a","widthMm","heightMm","import_react","import_jsx_runtime","roundMm","import_react","import_lucide_react","import_jsx_runtime","BORDER_TYPES","BORDER_WIDTHS","roundMm","mmToHwp","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","_a","_b","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_lucide_react","import_hwpxcore","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","TABS","BasicTab","ExtendedTab","import_react","import_jsx_runtime","TABS","import_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_lucide_react","import_jsx_runtime","import_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime"]}