@yurikilian/lex4 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/components/BlockTypePicker.d.ts +1 -1
- package/dist/components/BlockTypePicker.d.ts.map +1 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/context/document-provider.d.ts.map +1 -1
- package/dist/context/toolbar-style-snapshot.d.ts +4 -0
- package/dist/context/toolbar-style-snapshot.d.ts.map +1 -0
- package/dist/context/toolbar-style-store.d.ts +28 -0
- package/dist/context/toolbar-style-store.d.ts.map +1 -0
- package/dist/lex4-editor.cjs +544 -161
- package/dist/lex4-editor.cjs.map +1 -1
- package/dist/lex4-editor.js +547 -164
- package/dist/lex4-editor.js.map +1 -1
- package/dist/lexical/commands/block-commands.d.ts +1 -1
- package/dist/lexical/commands/block-commands.d.ts.map +1 -1
- package/dist/lexical/commands/block-types.d.ts +2 -0
- package/dist/lexical/commands/block-types.d.ts.map +1 -0
- package/dist/style.css +31 -27
- package/dist/utils/text-style.d.ts +6 -0
- package/dist/utils/text-style.d.ts.map +1 -1
- package/dist/variables/variable-formatting.d.ts +1 -0
- package/dist/variables/variable-formatting.d.ts.map +1 -1
- package/dist/variables/variable-node.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/lex4-editor.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex4-editor.cjs","sources":["../src/types/document.ts","../src/context/document-context.ts","../src/constants/dimensions.ts","../src/utils/debug.ts","../src/context/document-reducer.ts","../src/utils/history-manager.ts","../src/i18n/defaults.ts","../src/i18n/pt-BR.ts","../src/i18n/context.tsx","../src/context/document-provider.tsx","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/context.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/a-large-small.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/bold.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/braces.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/check.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/chevron-down.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/copy-plus.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eraser.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/file-text.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/history.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/italic.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list-indent-decrease.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list-indent-increase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list-ordered.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/redo-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/refresh-cw.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/search.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/settings-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/strikethrough.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-center.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-end.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-justify.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-start.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/underline.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/undo-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/x.js","../src/components/EditorSidebar.tsx","../src/components/HistorySidebar.tsx","../src/context/toolbar-config.tsx","../src/extensions/types.ts","../src/extensions/extension-context.tsx","../src/lexical/plugins/font-plugin.tsx","../src/lexical/plugins/font-size-plugin.tsx","../src/lexical/commands/format-commands.ts","../src/lexical/commands/list-commands.ts","../src/lexical/commands/block-commands.ts","../src/utils/text-style.ts","../src/variables/variable-context.tsx","../src/variables/variable-node.tsx","../src/variables/variable-formatting.ts","../src/components/BlockTypePicker.tsx","../src/components/HeaderFooterToggle.tsx","../src/components/HeaderFooterActions.tsx","../src/components/CanvasControls.tsx","../src/components/Toolbar.tsx","../src/constants/page-layout.ts","../src/utils/editor-state-utils.ts","../src/hooks/use-pagination.ts","../src/lexical/theme.ts","../src/lexical/editor-setup.ts","../src/lexical/plugins/tab-indent-plugin.tsx","../src/lexical/plugins/paragraph-indent-plugin.tsx","../src/lexical/plugins/paste-plugin.tsx","../src/lexical/plugins/active-editor-plugin.tsx","../src/lexical/utils/mid-block-split.ts","../src/lexical/plugins/overflow-plugin.tsx","../src/lexical/plugins/history-capture-plugin.tsx","../src/lexical/plugins/page-boundary-plugin.tsx","../src/components/PageBody.tsx","../src/lexical/plugins/height-limit-plugin.tsx","../src/components/PageHeader.tsx","../src/components/PageFooter.tsx","../src/components/PageView.tsx","../src/components/DocumentView.tsx","../src/ast/types.ts","../src/ast/inline-mapper.ts","../src/ast/block-mapper.ts","../src/ast/content-mapper.ts","../src/ast/document-serializer.ts","../src/ast/payload-builder.ts","../src/lexical/utils/import-document-content.ts","../src/utils/document-insert-target.ts","../src/components/Lex4Editor.tsx","../src/hooks/use-overflow-detection.ts","../src/hooks/use-header-footer.ts","../src/extensions/ast-extension.ts","../src/variables/variable-commands.ts","../src/variables/variable-plugin.tsx","../src/components/VariablePanel.tsx","../src/extensions/variables-extension.tsx"],"sourcesContent":["import type { SerializedEditorState } from 'lexical';\n\nexport type PageCounterMode = 'none' | 'header' | 'footer' | 'both';\n\nexport interface PageChromeTemplate {\n headerState: SerializedEditorState | null;\n footerState: SerializedEditorState | null;\n headerHeight: number;\n footerHeight: number;\n}\n\n/** State for a single page in the document */\nexport interface PageState {\n id: string;\n bodyState: SerializedEditorState | null;\n headerState: SerializedEditorState | null;\n footerState: SerializedEditorState | null;\n headerHeight: number;\n footerHeight: number;\n /** Incremented on external body state changes (reflow/undo) to force editor remount */\n bodySyncVersion: number;\n /** Incremented on external header state changes (copy/clear) to force editor remount */\n headerSyncVersion: number;\n /** Incremented on external footer state changes (copy/clear) to force editor remount */\n footerSyncVersion: number;\n}\n\n/** Top-level document state */\nexport interface Lex4Document {\n pages: PageState[];\n headerFooterEnabled: boolean;\n pageCounterMode: PageCounterMode;\n defaultHeaderState: SerializedEditorState | null;\n defaultFooterState: SerializedEditorState | null;\n defaultHeaderHeight: number;\n defaultFooterHeight: number;\n}\n\n/** Creates a default empty page */\nexport function createEmptyPage(id?: string): PageState {\n return {\n id: id ?? crypto.randomUUID(),\n bodyState: null,\n headerState: null,\n footerState: null,\n headerHeight: 0,\n footerHeight: 0,\n bodySyncVersion: 0,\n headerSyncVersion: 0,\n footerSyncVersion: 0,\n };\n}\n\n/** Creates a new page that inherits header/footer chrome from a document default template. */\nexport function createPageFromTemplate(template?: PageChromeTemplate): PageState {\n return {\n ...createEmptyPage(),\n headerState: template?.headerState ?? null,\n footerState: template?.footerState ?? null,\n headerHeight: template?.headerHeight ?? 0,\n footerHeight: template?.footerHeight ?? 0,\n };\n}\n\n/** Creates a default empty document */\nexport function createEmptyDocument(): Lex4Document {\n return {\n pages: [createEmptyPage()],\n headerFooterEnabled: false,\n pageCounterMode: 'none',\n defaultHeaderState: null,\n defaultFooterState: null,\n defaultHeaderHeight: 0,\n defaultFooterHeight: 0,\n };\n}\n","import { createContext, useContext } from 'react';\nimport type { Lex4Document, PageCounterMode } from '../types/document';\nimport type { LexicalEditor } from 'lexical';\nimport type {\n CaretPosition,\n CaretSelection,\n HistoryActionDescriptor,\n HistoryEntry,\n} from '../types/history';\n\n/** All actions the document reducer can handle */\nexport type DocumentAction =\n | { type: 'ADD_PAGE'; afterIndex?: number; page?: import('../types/document').PageState }\n | { type: 'REMOVE_PAGE'; pageId: string }\n | { type: 'UPDATE_PAGE_BODY'; pageId: string; bodyState: import('lexical').SerializedEditorState | null }\n | {\n type: 'UPDATE_PAGE_HEADER_CONTENT';\n pageId: string;\n headerState: import('lexical').SerializedEditorState | null;\n height: number;\n }\n | {\n type: 'UPDATE_PAGE_FOOTER_CONTENT';\n pageId: string;\n footerState: import('lexical').SerializedEditorState | null;\n height: number;\n }\n | { type: 'UPDATE_PAGE_HEADER'; pageId: string; headerState: import('lexical').SerializedEditorState | null }\n | { type: 'UPDATE_PAGE_FOOTER'; pageId: string; footerState: import('lexical').SerializedEditorState | null }\n | { type: 'SET_HEADER_FOOTER_ENABLED'; enabled: boolean }\n | { type: 'SET_PAGE_COUNTER_MODE'; mode: PageCounterMode }\n | { type: 'COPY_HEADER_TO_ALL'; sourcePageId: string }\n | { type: 'COPY_FOOTER_TO_ALL'; sourcePageId: string }\n | { type: 'CLEAR_HEADER'; pageId: string }\n | { type: 'CLEAR_FOOTER'; pageId: string }\n | { type: 'CLEAR_ALL_HEADERS' }\n | { type: 'CLEAR_ALL_FOOTERS' }\n | { type: 'CLEAR_DOCUMENT_CONTENT' }\n | { type: 'SET_HEADER_HEIGHT'; pageId: string; height: number }\n | { type: 'SET_FOOTER_HEIGHT'; pageId: string; height: number }\n | { type: 'SET_DOCUMENT'; document: Lex4Document };\n\n/** Registry of page editors for direct cross-page content manipulation */\nexport interface EditorRegistry {\n register(pageId: string, editor: LexicalEditor): void;\n unregister(pageId: string, editor?: LexicalEditor): void;\n get(pageId: string): LexicalEditor | undefined;\n all(): LexicalEditor[];\n}\n\n/** Shape of the document context value */\nexport interface DocumentContextValue {\n document: Lex4Document;\n dispatch: React.Dispatch<DocumentAction>;\n activePageId: string | null;\n setActivePageId: (id: string | null) => void;\n activeEditor: LexicalEditor | null;\n activeCaretPosition: CaretPosition | null;\n setActiveEditor: (editor: LexicalEditor | null, caretPosition?: CaretPosition | null) => void;\n consumePendingCaretPosition: (caretPosition: CaretPosition) => CaretSelection | null | undefined;\n consumePendingFocusAtEnd: (caretPosition: CaretPosition) => boolean;\n requestFocusAtEnd: (caretPosition: CaretPosition) => void;\n focusAtEndVersion: number;\n globalSelectionActive: boolean;\n setGlobalSelectionActive: (active: boolean) => void;\n historyEntries: HistoryEntry[];\n historyCursor: number;\n canUndo: boolean;\n canRedo: boolean;\n queueHistoryAction: (action: HistoryActionDescriptor | null) => void;\n runHistoryAction: (action: HistoryActionDescriptor, callback: () => void) => void;\n jumpToHistoryEntry: (entryIndex: number) => void;\n clearHistory: (reason?: string) => void;\n historySidebarOpen: boolean;\n setHistorySidebarOpen: (open: boolean) => void;\n undo: () => void;\n redo: () => void;\n editorRegistry: EditorRegistry;\n}\n\nexport const DocumentContext = createContext<DocumentContextValue | null>(null);\n\n/** Hook to access the document context. Throws if used outside provider. */\nexport function useDocument(): DocumentContextValue {\n const ctx = useContext(DocumentContext);\n if (!ctx) {\n throw new Error('useDocument must be used within a DocumentProvider');\n }\n return ctx;\n}\n","/**\n * A4 page dimensions and layout constants.\n *\n * All values derived from the A4 standard (210mm × 297mm)\n * converted to CSS pixels at 96 DPI.\n */\n\nexport const A4_WIDTH_MM = 210;\nexport const A4_HEIGHT_MM = 297;\n\n/** CSS pixels per millimeter at 96 DPI */\nexport const PX_PER_MM = 96 / 25.4;\n\n/** A4 width in CSS pixels (≈794px) */\nexport const A4_WIDTH_PX = Math.round(A4_WIDTH_MM * PX_PER_MM);\n\n/** A4 height in CSS pixels (≈1123px) */\nexport const A4_HEIGHT_PX = Math.round(A4_HEIGHT_MM * PX_PER_MM);\n\n/** Standard A4 margin: 30mm on all sides (European standard) in CSS pixels */\nexport const PAGE_MARGIN_TOP_PX = Math.round(30 * PX_PER_MM);\nexport const PAGE_MARGIN_BOTTOM_PX = Math.round(30 * PX_PER_MM);\nexport const PAGE_MARGIN_LEFT_PX = Math.round(30 * PX_PER_MM);\nexport const PAGE_MARGIN_RIGHT_PX = Math.round(30 * PX_PER_MM);\n\n/** Maximum header height as a ratio of page height */\nexport const MAX_HEADER_RATIO = 0.2;\n\n/** Maximum footer height as a ratio of page height */\nexport const MAX_FOOTER_RATIO = 0.2;\n\n/** Maximum header height in CSS pixels */\nexport const MAX_HEADER_HEIGHT_PX = Math.round(A4_HEIGHT_PX * MAX_HEADER_RATIO);\n\n/** Maximum footer height in CSS pixels */\nexport const MAX_FOOTER_HEIGHT_PX = Math.round(A4_HEIGHT_PX * MAX_FOOTER_RATIO);\n","/**\n * Lex4 Debug Logger\n *\n * Zero-cost when disabled. Enable in the browser console:\n *\n * localStorage.setItem('lex4:debug', '*') // all channels\n * localStorage.setItem('lex4:debug', 'overflow,reducer') // specific channels\n * window.__LEX4_DEBUG__ = true // all channels (session only)\n *\n * Disable:\n * localStorage.removeItem('lex4:debug')\n * window.__LEX4_DEBUG__ = false\n *\n * Channels:\n * reducer — every dispatched action and resulting state\n * overflow — overflow detection, measurement, split decisions\n * registry — editor registry register/unregister/get\n * page — page creation, initial state loading, body changes\n * toolbar — formatting command dispatches\n * header — header height changes, content changes\n * footer — footer height changes, content changes\n * focus — editor focus changes, active editor/page tracking\n */\n\nexport type DebugChannel =\n | 'reducer'\n | 'overflow'\n | 'registry'\n | 'page'\n | 'toolbar'\n | 'header'\n | 'footer'\n | 'focus';\n\nconst CHANNEL_COLORS: Record<DebugChannel, string> = {\n reducer: '#e91e63',\n overflow: '#ff5722',\n registry: '#9c27b0',\n page: '#2196f3',\n toolbar: '#4caf50',\n header: '#ff9800',\n footer: '#795548',\n focus: '#607d8b',\n};\n\ndeclare global {\n interface Window {\n __LEX4_DEBUG__?: boolean | string;\n }\n}\n\nfunction getFlag(): string | boolean | null {\n if (typeof window === 'undefined') return null;\n\n const win = (window as Window).__LEX4_DEBUG__;\n if (win !== undefined && win !== null) return win;\n\n if (typeof localStorage !== 'undefined') {\n return localStorage.getItem('lex4:debug');\n }\n\n return null;\n}\n\nfunction isEnabled(channel: DebugChannel): boolean {\n const flag = getFlag();\n if (!flag) return false;\n if (flag === true || flag === '*' || flag === 'true') return true;\n\n if (typeof flag === 'string') {\n return flag.split(',').some(s => s.trim() === channel);\n }\n\n return false;\n}\n\n/**\n * Log a debug message on the given channel.\n * No-ops instantly when the channel is disabled.\n */\nexport function debug(channel: DebugChannel, message: string, ...data: unknown[]): void {\n if (!isEnabled(channel)) return;\n\n const color = CHANNEL_COLORS[channel];\n const prefix = `%c[lex4:${channel}]`;\n const style = `color: ${color}; font-weight: bold;`;\n\n if (data.length > 0) {\n console.log(prefix, style, message, ...data);\n } else {\n console.log(prefix, style, message);\n }\n}\n\n/**\n * Log a warning on the given channel.\n */\nexport function debugWarn(channel: DebugChannel, message: string, ...data: unknown[]): void {\n if (!isEnabled(channel)) return;\n\n const color = CHANNEL_COLORS[channel];\n const prefix = `%c[lex4:${channel}]`;\n const style = `color: ${color}; font-weight: bold;`;\n\n if (data.length > 0) {\n console.warn(prefix, style, message, ...data);\n } else {\n console.warn(prefix, style, message);\n }\n}\n\n/** Short-id helper: first 8 chars of a UUID for readable logs */\nexport function shortId(id: string): string {\n return id.substring(0, 8);\n}\n","import type { Lex4Document } from '../types/document';\nimport { createEmptyPage } from '../types/document';\nimport type { DocumentAction } from './document-context';\nimport { MAX_HEADER_HEIGHT_PX, MAX_FOOTER_HEIGHT_PX } from '../constants/dimensions';\nimport { debug, shortId } from '../utils/debug';\n\nfunction serializedStateChanged(\n current: import('lexical').SerializedEditorState | null,\n next: import('lexical').SerializedEditorState | null,\n): boolean {\n return JSON.stringify(current) !== JSON.stringify(next);\n}\n\nfunction withExternalSyncVersions(\n currentDocument: Lex4Document,\n nextDocument: Lex4Document,\n): Lex4Document {\n const currentPages = new Map(currentDocument.pages.map(page => [page.id, page]));\n\n return {\n ...nextDocument,\n pages: nextDocument.pages.map(nextPage => {\n const currentPage = currentPages.get(nextPage.id);\n if (!currentPage) {\n return nextPage;\n }\n\n const bodyChanged = serializedStateChanged(currentPage.bodyState, nextPage.bodyState);\n const headerChanged =\n currentPage.headerHeight !== nextPage.headerHeight ||\n serializedStateChanged(currentPage.headerState, nextPage.headerState);\n const footerChanged =\n currentPage.footerHeight !== nextPage.footerHeight ||\n serializedStateChanged(currentPage.footerState, nextPage.footerState);\n\n return {\n ...nextPage,\n bodySyncVersion: bodyChanged ? currentPage.bodySyncVersion + 1 : currentPage.bodySyncVersion,\n headerSyncVersion: headerChanged ? currentPage.headerSyncVersion + 1 : currentPage.headerSyncVersion,\n footerSyncVersion: footerChanged ? currentPage.footerSyncVersion + 1 : currentPage.footerSyncVersion,\n };\n }),\n };\n}\n\n/**\n * Pure reducer for document state.\n * Handles all page-level and document-level mutations.\n */\nexport function documentReducer(state: Lex4Document, action: DocumentAction): Lex4Document {\n switch (action.type) {\n case 'ADD_PAGE': {\n const newPage = action.page ?? createEmptyPage();\n const pages = [...state.pages];\n const insertAt = action.afterIndex !== undefined ? action.afterIndex + 1 : pages.length;\n pages.splice(insertAt, 0, newPage);\n const hasBody = !!(action.page?.bodyState?.root?.children?.length);\n debug('reducer', `ADD_PAGE id=${shortId(newPage.id)} at=${insertAt} withBody=${hasBody} totalPages=${pages.length}`);\n return { ...state, pages };\n }\n\n case 'REMOVE_PAGE': {\n if (state.pages.length <= 1) {\n debug('reducer', `REMOVE_PAGE id=${shortId(action.pageId)} — skipped (last page)`);\n return state;\n }\n debug('reducer', `REMOVE_PAGE id=${shortId(action.pageId)} remaining=${state.pages.length - 1}`);\n return {\n ...state,\n pages: state.pages.filter(p => p.id !== action.pageId),\n };\n }\n\n case 'UPDATE_PAGE_BODY': {\n const childCount = action.bodyState?.root?.children?.length ?? 0;\n debug('reducer', `UPDATE_PAGE_BODY id=${shortId(action.pageId)} children=${childCount}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, bodyState: action.bodyState } : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_HEADER': {\n debug('reducer', `UPDATE_PAGE_HEADER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, headerState: action.headerState } : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_HEADER_CONTENT': {\n const clamped = Math.min(action.height, MAX_HEADER_HEIGHT_PX);\n debug('reducer', `UPDATE_PAGE_HEADER_CONTENT id=${shortId(action.pageId)} height=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, headerState: action.headerState, headerHeight: clamped }\n : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_FOOTER': {\n debug('reducer', `UPDATE_PAGE_FOOTER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, footerState: action.footerState } : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_FOOTER_CONTENT': {\n const clamped = Math.min(action.height, MAX_FOOTER_HEIGHT_PX);\n debug('reducer', `UPDATE_PAGE_FOOTER_CONTENT id=${shortId(action.pageId)} height=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, footerState: action.footerState, footerHeight: clamped }\n : p,\n ),\n };\n }\n\n case 'SET_HEADER_FOOTER_ENABLED': {\n debug('reducer', `SET_HEADER_FOOTER_ENABLED enabled=${action.enabled}`);\n return { ...state, headerFooterEnabled: action.enabled };\n }\n\n case 'SET_PAGE_COUNTER_MODE': {\n debug('reducer', `SET_PAGE_COUNTER_MODE mode=${action.mode}`);\n return { ...state, pageCounterMode: action.mode };\n }\n\n case 'COPY_HEADER_TO_ALL': {\n debug('reducer', `COPY_HEADER_TO_ALL from=${shortId(action.sourcePageId)}`);\n const source = state.pages.find(p => p.id === action.sourcePageId);\n if (!source) return state;\n return {\n ...state,\n defaultHeaderState: source.headerState,\n defaultHeaderHeight: source.headerHeight,\n pages: state.pages.map(p => ({\n ...p,\n headerState: source.headerState,\n headerHeight: source.headerHeight,\n headerSyncVersion: p.headerSyncVersion + 1,\n })),\n };\n }\n\n case 'COPY_FOOTER_TO_ALL': {\n debug('reducer', `COPY_FOOTER_TO_ALL from=${shortId(action.sourcePageId)}`);\n const source = state.pages.find(p => p.id === action.sourcePageId);\n if (!source) return state;\n return {\n ...state,\n defaultFooterState: source.footerState,\n defaultFooterHeight: source.footerHeight,\n pages: state.pages.map(p => ({\n ...p,\n footerState: source.footerState,\n footerHeight: source.footerHeight,\n footerSyncVersion: p.footerSyncVersion + 1,\n })),\n };\n }\n\n case 'CLEAR_HEADER': {\n debug('reducer', `CLEAR_HEADER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, headerState: null, headerHeight: 0, headerSyncVersion: p.headerSyncVersion + 1 }\n : p,\n ),\n };\n }\n\n case 'CLEAR_FOOTER': {\n debug('reducer', `CLEAR_FOOTER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, footerState: null, footerHeight: 0, footerSyncVersion: p.footerSyncVersion + 1 }\n : p,\n ),\n };\n }\n\n case 'CLEAR_ALL_HEADERS': {\n debug('reducer', 'CLEAR_ALL_HEADERS');\n return {\n ...state,\n defaultHeaderState: null,\n defaultHeaderHeight: 0,\n pages: state.pages.map(p => ({\n ...p, headerState: null, headerHeight: 0, headerSyncVersion: p.headerSyncVersion + 1,\n })),\n };\n }\n\n case 'CLEAR_ALL_FOOTERS': {\n debug('reducer', 'CLEAR_ALL_FOOTERS');\n return {\n ...state,\n defaultFooterState: null,\n defaultFooterHeight: 0,\n pages: state.pages.map(p => ({\n ...p, footerState: null, footerHeight: 0, footerSyncVersion: p.footerSyncVersion + 1,\n })),\n };\n }\n\n case 'CLEAR_DOCUMENT_CONTENT': {\n debug('reducer', 'CLEAR_DOCUMENT_CONTENT');\n const firstPage = state.pages[0];\n return {\n ...state,\n pages: [{\n ...createEmptyPage(firstPage?.id),\n headerState: firstPage?.headerState ?? null,\n footerState: firstPage?.footerState ?? null,\n headerHeight: firstPage?.headerHeight ?? 0,\n footerHeight: firstPage?.footerHeight ?? 0,\n bodySyncVersion: (firstPage?.bodySyncVersion ?? 0) + 1,\n headerSyncVersion: firstPage?.headerSyncVersion ?? 0,\n footerSyncVersion: firstPage?.footerSyncVersion ?? 0,\n }],\n };\n }\n\n case 'SET_HEADER_HEIGHT': {\n const clamped = Math.min(action.height, MAX_HEADER_HEIGHT_PX);\n debug('header', `SET_HEADER_HEIGHT id=${shortId(action.pageId)} raw=${action.height} clamped=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, headerHeight: clamped } : p,\n ),\n };\n }\n\n case 'SET_FOOTER_HEIGHT': {\n const clamped = Math.min(action.height, MAX_FOOTER_HEIGHT_PX);\n debug('footer', `SET_FOOTER_HEIGHT id=${shortId(action.pageId)} raw=${action.height} clamped=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, footerHeight: clamped } : p,\n ),\n };\n }\n\n case 'SET_DOCUMENT': {\n debug('reducer', `SET_DOCUMENT pages=${action.document.pages.length}`);\n return withExternalSyncVersions(state, action.document);\n }\n\n default:\n return state;\n }\n}\n","import type { Lex4Document } from '../types/document';\nimport type {\n CaretPosition,\n CaretSelection,\n HistoryActionDescriptor,\n HistoryEntry,\n HistoryState,\n} from '../types/history';\n\nexport const MAX_HISTORY_ACTIONS = 100;\n\nfunction cloneSnapshot(document: Lex4Document): Lex4Document {\n return structuredClone(document);\n}\n\nfunction createHistoryEntry(\n document: Lex4Document,\n descriptor: HistoryActionDescriptor,\n undoSnapshot: Lex4Document,\n caretPosition: CaretPosition | null,\n caretSelection: CaretSelection | null,\n undoCaretPosition: CaretPosition | null,\n undoCaretSelection: CaretSelection | null,\n): HistoryEntry {\n return {\n ...descriptor,\n id: crypto.randomUUID(),\n snapshot: cloneSnapshot(document),\n undoSnapshot: cloneSnapshot(undoSnapshot),\n timestamp: new Date().toISOString(),\n caretPosition,\n caretSelection,\n undoCaretPosition,\n undoCaretSelection,\n };\n}\n\nexport function createHistoryState(\n document: Lex4Document,\n baseCaretPosition: CaretPosition | null = null,\n): HistoryState {\n return {\n baseSnapshot: cloneSnapshot(document),\n baseCaretPosition,\n entries: [],\n cursor: 0,\n };\n}\n\nexport function getHistorySnapshot(history: HistoryState, cursor = history.cursor): Lex4Document {\n if (cursor <= 0) {\n return cloneSnapshot(history.baseSnapshot);\n }\n\n return cloneSnapshot(history.entries[cursor - 1].snapshot);\n}\n\nexport function clearHistoryState(\n document: Lex4Document,\n baseCaretPosition: CaretPosition | null = null,\n): HistoryState {\n return createHistoryState(document, baseCaretPosition);\n}\n\nexport function recordHistoryEntry(\n history: HistoryState,\n nextDocument: Lex4Document,\n descriptor: HistoryActionDescriptor,\n undoSnapshot: Lex4Document,\n caretPosition: CaretPosition | null,\n caretSelection: CaretSelection | null,\n undoCaretPosition: CaretPosition | null,\n undoCaretSelection: CaretSelection | null,\n): HistoryState {\n const entries = history.entries.slice(0, history.cursor);\n entries.push(createHistoryEntry(\n nextDocument,\n descriptor,\n undoSnapshot,\n caretPosition,\n caretSelection,\n undoCaretPosition,\n undoCaretSelection,\n ));\n\n let baseSnapshot = cloneSnapshot(history.baseSnapshot);\n let baseCaretPosition = history.baseCaretPosition;\n let trimmedEntries = entries;\n\n if (trimmedEntries.length > MAX_HISTORY_ACTIONS) {\n baseSnapshot = cloneSnapshot(trimmedEntries[1].undoSnapshot);\n baseCaretPosition = trimmedEntries[1].undoCaretPosition;\n trimmedEntries = trimmedEntries.slice(1);\n }\n\n return {\n baseSnapshot,\n baseCaretPosition,\n entries: trimmedEntries,\n cursor: trimmedEntries.length,\n };\n}\n\nexport function undoHistory(\n history: HistoryState,\n): {\n history: HistoryState;\n document: Lex4Document;\n caretPosition: CaretPosition | null;\n caretSelection: CaretSelection | null;\n} | null {\n if (history.cursor === 0) {\n return null;\n }\n\n const cursor = history.cursor - 1;\n const nextHistory: HistoryState = {\n ...history,\n cursor,\n };\n\n return {\n history: nextHistory,\n document: cloneSnapshot(history.entries[history.cursor - 1].undoSnapshot),\n caretPosition: history.entries[history.cursor - 1].undoCaretPosition,\n caretSelection: history.entries[history.cursor - 1].undoCaretSelection,\n };\n}\n\nexport function redoHistory(\n history: HistoryState,\n): {\n history: HistoryState;\n document: Lex4Document;\n caretPosition: CaretPosition | null;\n caretSelection: CaretSelection | null;\n} | null {\n if (history.cursor >= history.entries.length) {\n return null;\n }\n\n const cursor = history.cursor + 1;\n const nextHistory: HistoryState = {\n ...history,\n cursor,\n };\n\n return {\n history: nextHistory,\n document: getHistorySnapshot(nextHistory),\n caretPosition: nextHistory.entries[cursor - 1]?.caretPosition ?? nextHistory.baseCaretPosition,\n caretSelection: nextHistory.entries[cursor - 1]?.caretSelection ?? null,\n };\n}\n\nexport function jumpToHistoryEntry(\n history: HistoryState,\n entryIndex: number,\n): {\n history: HistoryState;\n document: Lex4Document;\n caretPosition: CaretPosition | null;\n caretSelection: CaretSelection | null;\n} | null {\n if (entryIndex < 0 || entryIndex >= history.entries.length) {\n return null;\n }\n\n const nextHistory: HistoryState = {\n ...history,\n cursor: entryIndex + 1,\n };\n\n return {\n history: nextHistory,\n document: getHistorySnapshot(nextHistory),\n caretPosition: nextHistory.entries[nextHistory.cursor - 1]?.caretPosition ?? nextHistory.baseCaretPosition,\n caretSelection: nextHistory.entries[nextHistory.cursor - 1]?.caretSelection ?? null,\n };\n}\n","import type { Lex4Translations } from './types';\n\nexport const DEFAULT_TRANSLATIONS: Lex4Translations = {\n toolbar: {\n undo: 'Undo',\n redo: 'Redo',\n bold: 'Bold (Ctrl+B)',\n italic: 'Italic (Ctrl+I)',\n underline: 'Underline (Ctrl+U)',\n strikethrough: 'Strikethrough',\n alignLeft: 'Align Left',\n alignCenter: 'Align Center',\n alignRight: 'Align Right',\n justify: 'Justify',\n numberedList: 'Numbered List',\n bulletList: 'Bullet List',\n indent: 'Indent',\n outdent: 'Outdent',\n history: 'History',\n blockType: 'Block type',\n paragraph: 'Paragraph',\n heading1: 'Heading 1',\n heading2: 'Heading 2',\n heading3: 'Heading 3',\n heading4: 'Heading 4',\n heading5: 'Heading 5',\n heading6: 'Heading 6',\n openHistory: 'Open History',\n closeHistory: 'Close History',\n },\n\n history: {\n title: 'History',\n subtitle: 'Word-style session history (last 100 actions)',\n empty: 'No history yet.',\n clearHistory: 'Clear History',\n actions: {\n enabledHeadersFooters: 'Enabled headers and footers',\n disabledHeadersFooters: 'Disabled headers and footers',\n copiedHeaderToAll: 'Copied header to all pages',\n copiedFooterToAll: 'Copied footer to all pages',\n clearedHeader: 'Cleared header',\n clearedFooter: 'Cleared footer',\n clearedAllHeaders: 'Cleared all headers',\n clearedAllFooters: 'Cleared all footers',\n pageCounterSet: 'Page counter set to {{value}}',\n boldApplied: 'Bold applied',\n italicApplied: 'Italic applied',\n underlineApplied: 'Underline applied',\n strikethroughApplied: 'Strikethrough applied',\n alignedLeft: 'Aligned left',\n alignedCenter: 'Aligned center',\n alignedRight: 'Aligned right',\n justifiedText: 'Justified text',\n insertedNumberedList: 'Inserted numbered list',\n insertedBulletList: 'Inserted bullet list',\n indentedContent: 'Indented content',\n outdentedContent: 'Outdented content',\n fontChanged: 'Font changed to {{value}}',\n fontSizeChanged: 'Font size changed to {{value}}pt',\n blockTypeChanged: 'Block type changed to {{value}}',\n insertedDocumentContent: 'Inserted document content',\n },\n },\n\n variables: {\n title: 'Variables',\n available: '{{count}} available',\n refreshVariables: 'Refresh variables',\n searchPlaceholder: 'Search variables...',\n noVariablesFound: 'No variables found',\n insertVariable: 'Insert variable {{key}}',\n openPanel: 'Open Variables',\n closePanel: 'Close Variables',\n newVariable: 'New variable',\n createVariableTitle: 'Create variable',\n createVariableLabel: 'Label',\n createVariableKey: 'Key',\n createVariableGroup: 'Group',\n createVariableType: 'Type',\n createVariableSave: 'Add variable',\n createVariableCancel: 'Cancel',\n createVariableMissingFields: 'Label and key are required.',\n createVariableDuplicateKey: 'Variable {{key}} already exists.',\n },\n\n header: {\n placeholder: 'Header',\n },\n\n footer: {\n placeholder: 'Footer',\n },\n\n body: {\n placeholder: 'Start typing...',\n },\n\n pageCounter: {\n format: 'Page {{current}} of {{total}}',\n },\n\n regions: {\n body: 'body',\n header: 'header',\n footer: 'footer',\n document: 'document',\n toolbar: 'toolbar',\n overflow: 'overflow',\n history: 'history',\n page: 'Page {{page}}',\n },\n\n headerFooter: {\n label: 'Headers & Footers',\n settingsLabel: 'Header and footer settings',\n pageCounter: 'Page counter',\n pageCounterModes: {\n none: 'None',\n header: 'Header',\n footer: 'Footer',\n both: 'Both',\n },\n headerSection: 'Header',\n footerSection: 'Footer',\n copyToAllPages: 'Copy to all pages',\n clearThisPage: 'Clear this page',\n clearAll: 'Clear all',\n },\n\n sidebar: {\n close: 'Close sidebar',\n },\n\n historyLabels: {\n typedText: 'Typed text',\n pastedContent: 'Pasted content',\n insertedLineBreak: 'Inserted line break',\n deletedBackward: 'Deleted backward',\n deletedForward: 'Deleted forward',\n formattedText: 'Formatted text',\n formattedParagraph: 'Formatted paragraph',\n editedBody: 'Edited body',\n editedHeader: 'Edited header',\n editedFooter: 'Edited footer',\n clearedDocumentBody: 'Cleared document body',\n resizedHeader: 'Resized header',\n resizedFooter: 'Resized footer',\n addedPage: 'Added page',\n removedPage: 'Removed page',\n documentReflow: 'Document reflow',\n updatedDocument: 'Updated document',\n },\n};\n","import type { Lex4Translations } from './types';\n\nexport const PT_BR_TRANSLATIONS: Lex4Translations = {\n toolbar: {\n undo: 'Desfazer',\n redo: 'Refazer',\n bold: 'Negrito (Ctrl+B)',\n italic: 'Itálico (Ctrl+I)',\n underline: 'Sublinhado (Ctrl+U)',\n strikethrough: 'Tachado',\n alignLeft: 'Alinhar à Esquerda',\n alignCenter: 'Centralizar',\n alignRight: 'Alinhar à Direita',\n justify: 'Justificar',\n numberedList: 'Lista Numerada',\n bulletList: 'Lista com Marcadores',\n indent: 'Aumentar Recuo',\n outdent: 'Diminuir Recuo',\n history: 'Histórico',\n blockType: 'Tipo de bloco',\n paragraph: 'Parágrafo',\n heading1: 'Título 1',\n heading2: 'Título 2',\n heading3: 'Título 3',\n heading4: 'Título 4',\n heading5: 'Título 5',\n heading6: 'Título 6',\n openHistory: 'Abrir Histórico',\n closeHistory: 'Fechar Histórico',\n },\n\n history: {\n title: 'Histórico',\n subtitle: 'Histórico de sessão (últimas 100 ações)',\n empty: 'Nenhum histórico ainda.',\n clearHistory: 'Limpar Histórico',\n actions: {\n enabledHeadersFooters: 'Cabeçalhos e rodapés ativados',\n disabledHeadersFooters: 'Cabeçalhos e rodapés desativados',\n copiedHeaderToAll: 'Cabeçalho copiado para todas as páginas',\n copiedFooterToAll: 'Rodapé copiado para todas as páginas',\n clearedHeader: 'Cabeçalho limpo',\n clearedFooter: 'Rodapé limpo',\n clearedAllHeaders: 'Todos os cabeçalhos limpos',\n clearedAllFooters: 'Todos os rodapés limpos',\n pageCounterSet: 'Contador de páginas definido como {{value}}',\n boldApplied: 'Negrito aplicado',\n italicApplied: 'Itálico aplicado',\n underlineApplied: 'Sublinhado aplicado',\n strikethroughApplied: 'Tachado aplicado',\n alignedLeft: 'Alinhado à esquerda',\n alignedCenter: 'Centralizado',\n alignedRight: 'Alinhado à direita',\n justifiedText: 'Texto justificado',\n insertedNumberedList: 'Lista numerada inserida',\n insertedBulletList: 'Lista com marcadores inserida',\n indentedContent: 'Conteúdo recuado',\n outdentedContent: 'Recuo reduzido',\n fontChanged: 'Fonte alterada para {{value}}',\n fontSizeChanged: 'Tamanho da fonte alterado para {{value}}pt',\n blockTypeChanged: 'Tipo de bloco alterado para {{value}}',\n insertedDocumentContent: 'Conteúdo do documento inserido',\n },\n },\n\n variables: {\n title: 'Variáveis',\n available: '{{count}} disponíveis',\n refreshVariables: 'Atualizar variáveis',\n searchPlaceholder: 'Buscar variáveis...',\n noVariablesFound: 'Nenhuma variável encontrada',\n insertVariable: 'Inserir variável {{key}}',\n openPanel: 'Abrir Variáveis',\n closePanel: 'Fechar Variáveis',\n newVariable: 'Nova variável',\n createVariableTitle: 'Criar variável',\n createVariableLabel: 'Rótulo',\n createVariableKey: 'Chave',\n createVariableGroup: 'Grupo',\n createVariableType: 'Tipo',\n createVariableSave: 'Adicionar variável',\n createVariableCancel: 'Cancelar',\n createVariableMissingFields: 'Rótulo e chave são obrigatórios.',\n createVariableDuplicateKey: 'A variável {{key}} já existe.',\n },\n\n header: {\n placeholder: 'Cabeçalho',\n },\n\n footer: {\n placeholder: 'Rodapé',\n },\n\n body: {\n placeholder: 'Comece a digitar...',\n },\n\n pageCounter: {\n format: 'Página {{current}} de {{total}}',\n },\n\n regions: {\n body: 'corpo',\n header: 'cabeçalho',\n footer: 'rodapé',\n document: 'documento',\n toolbar: 'barra de ferramentas',\n overflow: 'estouro',\n history: 'histórico',\n page: 'Página {{page}}',\n },\n\n headerFooter: {\n label: 'Cabeçalhos e Rodapés',\n settingsLabel: 'Configurações de cabeçalho e rodapé',\n pageCounter: 'Contador de páginas',\n pageCounterModes: {\n none: 'Nenhum',\n header: 'Cabeçalho',\n footer: 'Rodapé',\n both: 'Ambos',\n },\n headerSection: 'Cabeçalho',\n footerSection: 'Rodapé',\n copyToAllPages: 'Copiar para todas as páginas',\n clearThisPage: 'Limpar esta página',\n clearAll: 'Limpar tudo',\n },\n\n sidebar: {\n close: 'Fechar barra lateral',\n },\n\n historyLabels: {\n typedText: 'Texto digitado',\n pastedContent: 'Conteúdo colado',\n insertedLineBreak: 'Quebra de linha inserida',\n deletedBackward: 'Exclusão para trás',\n deletedForward: 'Exclusão para frente',\n formattedText: 'Texto formatado',\n formattedParagraph: 'Parágrafo formatado',\n editedBody: 'Corpo editado',\n editedHeader: 'Cabeçalho editado',\n editedFooter: 'Rodapé editado',\n clearedDocumentBody: 'Corpo do documento limpo',\n resizedHeader: 'Cabeçalho redimensionado',\n resizedFooter: 'Rodapé redimensionado',\n addedPage: 'Página adicionada',\n removedPage: 'Página removida',\n documentReflow: 'Redistribuição do documento',\n updatedDocument: 'Documento atualizado',\n },\n};\n","import React, { createContext, useContext, useMemo } from 'react';\nimport type { Lex4Translations } from './types';\nimport { DEFAULT_TRANSLATIONS } from './defaults';\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\nfunction deepMerge<T>(\n target: T,\n source: DeepPartial<T>,\n): T {\n if (typeof target !== 'object' || target === null) {\n return (source ?? target) as T;\n }\n const result = { ...target } as Record<string, unknown>;\n for (const key of Object.keys(source as Record<string, unknown>)) {\n const sourceVal = (source as Record<string, unknown>)[key];\n const targetVal = (target as Record<string, unknown>)[key];\n if (\n sourceVal !== undefined &&\n typeof sourceVal === 'object' &&\n sourceVal !== null &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === 'object' &&\n targetVal !== null\n ) {\n result[key] = deepMerge(targetVal, sourceVal as DeepPartial<typeof targetVal>);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n return result as T;\n}\n\nconst TranslationsContext = createContext<Lex4Translations>(DEFAULT_TRANSLATIONS);\n\n/**\n * Returns the active translations. Use inside any editor component\n * to access localized strings.\n */\nexport function useTranslations(): Lex4Translations {\n return useContext(TranslationsContext);\n}\n\n/**\n * Interpolates `{{key}}` placeholders in a translation string.\n *\n * @example\n * interpolate('Font changed to {{value}}', { value: 'Inter' })\n * // => 'Font changed to Inter'\n */\nexport function interpolate(\n template: string,\n params: Record<string, string | number>,\n): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) =>\n String(params[key] ?? `{{${key}}}`),\n );\n}\n\ninterface TranslationsProviderProps {\n translations?: DeepPartial<Lex4Translations>;\n children: React.ReactNode;\n}\n\n/**\n * TranslationsProvider — merges consumer overrides with DEFAULT_TRANSLATIONS.\n */\nexport const TranslationsProvider: React.FC<TranslationsProviderProps> = ({\n translations,\n children,\n}) => {\n const merged = useMemo(\n () =>\n translations\n ? deepMerge(DEFAULT_TRANSLATIONS, translations)\n : DEFAULT_TRANSLATIONS,\n [translations],\n );\n\n return (\n <TranslationsContext.Provider value={merged}>\n {children}\n </TranslationsContext.Provider>\n );\n};\n","import React, { useReducer, useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport type { Lex4Document } from '../types/document';\nimport type {\n CaretPosition,\n CaretSelection,\n HistoryActionDescriptor,\n HistoryState,\n} from '../types/history';\nimport { $createRangeSelectionFromDom, $getRoot, $getSelection, $isRangeSelection } from 'lexical';\nimport type { LexicalEditor } from 'lexical';\nimport { createEmptyDocument } from '../types/document';\nimport { DocumentContext, type DocumentAction, type EditorRegistry } from './document-context';\nimport { documentReducer } from './document-reducer';\nimport {\n clearHistoryState,\n createHistoryState,\n jumpToHistoryEntry,\n recordHistoryEntry,\n redoHistory,\n undoHistory,\n} from '../utils/history-manager';\nimport { useTranslations, interpolate } from '../i18n';\nimport type { Lex4Translations } from '../i18n/types';\n\ninterface DocumentProviderProps {\n initialDocument?: Lex4Document;\n onDocumentChange?: (doc: Lex4Document) => void;\n children: React.ReactNode;\n}\n\nconst HISTORY_RESTORE_SUPPRESSION_MS = 100;\nconst HISTORY_BATCH_FLUSH_MS = 16;\n\nfunction cloneDocumentSnapshot(document: Lex4Document): Lex4Document {\n return structuredClone(document);\n}\n\nfunction captureUndoSnapshot(\n document: Lex4Document,\n activeEditor: LexicalEditor | null,\n caretPosition: CaretPosition | null,\n): Lex4Document {\n const snapshot = cloneDocumentSnapshot(document);\n if (!activeEditor || !caretPosition) {\n return snapshot;\n }\n\n const page = snapshot.pages.find(candidate => candidate.id === caretPosition.pageId);\n if (!page) {\n return snapshot;\n }\n\n const editorState = activeEditor.getEditorState().toJSON();\n if (caretPosition.region === 'body') {\n page.bodyState = editorState;\n } else if (caretPosition.region === 'header') {\n page.headerState = editorState;\n } else {\n page.footerState = editorState;\n }\n\n return snapshot;\n}\n\nfunction captureCaretSelection(editor: LexicalEditor | null): CaretSelection | null {\n if (!editor) {\n return null;\n }\n\n const rootElement = editor.getRootElement();\n const domSelection = window.getSelection();\n const selectionInRoot = (node: Node | null) =>\n !!node && !!rootElement && (node === rootElement || rootElement.contains(node));\n const getTextOffset = (node: Node, offset: number) => {\n if (!rootElement) {\n return 0;\n }\n\n const range = document.createRange();\n range.setStart(rootElement, 0);\n range.setEnd(node, offset);\n return range.toString().length;\n };\n\n let caretSelection: CaretSelection | null = null;\n editor.getEditorState().read(() => {\n const selection = $createRangeSelectionFromDom(window.getSelection(), editor) ?? $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n caretSelection = {\n anchor: {\n key: selection.anchor.key,\n offset: selection.anchor.offset,\n type: selection.anchor.type,\n },\n focus: {\n key: selection.focus.key,\n offset: selection.focus.offset,\n type: selection.focus.type,\n },\n anchorTextOffset:\n domSelection && selectionInRoot(domSelection.anchorNode)\n ? getTextOffset(domSelection.anchorNode!, domSelection.anchorOffset)\n : 0,\n focusTextOffset:\n domSelection && selectionInRoot(domSelection.focusNode)\n ? getTextOffset(domSelection.focusNode!, domSelection.focusOffset)\n : 0,\n format: selection.format,\n style: selection.style,\n };\n });\n\n return caretSelection;\n}\n\nfunction getPageNumber(document: Lex4Document, pageId?: string): number | null {\n if (!pageId) {\n return null;\n }\n\n const index = document.pages.findIndex(page => page.id === pageId);\n return index >= 0 ? index + 1 : null;\n}\n\nfunction describeAction(\n action: DocumentAction,\n document: Lex4Document,\n t: Lex4Translations,\n): HistoryActionDescriptor {\n const pageSuffix = (pageId: string) => {\n const num = getPageNumber(document, pageId);\n return num ? ` - ${interpolate(t.regions.page, { page: num })}` : '';\n };\n\n switch (action.type) {\n case 'UPDATE_PAGE_BODY': {\n return {\n label: t.historyLabels.editedBody + pageSuffix(action.pageId),\n source: 'body',\n pageId: action.pageId,\n region: 'body',\n };\n }\n case 'UPDATE_PAGE_HEADER':\n case 'UPDATE_PAGE_HEADER_CONTENT': {\n return {\n label: t.historyLabels.editedHeader + pageSuffix(action.pageId),\n source: 'header',\n pageId: action.pageId,\n region: 'header',\n };\n }\n case 'UPDATE_PAGE_FOOTER':\n case 'UPDATE_PAGE_FOOTER_CONTENT': {\n return {\n label: t.historyLabels.editedFooter + pageSuffix(action.pageId),\n source: 'footer',\n pageId: action.pageId,\n region: 'footer',\n };\n }\n case 'SET_HEADER_FOOTER_ENABLED':\n return {\n label: action.enabled\n ? t.history.actions.enabledHeadersFooters\n : t.history.actions.disabledHeadersFooters,\n source: 'document',\n region: 'document',\n };\n case 'SET_PAGE_COUNTER_MODE':\n return {\n label: interpolate(t.history.actions.pageCounterSet, { value: action.mode }),\n source: 'document',\n region: 'document',\n };\n case 'COPY_HEADER_TO_ALL':\n return {\n label: t.history.actions.copiedHeaderToAll,\n source: 'toolbar',\n pageId: action.sourcePageId,\n region: 'header',\n };\n case 'COPY_FOOTER_TO_ALL':\n return {\n label: t.history.actions.copiedFooterToAll,\n source: 'toolbar',\n pageId: action.sourcePageId,\n region: 'footer',\n };\n case 'CLEAR_HEADER': {\n return {\n label: t.history.actions.clearedHeader + pageSuffix(action.pageId),\n source: 'toolbar',\n pageId: action.pageId,\n region: 'header',\n };\n }\n case 'CLEAR_FOOTER': {\n return {\n label: t.history.actions.clearedFooter + pageSuffix(action.pageId),\n source: 'toolbar',\n pageId: action.pageId,\n region: 'footer',\n };\n }\n case 'CLEAR_ALL_HEADERS':\n return {\n label: t.history.actions.clearedAllHeaders,\n source: 'toolbar',\n region: 'header',\n };\n case 'CLEAR_ALL_FOOTERS':\n return {\n label: t.history.actions.clearedAllFooters,\n source: 'toolbar',\n region: 'footer',\n };\n case 'CLEAR_DOCUMENT_CONTENT':\n return {\n label: t.historyLabels.clearedDocumentBody,\n source: 'document',\n region: 'document',\n };\n case 'SET_HEADER_HEIGHT': {\n return {\n label: t.historyLabels.resizedHeader + pageSuffix(action.pageId),\n source: 'header',\n pageId: action.pageId,\n region: 'header',\n };\n }\n case 'SET_FOOTER_HEIGHT': {\n return {\n label: t.historyLabels.resizedFooter + pageSuffix(action.pageId),\n source: 'footer',\n pageId: action.pageId,\n region: 'footer',\n };\n }\n case 'ADD_PAGE':\n return {\n label: t.historyLabels.addedPage,\n source: 'overflow',\n region: 'document',\n };\n case 'REMOVE_PAGE':\n return {\n label: t.historyLabels.removedPage,\n source: 'overflow',\n region: 'document',\n };\n case 'SET_DOCUMENT':\n return {\n label: t.historyLabels.documentReflow,\n source: 'overflow',\n region: 'document',\n };\n default:\n return {\n label: t.historyLabels.updatedDocument,\n source: 'document',\n region: 'document',\n };\n }\n}\n\nfunction documentsAreEqual(current: Lex4Document, next: Lex4Document): boolean {\n return JSON.stringify(current) === JSON.stringify(next);\n}\n\nexport const DocumentProvider: React.FC<DocumentProviderProps> = ({\n initialDocument,\n onDocumentChange,\n children,\n}) => {\n const initialSnapshot = initialDocument ?? createEmptyDocument();\n const [document, baseDispatch] = useReducer(documentReducer, initialSnapshot);\n const [historyState, setHistoryState] = useState<HistoryState>(() => createHistoryState(initialSnapshot));\n const documentRef = useRef(document);\n const historyStateRef = useRef(historyState);\n const [activePageId, setActivePageIdRaw] = useState<string | null>(\n initialSnapshot.pages[0]?.id ?? null,\n );\n const activePageIdRef = useRef<string | null>(initialSnapshot.pages[0]?.id ?? null);\n const [globalSelectionActive, setGlobalSelectionActive] = useState(false);\n const [historySidebarOpen, setHistorySidebarOpen] = useState(false);\n const [focusAtEndVersion, setFocusAtEndVersion] = useState(0);\n const t = useTranslations();\n const activeEditorRef = useRef<LexicalEditor | null>(null);\n const activeCaretPositionRef = useRef<CaretPosition | null>(null);\n const pendingCaretPositionRef = useRef<CaretPosition | null>(null);\n const pendingCaretSelectionRef = useRef<CaretSelection | null>(null);\n const pendingFocusAtEndRef = useRef<CaretPosition | null>(null);\n const [, forceUpdate] = useState(0);\n const historySuppressedRef = useRef(false);\n const historyReleaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const historyFlushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingHistoryActionRef = useRef<HistoryActionDescriptor | null>(null);\n const pendingUndoSnapshotRef = useRef<Lex4Document | null>(null);\n const pendingUndoCaretPositionRef = useRef<CaretPosition | null>(null);\n const pendingUndoCaretSelectionRef = useRef<CaretSelection | null>(null);\n const historyBatchRef = useRef<{\n descriptor: HistoryActionDescriptor;\n nextDocument: Lex4Document | null;\n undoSnapshot: Lex4Document | null;\n undoCaretPosition: CaretPosition | null;\n undoCaretSelection: CaretSelection | null;\n hasMutation: boolean;\n } | null>(null);\n\n const editorMapRef = useRef(new Map<string, LexicalEditor>());\n const editorRegistry: EditorRegistry = useMemo(() => ({\n register: (pageId: string, editor: LexicalEditor) => {\n editorMapRef.current.set(pageId, editor);\n },\n unregister: (pageId: string, editor?: LexicalEditor) => {\n const currentEditor = editorMapRef.current.get(pageId);\n if (editor && currentEditor && currentEditor !== editor) {\n return;\n }\n\n editorMapRef.current.delete(pageId);\n },\n get: (pageId: string) => editorMapRef.current.get(pageId),\n all: () => Array.from(editorMapRef.current.values()),\n }), []);\n\n const setActivePageId = useCallback((id: string | null) => {\n activePageIdRef.current = id;\n setActivePageIdRaw(id);\n }, []);\n\n const setActiveEditor = useCallback((\n editor: LexicalEditor | null,\n caretPosition: CaretPosition | null = null,\n ) => {\n activeEditorRef.current = editor;\n activeCaretPositionRef.current = caretPosition;\n forceUpdate(n => n + 1);\n }, []);\n\n const focusEditorAtEnd = useCallback((editor: LexicalEditor, caretPosition: CaretPosition) => {\n requestAnimationFrame(() => {\n setActivePageId(caretPosition.pageId);\n setActiveEditor(editor, caretPosition);\n editor.focus(() => {\n editor.update(() => {\n $getRoot().selectEnd();\n });\n });\n });\n }, [setActiveEditor, setActivePageId]);\n\n const consumePendingCaretPosition = useCallback((caretPosition: CaretPosition) => {\n const pendingCaretPosition = pendingCaretPositionRef.current;\n if (\n !pendingCaretPosition\n || pendingCaretPosition.pageId !== caretPosition.pageId\n || pendingCaretPosition.region !== caretPosition.region\n ) {\n return undefined;\n }\n\n pendingCaretPositionRef.current = null;\n const pendingCaretSelection = pendingCaretSelectionRef.current;\n pendingCaretSelectionRef.current = null;\n return pendingCaretSelection;\n }, []);\n\n const consumePendingFocusAtEnd = useCallback((caretPosition: CaretPosition) => {\n const pendingFocusAtEnd = pendingFocusAtEndRef.current;\n if (\n !pendingFocusAtEnd\n || pendingFocusAtEnd.pageId !== caretPosition.pageId\n || pendingFocusAtEnd.region !== caretPosition.region\n ) {\n return false;\n }\n\n pendingFocusAtEndRef.current = null;\n return true;\n }, []);\n\n const requestFocusAtEnd = useCallback((caretPosition: CaretPosition) => {\n pendingCaretPositionRef.current = null;\n pendingCaretSelectionRef.current = null;\n\n if (caretPosition.region === 'body') {\n const editor = editorRegistry.get(caretPosition.pageId);\n if (editor) {\n pendingFocusAtEndRef.current = null;\n focusEditorAtEnd(editor, caretPosition);\n return;\n }\n }\n\n pendingFocusAtEndRef.current = caretPosition;\n setFocusAtEndVersion(version => version + 1);\n }, [editorRegistry, focusEditorAtEnd]);\n\n const flushHistoryBatch = useCallback(() => {\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n historyFlushTimerRef.current = null;\n }\n\n const batch = historyBatchRef.current;\n historyBatchRef.current = null;\n pendingHistoryActionRef.current = null;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n\n if (!batch || historySuppressedRef.current || !batch.hasMutation || !batch.nextDocument) {\n return;\n }\n\n const undoSnapshot = batch.undoSnapshot ?? batch.nextDocument;\n\n setHistoryState(previousHistory => {\n const nextHistory = recordHistoryEntry(\n previousHistory,\n batch.nextDocument as Lex4Document,\n batch.descriptor,\n undoSnapshot,\n activeCaretPositionRef.current,\n captureCaretSelection(activeEditorRef.current),\n batch.undoCaretPosition,\n batch.undoCaretSelection,\n );\n historyStateRef.current = nextHistory;\n return nextHistory;\n });\n }, []);\n\n const scheduleHistoryBatchFlush = useCallback(() => {\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n }\n\n historyFlushTimerRef.current = setTimeout(() => {\n flushHistoryBatch();\n }, HISTORY_BATCH_FLUSH_MS);\n }, [flushHistoryBatch]);\n\n const queueHistoryAction = useCallback((action: HistoryActionDescriptor | null) => {\n pendingHistoryActionRef.current = action;\n pendingUndoSnapshotRef.current = action\n ? captureUndoSnapshot(\n documentRef.current,\n activeEditorRef.current,\n activeCaretPositionRef.current,\n )\n : null;\n pendingUndoCaretPositionRef.current = action ? activeCaretPositionRef.current : null;\n pendingUndoCaretSelectionRef.current = action ? captureCaretSelection(activeEditorRef.current) : null;\n }, []);\n\n const runHistoryAction = useCallback((action: HistoryActionDescriptor, callback: () => void) => {\n if (historyBatchRef.current) {\n callback();\n return;\n }\n\n historyBatchRef.current = {\n descriptor: action,\n nextDocument: null,\n undoSnapshot: captureUndoSnapshot(\n documentRef.current,\n activeEditorRef.current,\n activeCaretPositionRef.current,\n ),\n undoCaretPosition: activeCaretPositionRef.current,\n undoCaretSelection: captureCaretSelection(activeEditorRef.current),\n hasMutation: false,\n };\n\n pendingHistoryActionRef.current = action;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n\n try {\n callback();\n } finally {\n scheduleHistoryBatchFlush();\n }\n }, [scheduleHistoryBatchFlush]);\n\n const suppressHistoryTemporarily = useCallback(() => {\n historySuppressedRef.current = true;\n pendingHistoryActionRef.current = null;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n historyBatchRef.current = null;\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n historyFlushTimerRef.current = null;\n }\n if (historyReleaseTimerRef.current) {\n clearTimeout(historyReleaseTimerRef.current);\n }\n historyReleaseTimerRef.current = setTimeout(() => {\n historySuppressedRef.current = false;\n historyReleaseTimerRef.current = null;\n }, HISTORY_RESTORE_SUPPRESSION_MS);\n }, []);\n\n const dispatch = useCallback((action: DocumentAction) => {\n const currentDocument = documentRef.current;\n const nextDocument = documentReducer(currentDocument, action);\n const changed = !documentsAreEqual(currentDocument, nextDocument);\n const suppressPassiveBodyHistory =\n action.type === 'UPDATE_PAGE_BODY'\n && action.pageId !== activePageIdRef.current\n && !historyBatchRef.current\n && !pendingHistoryActionRef.current;\n\n documentRef.current = nextDocument;\n\n if (changed && !historySuppressedRef.current && !suppressPassiveBodyHistory) {\n if (historyBatchRef.current) {\n historyBatchRef.current.nextDocument = cloneDocumentSnapshot(nextDocument);\n historyBatchRef.current.hasMutation = true;\n scheduleHistoryBatchFlush();\n } else if (pendingHistoryActionRef.current) {\n historyBatchRef.current = {\n descriptor: pendingHistoryActionRef.current,\n nextDocument: cloneDocumentSnapshot(nextDocument),\n undoSnapshot: pendingUndoSnapshotRef.current,\n undoCaretPosition: pendingUndoCaretPositionRef.current,\n undoCaretSelection: pendingUndoCaretSelectionRef.current,\n hasMutation: true,\n };\n scheduleHistoryBatchFlush();\n } else {\n const descriptor = describeAction(action, currentDocument, t);\n setHistoryState(previousHistory => {\n const nextHistory = recordHistoryEntry(\n previousHistory,\n nextDocument,\n descriptor,\n captureUndoSnapshot(\n currentDocument,\n activeEditorRef.current,\n activeCaretPositionRef.current,\n ),\n activeCaretPositionRef.current,\n captureCaretSelection(activeEditorRef.current),\n activeCaretPositionRef.current,\n captureCaretSelection(activeEditorRef.current),\n );\n historyStateRef.current = nextHistory;\n return nextHistory;\n });\n }\n } else {\n pendingHistoryActionRef.current = null;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n }\n\n baseDispatch(action);\n }, [scheduleHistoryBatchFlush]);\n\n const restoreDocument = useCallback((\n snapshot: Lex4Document,\n caretPosition: CaretPosition | null,\n caretSelection: CaretSelection | null,\n ) => {\n suppressHistoryTemporarily();\n pendingCaretPositionRef.current = caretPosition;\n pendingCaretSelectionRef.current = caretSelection;\n activeEditorRef.current = null;\n activeCaretPositionRef.current = caretPosition;\n forceUpdate(n => n + 1);\n documentRef.current = cloneDocumentSnapshot(snapshot);\n baseDispatch({ type: 'SET_DOCUMENT', document: cloneDocumentSnapshot(snapshot) });\n }, [suppressHistoryTemporarily]);\n\n const undo = useCallback(() => {\n flushHistoryBatch();\n const result = undoHistory(historyStateRef.current);\n if (!result) {\n return;\n }\n\n historyStateRef.current = result.history;\n setHistoryState(result.history);\n restoreDocument(result.document, result.caretPosition, result.caretSelection);\n }, [flushHistoryBatch, restoreDocument]);\n\n const redo = useCallback(() => {\n flushHistoryBatch();\n const result = redoHistory(historyStateRef.current);\n if (!result) {\n return;\n }\n\n historyStateRef.current = result.history;\n setHistoryState(result.history);\n restoreDocument(result.document, result.caretPosition, result.caretSelection);\n }, [flushHistoryBatch, restoreDocument]);\n\n const clearHistory = useCallback(() => {\n flushHistoryBatch();\n const nextHistory = clearHistoryState(documentRef.current, activeCaretPositionRef.current);\n historyStateRef.current = nextHistory;\n setHistoryState(nextHistory);\n }, [flushHistoryBatch]);\n\n const handleJumpToHistoryEntry = useCallback((entryIndex: number) => {\n flushHistoryBatch();\n const result = jumpToHistoryEntry(historyStateRef.current, entryIndex);\n if (!result) {\n return;\n }\n\n historyStateRef.current = result.history;\n setHistoryState(result.history);\n restoreDocument(result.document, result.caretPosition, result.caretSelection);\n }, [flushHistoryBatch, restoreDocument]);\n\n useEffect(() => {\n documentRef.current = document;\n onDocumentChange?.(document);\n }, [document, onDocumentChange]);\n\n useEffect(() => {\n historyStateRef.current = historyState;\n }, [historyState]);\n\n useEffect(() => {\n const firstPageId = document.pages[0]?.id ?? null;\n const activePageStillExists = activePageId !== null\n && document.pages.some(page => page.id === activePageId);\n\n if (!activePageStillExists) {\n activePageIdRef.current = firstPageId;\n setActivePageIdRaw(firstPageId);\n activeEditorRef.current = null;\n activeCaretPositionRef.current = null;\n forceUpdate(n => n + 1);\n }\n }, [activePageId, document.pages]);\n\n useEffect(\n () => () => {\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n }\n if (historyReleaseTimerRef.current) {\n clearTimeout(historyReleaseTimerRef.current);\n }\n },\n [],\n );\n\n return (\n <DocumentContext.Provider value={{\n document,\n dispatch,\n activePageId,\n setActivePageId,\n activeEditor: activeEditorRef.current,\n activeCaretPosition: activeCaretPositionRef.current,\n consumePendingCaretPosition,\n consumePendingFocusAtEnd,\n requestFocusAtEnd,\n focusAtEndVersion,\n setActiveEditor,\n globalSelectionActive,\n setGlobalSelectionActive,\n historyEntries: historyState.entries,\n historyCursor: historyState.cursor,\n canUndo: historyState.cursor > 0,\n canRedo: historyState.cursor < historyState.entries.length,\n queueHistoryAction,\n runHistoryAction,\n jumpToHistoryEntry: handleJumpToHistoryEntry,\n clearHistory,\n historySidebarOpen,\n setHistorySidebarOpen,\n undo,\n redo,\n editorRegistry,\n }}>\n {children}\n </DocumentContext.Provider>\n );\n};\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.js';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.js.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.js.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.js';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.js';\nimport { useLucideContext } from './context.js';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.js';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.js';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m15 16 2.536-7.328a1.02 1.02 1 0 1 1.928 0L22 16\", key: \"xik6mr\" }],\n [\"path\", { d: \"M15.697 14h5.606\", key: \"1stdlc\" }],\n [\"path\", { d: \"m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16\", key: \"d5nyq2\" }],\n [\"path\", { d: \"M3.304 13h6.392\", key: \"1q3zxz\" }]\n];\nconst ALargeSmall = createLucideIcon(\"a-large-small\", __iconNode);\n\nexport { __iconNode, ALargeSmall as default };\n//# sourceMappingURL=a-large-small.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\", key: \"mg9rjx\" }\n ]\n];\nconst Bold = createLucideIcon(\"bold\", __iconNode);\n\nexport { __iconNode, Bold as default };\n//# sourceMappingURL=bold.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1\", key: \"ezmyqa\" }\n ],\n [\n \"path\",\n {\n d: \"M16 21h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1\",\n key: \"e1hn23\"\n }\n ]\n];\nconst Braces = createLucideIcon(\"braces\", __iconNode);\n\nexport { __iconNode, Braces as default };\n//# sourceMappingURL=braces.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]];\nconst Check = createLucideIcon(\"check\", __iconNode);\n\nexport { __iconNode, Check as default };\n//# sourceMappingURL=check.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"15\", x2: \"15\", y1: \"12\", y2: \"18\", key: \"1p7wdc\" }],\n [\"line\", { x1: \"12\", x2: \"18\", y1: \"15\", y2: \"15\", key: \"1nscbv\" }],\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n];\nconst CopyPlus = createLucideIcon(\"copy-plus\", __iconNode);\n\nexport { __iconNode, CopyPlus as default };\n//# sourceMappingURL=copy-plus.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21\",\n key: \"g5wo59\"\n }\n ],\n [\"path\", { d: \"m5.082 11.09 8.828 8.828\", key: \"1wx5vj\" }]\n];\nconst Eraser = createLucideIcon(\"eraser\", __iconNode);\n\nexport { __iconNode, Eraser as default };\n//# sourceMappingURL=eraser.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M10 9H8\", key: \"b1mrlr\" }],\n [\"path\", { d: \"M16 13H8\", key: \"t4e002\" }],\n [\"path\", { d: \"M16 17H8\", key: \"z1uh3a\" }]\n];\nconst FileText = createLucideIcon(\"file-text\", __iconNode);\n\nexport { __iconNode, FileText as default };\n//# sourceMappingURL=file-text.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }],\n [\"path\", { d: \"M12 7v5l4 2\", key: \"1fdv2h\" }]\n];\nconst History = createLucideIcon(\"history\", __iconNode);\n\nexport { __iconNode, History as default };\n//# sourceMappingURL=history.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n];\nconst Italic = createLucideIcon(\"italic\", __iconNode);\n\nexport { __iconNode, Italic as default };\n//# sourceMappingURL=italic.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H11\", key: \"us1j55\" }],\n [\"path\", { d: \"M21 12H11\", key: \"wd7e0v\" }],\n [\"path\", { d: \"M21 19H11\", key: \"saa85w\" }],\n [\"path\", { d: \"m7 8-4 4 4 4\", key: \"o5hrat\" }]\n];\nconst ListIndentDecrease = createLucideIcon(\"list-indent-decrease\", __iconNode);\n\nexport { __iconNode, ListIndentDecrease as default };\n//# sourceMappingURL=list-indent-decrease.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H11\", key: \"us1j55\" }],\n [\"path\", { d: \"M21 12H11\", key: \"wd7e0v\" }],\n [\"path\", { d: \"M21 19H11\", key: \"saa85w\" }],\n [\"path\", { d: \"m3 8 4 4-4 4\", key: \"1a3j6y\" }]\n];\nconst ListIndentIncrease = createLucideIcon(\"list-indent-increase\", __iconNode);\n\nexport { __iconNode, ListIndentIncrease as default };\n//# sourceMappingURL=list-indent-increase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M11 5h10\", key: \"1cz7ny\" }],\n [\"path\", { d: \"M11 12h10\", key: \"1438ji\" }],\n [\"path\", { d: \"M11 19h10\", key: \"11t30w\" }],\n [\"path\", { d: \"M4 4h1v5\", key: \"10yrso\" }],\n [\"path\", { d: \"M4 9h2\", key: \"r1h2o0\" }],\n [\"path\", { d: \"M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02\", key: \"xtkcd5\" }]\n];\nconst ListOrdered = createLucideIcon(\"list-ordered\", __iconNode);\n\nexport { __iconNode, ListOrdered as default };\n//# sourceMappingURL=list-ordered.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 5h.01\", key: \"18ugdj\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M3 19h.01\", key: \"noohij\" }],\n [\"path\", { d: \"M8 5h13\", key: \"1pao27\" }],\n [\"path\", { d: \"M8 12h13\", key: \"1za7za\" }],\n [\"path\", { d: \"M8 19h13\", key: \"m83p4d\" }]\n];\nconst List = createLucideIcon(\"list\", __iconNode);\n\nexport { __iconNode, List as default };\n//# sourceMappingURL=list.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m15 14 5-5-5-5\", key: \"12vg1m\" }],\n [\"path\", { d: \"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13\", key: \"6uklza\" }]\n];\nconst Redo2 = createLucideIcon(\"redo-2\", __iconNode);\n\nexport { __iconNode, Redo2 as default };\n//# sourceMappingURL=redo-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\", key: \"v9h5vc\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }],\n [\"path\", { d: \"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\", key: \"3uifl3\" }],\n [\"path\", { d: \"M8 16H3v5\", key: \"1cv678\" }]\n];\nconst RefreshCw = createLucideIcon(\"refresh-cw\", __iconNode);\n\nexport { __iconNode, RefreshCw as default };\n//# sourceMappingURL=refresh-cw.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M14 17H5\", key: \"gfn3mx\" }],\n [\"path\", { d: \"M19 7h-9\", key: \"6i9tg\" }],\n [\"circle\", { cx: \"17\", cy: \"17\", r: \"3\", key: \"18b49y\" }],\n [\"circle\", { cx: \"7\", cy: \"7\", r: \"3\", key: \"dfmy0x\" }]\n];\nconst Settings2 = createLucideIcon(\"settings-2\", __iconNode);\n\nexport { __iconNode, Settings2 as default };\n//# sourceMappingURL=settings-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 4H9a3 3 0 0 0-2.83 4\", key: \"43sutm\" }],\n [\"path\", { d: \"M14 12a4 4 0 0 1 0 8H6\", key: \"nlfj13\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"12\", y2: \"12\", key: \"1e0a9i\" }]\n];\nconst Strikethrough = createLucideIcon(\"strikethrough\", __iconNode);\n\nexport { __iconNode, Strikethrough as default };\n//# sourceMappingURL=strikethrough.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }],\n [\"path\", { d: \"M19 19H5\", key: \"vjpgq2\" }]\n];\nconst TextAlignCenter = createLucideIcon(\"text-align-center\", __iconNode);\n\nexport { __iconNode, TextAlignCenter as default };\n//# sourceMappingURL=text-align-center.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M21 19H7\", key: \"4cu937\" }]\n];\nconst TextAlignEnd = createLucideIcon(\"text-align-end\", __iconNode);\n\nexport { __iconNode, TextAlignEnd as default };\n//# sourceMappingURL=text-align-end.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 5h18\", key: \"1u36vt\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }],\n [\"path\", { d: \"M3 19h18\", key: \"awlh7x\" }]\n];\nconst TextAlignJustify = createLucideIcon(\"text-align-justify\", __iconNode);\n\nexport { __iconNode, TextAlignJustify as default };\n//# sourceMappingURL=text-align-justify.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M17 19H3\", key: \"z6ezky\" }]\n];\nconst TextAlignStart = createLucideIcon(\"text-align-start\", __iconNode);\n\nexport { __iconNode, TextAlignStart as default };\n//# sourceMappingURL=text-align-start.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 4v16\", key: \"1654pz\" }],\n [\"path\", { d: \"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\", key: \"e0r10z\" }],\n [\"path\", { d: \"M9 20h6\", key: \"s66wpe\" }]\n];\nconst Type = createLucideIcon(\"type\", __iconNode);\n\nexport { __iconNode, Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M6 4v6a6 6 0 0 0 12 0V4\", key: \"9kb039\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"20\", y2: \"20\", key: \"nun2al\" }]\n];\nconst Underline = createLucideIcon(\"underline\", __iconNode);\n\nexport { __iconNode, Underline as default };\n//# sourceMappingURL=underline.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M9 14 4 9l5-5\", key: \"102s5s\" }],\n [\"path\", { d: \"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11\", key: \"f3b9sd\" }]\n];\nconst Undo2 = createLucideIcon(\"undo-2\", __iconNode);\n\nexport { __iconNode, Undo2 as default };\n//# sourceMappingURL=undo-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.js.map\n","import React from 'react';\nimport { X } from 'lucide-react';\nimport { useTranslations } from '../i18n';\n\ninterface EditorSidebarProps {\n title: string;\n subtitle?: string;\n open: boolean;\n onClose?: () => void;\n headerActions?: React.ReactNode;\n testId?: string;\n children: React.ReactNode;\n}\n\nexport const EditorSidebar: React.FC<EditorSidebarProps> = ({\n title,\n subtitle,\n open,\n onClose,\n headerActions,\n testId = 'editor-sidebar',\n children,\n}) => {\n const t = useTranslations();\n\n if (!open) {\n return null;\n }\n\n return (\n <aside\n className=\"lex4-sidebar\"\n data-testid={testId}\n >\n <div className=\"lex4-sidebar-header\">\n <div>\n <h2 className=\"lex4-sidebar-title\">{title}</h2>\n {subtitle && (\n <p className=\"lex4-sidebar-subtitle\">{subtitle}</p>\n )}\n </div>\n <div className=\"lex4-sidebar-actions\">\n {headerActions}\n {onClose && (\n <button\n type=\"button\"\n className=\"lex4-sidebar-action-btn\"\n data-testid=\"close-editor-sidebar\"\n onClick={onClose}\n aria-label={t.sidebar.close}\n >\n <X size={14} />\n </button>\n )}\n </div>\n </div>\n <div className=\"lex4-sidebar-body\">\n {children}\n </div>\n </aside>\n );\n};\n","import React from 'react';\nimport { Trash2 } from 'lucide-react';\nimport { useDocument } from '../context/document-context';\nimport { EditorSidebar } from './EditorSidebar';\nimport { useTranslations } from '../i18n';\n\nfunction formatTimestamp(timestamp: string): string {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nexport const HistorySidebar: React.FC = () => {\n const {\n clearHistory,\n historyEntries,\n historyCursor,\n historySidebarOpen,\n jumpToHistoryEntry,\n setHistorySidebarOpen,\n } = useDocument();\n const t = useTranslations();\n\n const visibleEntries = historyEntries.slice().reverse();\n\n const headerActions = (\n <button\n type=\"button\"\n title={t.history.clearHistory}\n aria-label={t.history.clearHistory}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => clearHistory('manual')}\n className=\"lex4-sidebar-action-btn\"\n data-testid=\"clear-history\"\n >\n <Trash2 size={13} />\n </button>\n );\n\n return (\n <EditorSidebar\n title={t.history.title}\n subtitle={t.history.subtitle}\n open={historySidebarOpen}\n onClose={() => setHistorySidebarOpen(false)}\n headerActions={headerActions}\n testId=\"history-sidebar\"\n >\n {visibleEntries.length === 0 ? (\n <div\n className=\"lex4-history-empty\"\n data-testid=\"history-empty\"\n >\n {t.history.empty}\n </div>\n ) : (\n <ol className=\"lex4-history-list\" data-testid=\"history-entry-list\">\n {visibleEntries.map((entry, reversedIndex) => {\n const actualIndex = historyEntries.length - reversedIndex - 1;\n const isCurrent = actualIndex === historyCursor - 1;\n\n return (\n <li key={entry.id}>\n <button\n type=\"button\"\n className={`lex4-history-entry ${\n isCurrent ? 'active' : ''\n }`}\n data-testid={`history-entry-${actualIndex}`}\n data-history-current={isCurrent ? 'true' : 'false'}\n onClick={() => jumpToHistoryEntry(actualIndex)}\n >\n <div className=\"lex4-history-entry-row\">\n <div className=\"lex4-history-entry-dot\" />\n <div className=\"lex4-history-entry-content\">\n <div className=\"lex4-history-entry-label\">\n {entry.label}\n </div>\n <div className=\"lex4-history-entry-meta\">\n <span className=\"lex4-history-entry-source\">\n {t.regions[entry.source as keyof typeof t.regions] ?? entry.source}\n </span>\n <span className=\"lex4-history-entry-meta-dot\">·</span>\n <span className=\"lex4-history-entry-time\">\n {formatTimestamp(entry.timestamp)}\n </span>\n </div>\n </div>\n </div>\n </button>\n </li>\n );\n })}\n </ol>\n )}\n </EditorSidebar>\n );\n};\n","import React, { createContext, useContext, useMemo } from 'react';\nimport type { Lex4ToolbarConfig, Lex4ToolbarControlConfig } from '../types/editor-props';\n\nexport interface ResolvedLex4ToolbarControlConfig {\n visible: boolean;\n showLabel: boolean;\n}\n\nexport interface ResolvedLex4ToolbarConfig {\n history: ResolvedLex4ToolbarControlConfig;\n variables: ResolvedLex4ToolbarControlConfig;\n headerFooter: ResolvedLex4ToolbarControlConfig;\n}\n\nconst DEFAULT_TOOLBAR_CONTROL_CONFIG: ResolvedLex4ToolbarControlConfig = {\n visible: true,\n showLabel: true,\n};\n\nconst DEFAULT_TOOLBAR_CONFIG: ResolvedLex4ToolbarConfig = {\n history: DEFAULT_TOOLBAR_CONTROL_CONFIG,\n variables: DEFAULT_TOOLBAR_CONTROL_CONFIG,\n headerFooter: DEFAULT_TOOLBAR_CONTROL_CONFIG,\n};\n\nconst ToolbarConfigContext = createContext<ResolvedLex4ToolbarConfig>(DEFAULT_TOOLBAR_CONFIG);\n\nfunction resolveControlConfig(\n config?: Lex4ToolbarControlConfig,\n): ResolvedLex4ToolbarControlConfig {\n return {\n visible: config?.visible ?? true,\n showLabel: config?.showLabel ?? true,\n };\n}\n\nexport function normalizeToolbarConfig(\n config?: Lex4ToolbarConfig,\n): ResolvedLex4ToolbarConfig {\n return {\n history: resolveControlConfig(config?.history),\n variables: resolveControlConfig(config?.variables),\n headerFooter: resolveControlConfig(config?.headerFooter),\n };\n}\n\nexport const ToolbarConfigProvider: React.FC<{\n toolbar?: Lex4ToolbarConfig;\n children: React.ReactNode;\n}> = ({ toolbar, children }) => {\n const resolvedConfig = useMemo(() => normalizeToolbarConfig(toolbar), [toolbar]);\n return (\n <ToolbarConfigContext.Provider value={resolvedConfig}>\n {children}\n </ToolbarConfigContext.Provider>\n );\n};\n\nexport function useToolbarConfig(): ResolvedLex4ToolbarConfig {\n return useContext(ToolbarConfigContext);\n}\n","import type { EditorThemeClasses, Klass, LexicalNode } from 'lexical';\nimport type { Lex4Document } from '../types/document';\n\n/**\n * Context passed to extension handleMethods factories.\n * Provides read access to editor state so extensions can build\n * their imperative API methods.\n */\nexport interface ExtensionContext {\n getDocument: () => Lex4Document;\n getActiveEditor: () => import('lexical').LexicalEditor | null;\n getExtensionState: <T = unknown>(key: string) => T | undefined;\n setExtensionState: <T = unknown>(key: string, value: T) => void;\n}\n\n/**\n * Lex4Extension — Plugin-based extension contract.\n *\n * Extensions add capabilities to the editor without requiring\n * hard-wired imports. Each extension can contribute:\n * - Lexical nodes (custom block/inline node types)\n * - Body plugins (rendered inside every page's LexicalComposer)\n * - Toolbar items (rendered in the toolbar extension slot)\n * - Side panels (rendered to the right of the document area)\n * - Provider wrappers (React context providers wrapping the editor)\n * - Imperative handle methods (merged into the ref API)\n */\nexport interface Lex4Extension {\n /** Unique extension name used for identification. */\n name: string;\n\n /** Additional Lexical node classes to register in every editor instance. */\n nodes?: Klass<LexicalNode>[];\n\n /** Plugin components rendered inside each page body's LexicalComposer. */\n bodyPlugins?: React.ComponentType[];\n\n /** Components rendered in the toolbar's extension slot. */\n toolbarItems?: React.ComponentType[];\n\n /** Components rendered in the toolbar's right-aligned end area (next to history toggle). */\n toolbarEndItems?: React.ComponentType[];\n\n /** Component rendered as a right side panel. */\n sidePanel?: React.ComponentType;\n\n /**\n * Provider component that wraps the editor tree.\n * Useful for injecting React contexts.\n */\n provider?: React.ComponentType<{ children: React.ReactNode }>;\n\n /**\n * Lexical editor theme overrides contributed by this extension.\n * Merged into the base theme.\n */\n themeOverrides?: Partial<EditorThemeClasses>;\n\n /**\n * CSS custom property overrides applied on the `.lex4-editor` root.\n * Use to retheme the editor — e.g. `{ '--color-primary': 'hsl(350 80% 50%)' }`.\n */\n cssVariables?: Record<string, string>;\n\n /**\n * Extra CSS class name(s) added to the `.lex4-editor` root element.\n * Useful for scoping extension-specific styles.\n */\n rootClassName?: string;\n\n /**\n * Factory that returns imperative handle methods.\n * These are merged into the Lex4EditorHandle exposed via ref.\n */\n handleMethods?: (ctx: ExtensionContext) => Record<string, (...args: never[]) => unknown>;\n}\n\n/**\n * Resolved extension data after processing all extensions.\n * Used internally by the editor to wire everything together.\n */\nexport interface ResolvedExtensions {\n nodes: Klass<LexicalNode>[];\n bodyPlugins: React.ComponentType[];\n toolbarItems: React.ComponentType[];\n toolbarEndItems: React.ComponentType[];\n sidePanels: React.ComponentType[];\n providers: React.ComponentType<{ children: React.ReactNode }>[];\n themeOverrides: Partial<EditorThemeClasses>;\n cssVariables: Record<string, string>;\n rootClassNames: string[];\n handleFactories: Array<(ctx: ExtensionContext) => Record<string, (...args: never[]) => unknown>>;\n}\n\n/**\n * Processes an array of extensions into a single resolved structure.\n */\nexport function resolveExtensions(extensions: Lex4Extension[]): ResolvedExtensions {\n const resolved: ResolvedExtensions = {\n nodes: [],\n bodyPlugins: [],\n toolbarItems: [],\n toolbarEndItems: [],\n sidePanels: [],\n providers: [],\n themeOverrides: {},\n cssVariables: {},\n rootClassNames: [],\n handleFactories: [],\n };\n\n for (const ext of extensions) {\n if (ext.nodes) resolved.nodes.push(...ext.nodes);\n if (ext.bodyPlugins) resolved.bodyPlugins.push(...ext.bodyPlugins);\n if (ext.toolbarItems) resolved.toolbarItems.push(...ext.toolbarItems);\n if (ext.toolbarEndItems) resolved.toolbarEndItems.push(...ext.toolbarEndItems);\n if (ext.sidePanel) resolved.sidePanels.push(ext.sidePanel);\n if (ext.provider) resolved.providers.push(ext.provider);\n if (ext.themeOverrides) {\n resolved.themeOverrides = { ...resolved.themeOverrides, ...ext.themeOverrides };\n }\n if (ext.cssVariables) {\n Object.assign(resolved.cssVariables, ext.cssVariables);\n }\n if (ext.rootClassName) resolved.rootClassNames.push(ext.rootClassName);\n if (ext.handleMethods) resolved.handleFactories.push(ext.handleMethods);\n }\n\n return resolved;\n}\n","import React, { createContext, useContext, useMemo, useRef } from 'react';\nimport type { ResolvedExtensions, ExtensionContext } from './types';\nimport { resolveExtensions } from './types';\nimport type { Lex4Extension } from './types';\n\nconst EMPTY_RESOLVED: ResolvedExtensions = {\n nodes: [],\n bodyPlugins: [],\n toolbarItems: [],\n toolbarEndItems: [],\n sidePanels: [],\n providers: [],\n themeOverrides: {},\n cssVariables: {},\n rootClassNames: [],\n handleFactories: [],\n};\n\nconst ExtensionResolvedContext = createContext<ResolvedExtensions>(EMPTY_RESOLVED);\n\nfunction extensionArraysEqual(a?: Lex4Extension[], b?: Lex4Extension[]): boolean {\n if (a === b) return true;\n if (!a || !b) return !a && !b;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/**\n * Provides resolved extension data to all child components.\n * Extensions are resolved when the extension instances change.\n * This keeps providers and side panels in sync when an extension\n * keeps the same name but receives fresh configuration.\n */\nexport const ExtensionProvider: React.FC<{\n extensions?: Lex4Extension[];\n children: React.ReactNode;\n}> = ({ extensions, children }) => {\n const prevExtensionsRef = useRef<Lex4Extension[] | undefined>(undefined);\n const resolvedRef = useRef<ResolvedExtensions>(EMPTY_RESOLVED);\n\n if (!extensionArraysEqual(extensions, prevExtensionsRef.current)) {\n resolvedRef.current =\n extensions && extensions.length > 0 ? resolveExtensions(extensions) : EMPTY_RESOLVED;\n prevExtensionsRef.current = extensions;\n }\n const resolved = resolvedRef.current;\n\n // Wrap children with extension providers (inside-out order)\n let wrapped = <>{children}</>;\n for (let i = resolved.providers.length - 1; i >= 0; i--) {\n const Provider = resolved.providers[i];\n wrapped = <Provider>{wrapped}</Provider>;\n }\n\n return (\n <ExtensionResolvedContext.Provider value={resolved}>\n {wrapped}\n </ExtensionResolvedContext.Provider>\n );\n};\n\n/**\n * Returns the resolved extension data.\n */\nexport function useExtensions(): ResolvedExtensions {\n return useContext(ExtensionResolvedContext);\n}\n\n// --- Extension state store ---\n\nconst ExtensionStateContext = createContext<React.MutableRefObject<Record<string, unknown>> | null>(null);\n\nexport const ExtensionStateProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const stateRef = useRef<Record<string, unknown>>({});\n return (\n <ExtensionStateContext.Provider value={stateRef}>\n {children}\n </ExtensionStateContext.Provider>\n );\n};\n\n/**\n * Hook to get/set extension shared state from any component within the editor tree.\n */\nexport function useExtensionState() {\n const stateRef = useContext(ExtensionStateContext);\n return {\n get: <T = unknown>(key: string): T | undefined => stateRef?.current[key] as T | undefined,\n set: <T = unknown>(key: string, value: T) => {\n if (stateRef) stateRef.current[key] = value;\n },\n };\n}\n\n/**\n * Builds an ExtensionContext for handle method factories.\n */\nexport function useExtensionContext(\n getDocument: ExtensionContext['getDocument'],\n getActiveEditor: ExtensionContext['getActiveEditor'],\n): ExtensionContext {\n const stateRef = useContext(ExtensionStateContext);\n\n return useMemo(() => ({\n getDocument,\n getActiveEditor,\n getExtensionState: <T = unknown>(key: string) => stateRef?.current[key] as T | undefined,\n setExtensionState: <T = unknown>(key: string, value: T) => {\n if (stateRef) stateRef.current[key] = value;\n },\n }), [getDocument, getActiveEditor, stateRef]);\n}\n","import React, { useCallback, useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nconst SUPPORTED_FONTS = [\n 'Calibri',\n 'Inter',\n 'Times New Roman',\n 'Arial',\n 'Georgia',\n 'Courier New',\n] as const;\n\nexport type FontFamily = (typeof SUPPORTED_FONTS)[number];\n\nexport { SUPPORTED_FONTS };\n\n/**\n * Applies a font family to the current text selection by setting\n * inline CSS style on each selected text node.\n */\nexport function applyFontFamily(editor: LexicalEditor, fontFamily: FontFamily): void {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n node.setStyle(`font-family: ${fontFamily}`);\n }\n }\n });\n}\n\ninterface FontPluginProps {\n onFontChange?: (font: string) => void;\n}\n\n/**\n * FontPlugin — tracks the current selection's font and exposes a callback\n * for the toolbar to display the active font.\n */\nexport const FontPlugin: React.FC<FontPluginProps> = ({ onFontChange }) => {\n const [editor] = useLexicalComposerContext();\n\n const reportFont = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const node = selection.getNodes()[0];\n if ($isTextNode(node)) {\n const style = node.getStyle();\n const match = style.match(/font-family:\\s*([^;]+)/);\n onFontChange?.(match ? match[1].trim() : 'Calibri');\n }\n });\n }, [editor, onFontChange]);\n\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n reportFont();\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, reportFont]);\n\n return null;\n};\n","import { useCallback, useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nexport const SUPPORTED_FONT_SIZES = [\n 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72,\n] as const;\n\nexport type FontSize = (typeof SUPPORTED_FONT_SIZES)[number];\n\nexport const DEFAULT_FONT_SIZE: FontSize = 12;\n\n/**\n * Applies a font size to the current text selection by merging\n * into the existing inline CSS style on each selected text node.\n */\nexport function applyFontSize(editor: LexicalEditor, size: FontSize): void {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n const existing = node.getStyle();\n const updated = mergeFontSize(existing, size);\n node.setStyle(updated);\n }\n }\n });\n}\n\nfunction mergeFontSize(existingStyle: string, size: FontSize): string {\n const stripped = existingStyle.replace(/font-size:\\s*[^;]+;?\\s*/g, '').trim();\n const sizeDecl = `font-size: ${size}pt`;\n return stripped ? `${stripped}; ${sizeDecl}` : sizeDecl;\n}\n\nfunction extractFontSize(style: string): number | null {\n const match = style.match(/font-size:\\s*(\\d+(?:\\.\\d+)?)\\s*pt/);\n return match ? parseFloat(match[1]) : null;\n}\n\ninterface FontSizePluginProps {\n onFontSizeChange?: (size: number) => void;\n}\n\n/**\n * FontSizePlugin — tracks the current selection's font size\n * and exposes a callback for the toolbar to display the active size.\n */\nexport const FontSizePlugin: React.FC<FontSizePluginProps> = ({ onFontSizeChange }) => {\n const [editor] = useLexicalComposerContext();\n\n const reportFontSize = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const node = selection.getNodes()[0];\n if ($isTextNode(node)) {\n const style = node.getStyle();\n const size = extractFontSize(style);\n onFontSizeChange?.(size ?? DEFAULT_FONT_SIZE);\n }\n });\n }, [editor, onFontSizeChange]);\n\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n reportFontSize();\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, reportFontSize]);\n\n return null;\n};\n","import {\n FORMAT_TEXT_COMMAND,\n type LexicalEditor,\n type TextFormatType,\n} from 'lexical';\nimport { FORMAT_ELEMENT_COMMAND, type ElementFormatType } from 'lexical';\n\n/**\n * Dispatches a text formatting command to the given Lexical editor.\n */\nexport function toggleFormat(editor: LexicalEditor, format: TextFormatType): void {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);\n}\n\nexport function toggleBold(editor: LexicalEditor): void {\n toggleFormat(editor, 'bold');\n}\n\nexport function toggleItalic(editor: LexicalEditor): void {\n toggleFormat(editor, 'italic');\n}\n\nexport function toggleUnderline(editor: LexicalEditor): void {\n toggleFormat(editor, 'underline');\n}\n\nexport function toggleStrikethrough(editor: LexicalEditor): void {\n toggleFormat(editor, 'strikethrough');\n}\n\n/**\n * Dispatches an element alignment command.\n */\nexport function setAlignment(editor: LexicalEditor, alignment: ElementFormatType): void {\n editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, alignment);\n}\n","import {\n INSERT_ORDERED_LIST_COMMAND,\n INSERT_UNORDERED_LIST_COMMAND,\n REMOVE_LIST_COMMAND,\n} from '@lexical/list';\nimport {\n INDENT_CONTENT_COMMAND,\n OUTDENT_CONTENT_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nexport type ListType = 'number' | 'bullet';\n\n/**\n * Inserts a list of the given type into the editor.\n */\nexport function insertList(editor: LexicalEditor, type: ListType): void {\n if (type === 'number') {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n } else {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n }\n}\n\n/**\n * Removes the current list formatting.\n */\nexport function removeList(editor: LexicalEditor): void {\n editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n}\n\n/**\n * Indents the current selection.\n *\n * Paragraphs are rendered as first-line indents by the paragraph indent plugin,\n * while list items keep Lexical's native nesting behavior.\n */\nexport function indentContent(editor: LexicalEditor): void {\n editor.dispatchCommand(INDENT_CONTENT_COMMAND, undefined);\n}\n\n/**\n * Outdents the current selection.\n *\n * Paragraphs are rendered as first-line indents by the paragraph indent plugin,\n * while list items keep Lexical's native un-nesting behavior.\n */\nexport function outdentContent(editor: LexicalEditor): void {\n editor.dispatchCommand(OUTDENT_CONTENT_COMMAND, undefined);\n}\n","import { $setBlocksType } from '@lexical/selection';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n type LexicalEditor,\n} from 'lexical';\nimport {\n $createHeadingNode,\n $isHeadingNode,\n} from '@lexical/rich-text';\n\nexport type BlockType = 'paragraph' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\nexport function setBlockType(editor: LexicalEditor, blockType: BlockType): void {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n if (blockType === 'paragraph') {\n $setBlocksType(selection, () => $createParagraphNode());\n return;\n }\n\n $setBlocksType(selection, () => $createHeadingNode(blockType));\n });\n}\n\nexport function getActiveBlockType(editor: LexicalEditor): BlockType {\n let blockType: BlockType = 'paragraph';\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n const anchorNode = selection.anchor.getNode();\n const topLevelElement = anchorNode.getTopLevelElementOrThrow();\n if ($isHeadingNode(topLevelElement)) {\n blockType = topLevelElement.getTag();\n }\n });\n\n return blockType;\n}\n","export function extractStyleValue(style: string, property: string): string | undefined {\n const escapedProperty = property.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const match = style.match(new RegExp(`${escapedProperty}:\\\\s*([^;]+)`));\n return match ? match[1].trim().replace(/['\"]/g, '') : undefined;\n}\n\nexport function mergeStyleDeclaration(\n existingStyle: string,\n property: string,\n value: string,\n): string {\n const escapedProperty = property.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const stripped = existingStyle.replace(\n new RegExp(`${escapedProperty}:\\\\s*[^;]+;?\\\\s*`, 'g'),\n '',\n ).trim();\n const declaration = `${property}: ${value}`;\n return stripped ? `${stripped}; ${declaration}` : declaration;\n}\n\nexport function extractFontFamilyFromStyle(style: string): string | undefined {\n return extractStyleValue(style, 'font-family');\n}\n\nexport function extractFontSizePtFromStyle(style: string): number | undefined {\n const value = extractStyleValue(style, 'font-size');\n if (!value) {\n return undefined;\n }\n\n const match = value.match(/^(\\d+(?:\\.\\d+)?)\\s*pt$/);\n return match ? parseFloat(match[1]) : undefined;\n}\n\nexport function mergeFontFamilyStyle(existingStyle: string, fontFamily: string): string {\n return mergeStyleDeclaration(existingStyle, 'font-family', fontFamily);\n}\n\nexport function mergeFontSizeStyle(existingStyle: string, size: number): string {\n return mergeStyleDeclaration(existingStyle, 'font-size', `${size}pt`);\n}\n","import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\nimport type { VariableDefinition, VariableContextValue } from './types';\n\nconst EMPTY_CONTEXT: VariableContextValue = {\n definitions: [],\n refreshDefinitions: () => { /* no-op when variables extension not loaded */ },\n getDefinition: () => undefined,\n};\n\nconst VariableContext = createContext<VariableContextValue>(EMPTY_CONTEXT);\n\ninterface VariableProviderProps {\n initialDefinitions?: VariableDefinition[];\n children: React.ReactNode;\n}\n\n/**\n * VariableProvider — Manages the variable catalog.\n *\n * Host apps provide variable definitions via props.\n * The picker reads from this context. Definitions can be refreshed\n * at runtime without re-mounting the editor.\n */\nexport const VariableProvider: React.FC<VariableProviderProps> = ({\n initialDefinitions = [],\n children,\n}) => {\n const [definitions, setDefinitions] = useState<VariableDefinition[]>(initialDefinitions);\n\n const refresh = useCallback((newDefinitions: VariableDefinition[]) => {\n setDefinitions(newDefinitions);\n }, []);\n\n const getDefinition = useCallback(\n (key: string): VariableDefinition | undefined => {\n return definitions.find(d => d.key === key);\n },\n [definitions],\n );\n\n const value = useMemo<VariableContextValue>(\n () => ({ definitions, refreshDefinitions: refresh, getDefinition }),\n [definitions, refresh, getDefinition],\n );\n\n return (\n <VariableContext.Provider value={value}>\n {children}\n </VariableContext.Provider>\n );\n};\n\n/**\n * Hook to access the variable catalog from within the editor tree.\n * Returns empty defaults when called outside a VariableProvider.\n */\nexport function useVariables(): VariableContextValue {\n return useContext(VariableContext);\n}\n","import {\n $applyNodeReplacement,\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n DecoratorNode,\n type DOMConversionMap,\n type DOMExportOutput,\n type LexicalNode,\n type NodeKey,\n type SerializedLexicalNode,\n type Spread,\n} from 'lexical';\nimport {\n COMMAND_PRIORITY_LOW,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_DOWN_COMMAND,\n} from 'lexical';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';\nimport { useCallback, useEffect, useMemo, type MouseEvent } from 'react';\nimport { useVariables } from './variable-context';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n} from '../utils/text-style';\n\nexport type SerializedVariableNode = Spread<\n {\n variableKey: string;\n format?: number;\n style?: string;\n },\n SerializedLexicalNode\n>;\n\n/**\n * VariableNode — a custom Lexical DecoratorNode that represents\n * a document variable/placeholder (e.g. \"customer.name\").\n *\n * Variables are atomic, non-editable inline tokens that:\n * - Display as styled chips in the editor\n * - Serialize to a structured node in JSON (not plain text)\n * - Participate in copy/paste, undo/redo, and overflow\n * - Return {{key}} as text content for clipboard\n */\nexport class VariableNode extends DecoratorNode<JSX.Element> {\n __variableKey: string;\n __format: number;\n __style: string;\n\n static getType(): string {\n return 'variable-node';\n }\n\n static clone(node: VariableNode): VariableNode {\n return new VariableNode(node.__variableKey, node.__format, node.__style, node.__key);\n }\n\n constructor(variableKey: string, format = 0, style = '', key?: NodeKey) {\n super(key);\n this.__variableKey = variableKey;\n this.__format = format;\n this.__style = style;\n }\n\n getVariableKey(): string {\n return this.getLatest().__variableKey;\n }\n\n getFormat(): number {\n return this.getLatest().__format;\n }\n\n setFormat(format: number): this {\n const writable = this.getWritable();\n writable.__format = format;\n return writable;\n }\n\n getStyle(): string {\n return this.getLatest().__style;\n }\n\n setStyle(style: string): this {\n const writable = this.getWritable();\n writable.__style = style;\n return writable;\n }\n\n // -- Serialization --\n\n static importJSON(serializedNode: SerializedVariableNode): VariableNode {\n return $createVariableNode(\n serializedNode.variableKey,\n serializedNode.format ?? 0,\n serializedNode.style ?? '',\n );\n }\n\n exportJSON(): SerializedVariableNode {\n return {\n type: 'variable-node',\n version: 1,\n variableKey: this.__variableKey,\n format: this.__format,\n style: this.__style,\n };\n }\n\n // -- DOM --\n\n createDOM(): HTMLElement {\n const span = document.createElement('span');\n span.className = 'lex4-variable';\n span.setAttribute('data-variable-key', this.__variableKey);\n span.setAttribute('data-testid', `variable-${this.__variableKey}`);\n span.contentEditable = 'false';\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const span = document.createElement('span');\n span.setAttribute('data-variable-key', this.__variableKey);\n span.textContent = `{{${this.__variableKey}}}`;\n return { element: span };\n }\n\n static importDOM(): DOMConversionMap | null {\n return null;\n }\n\n // -- Behavior --\n\n isInline(): boolean {\n return true;\n }\n\n isKeyboardSelectable(): boolean {\n return true;\n }\n\n getTextContent(): string {\n return `{{${this.__variableKey}}}`;\n }\n\n // -- Rendering --\n\n decorate(): JSX.Element {\n return (\n <VariableChip\n nodeKey={this.__key}\n variableKey={this.__variableKey}\n format={this.__format}\n styleValue={this.__style}\n />\n );\n }\n}\n\nfunction VariableChip({\n nodeKey,\n variableKey,\n format,\n styleValue,\n}: {\n nodeKey: NodeKey;\n variableKey: string;\n format: number;\n styleValue: string;\n}): JSX.Element {\n const { getDefinition } = useVariables();\n const [editor] = useLexicalComposerContext();\n const [isSelected, setSelected, clearOtherSelections] = useLexicalNodeSelection(nodeKey);\n const def = getDefinition(variableKey);\n const label = def?.label ?? variableKey;\n const group = def?.group;\n const style = useMemo(() => {\n const fontFamily = extractFontFamilyFromStyle(styleValue);\n const fontSize = extractFontSizePtFromStyle(styleValue);\n return {\n ...(fontFamily ? { fontFamily } : {}),\n ...(fontSize ? { fontSize: `${fontSize}pt` } : {}),\n };\n }, [styleValue]);\n const className = [\n 'lex4-variable-chip',\n isSelected && 'lex4-variable-chip-selected',\n format & 1 ? 'lex4-text-bold' : '',\n format & 2 ? 'lex4-text-italic' : '',\n format & 8 ? 'lex4-text-underline' : '',\n format & 4 ? 'lex4-text-strikethrough' : '',\n ].filter(Boolean).join(' ');\n\n const handleClick = useCallback((event: MouseEvent<HTMLSpanElement>) => {\n event.preventDefault();\n\n if (!event.shiftKey) {\n clearOtherSelections();\n }\n\n setSelected(!isSelected);\n }, [clearOtherSelections, isSelected, setSelected]);\n\n useEffect(() => {\n const removeSelectedNodes = () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n const node = $getNodeByKey(nodeKey);\n if ($isVariableNode(node)) {\n node.remove();\n }\n return;\n }\n\n for (const node of selection.getNodes()) {\n if ($isVariableNode(node)) {\n node.remove();\n }\n }\n });\n };\n\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n () => {\n if (!isSelected) {\n return false;\n }\n removeSelectedNodes();\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n () => {\n if (!isSelected) {\n return false;\n }\n removeSelectedNodes();\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const moveCaretFromSelectedNode = (direction: 'backward' | 'forward') => {\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (!$isVariableNode(node)) {\n return;\n }\n\n if (direction === 'backward') {\n node.selectPrevious();\n } else {\n node.selectNext();\n }\n });\n };\n\n const unregisterArrowNavigation = editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (!isSelected || event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {\n return false;\n }\n\n if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault();\n moveCaretFromSelectedNode('backward');\n return true;\n }\n\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault();\n moveCaretFromSelectedNode('forward');\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n return () => {\n unregisterBackspace();\n unregisterDelete();\n unregisterArrowNavigation();\n };\n }, [editor, isSelected, nodeKey]);\n\n return (\n <span\n className={className}\n data-testid={`variable-chip-${variableKey}`}\n data-variable-group={group}\n title={variableKey}\n style={style}\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClick}\n >\n {label}\n </span>\n );\n}\n\nexport function $createVariableNode(\n variableKey: string,\n format = 0,\n style = '',\n): VariableNode {\n return $applyNodeReplacement(new VariableNode(variableKey, format, style));\n}\n\nexport function $isVariableNode(\n node: LexicalNode | null | undefined,\n): node is VariableNode {\n return node instanceof VariableNode;\n}\n","import {\n $getSelection,\n $isNodeSelection,\n type LexicalEditor,\n type TextFormatType,\n} from 'lexical';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n mergeFontFamilyStyle,\n mergeFontSizeStyle,\n} from '../utils/text-style';\nimport { $isVariableNode, type VariableNode } from './variable-node';\n\nconst FORMAT_MASKS: Partial<Record<TextFormatType, number>> = {\n bold: 1,\n italic: 2,\n strikethrough: 4,\n underline: 8,\n};\n\nfunction withSelectedVariableNodes(\n editor: LexicalEditor,\n updater: (nodes: VariableNode[]) => void,\n): boolean {\n let updated = false;\n\n editor.update(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n return;\n }\n\n const nodes = selection.getNodes().filter($isVariableNode);\n if (nodes.length === 0) {\n return;\n }\n\n updater(nodes);\n updated = true;\n });\n\n return updated;\n}\n\nexport function getSelectedVariableNodes(editor: LexicalEditor): VariableNode[] {\n let nodes: VariableNode[] = [];\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n return;\n }\n\n nodes = selection.getNodes().filter($isVariableNode);\n });\n\n return nodes;\n}\n\nexport function toggleSelectedVariableFormat(\n editor: LexicalEditor,\n format: TextFormatType,\n): boolean {\n const mask = FORMAT_MASKS[format];\n if (!mask) {\n return false;\n }\n\n return withSelectedVariableNodes(editor, (nodes) => {\n const shouldEnable = nodes.some((node) => (node.getFormat() & mask) === 0);\n\n for (const node of nodes) {\n const nextFormat = shouldEnable\n ? node.getFormat() | mask\n : node.getFormat() & ~mask;\n node.setFormat(nextFormat);\n }\n });\n}\n\nexport function applyFontFamilyToSelectedVariables(\n editor: LexicalEditor,\n fontFamily: string,\n): boolean {\n return withSelectedVariableNodes(editor, (nodes) => {\n for (const node of nodes) {\n node.setStyle(mergeFontFamilyStyle(node.getStyle(), fontFamily));\n }\n });\n}\n\nexport function applyFontSizeToSelectedVariables(\n editor: LexicalEditor,\n size: number,\n): boolean {\n return withSelectedVariableNodes(editor, (nodes) => {\n for (const node of nodes) {\n node.setStyle(mergeFontSizeStyle(node.getStyle(), size));\n }\n });\n}\n\nexport function readSelectedVariableFormatting(editor: LexicalEditor): {\n fontFamily?: string;\n fontSize?: number;\n} {\n let formatting: {\n fontFamily?: string;\n fontSize?: number;\n } = {};\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n return;\n }\n\n const firstNode = selection.getNodes().filter($isVariableNode)[0];\n if (!firstNode) {\n return;\n }\n\n const style = firstNode.getStyle();\n formatting = {\n fontFamily: extractFontFamilyFromStyle(style),\n fontSize: extractFontSizePtFromStyle(style),\n };\n });\n\n return formatting;\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Check, ChevronDown } from 'lucide-react';\nimport type { Lex4Translations } from '../i18n';\nimport { useTranslations } from '../i18n';\nimport type { BlockType } from '../lexical/commands/block-commands';\n\nconst BLOCK_TYPE_OPTIONS: Array<{ value: BlockType; shortLabel: string }> = [\n { value: 'paragraph', shortLabel: 'P' },\n { value: 'h1', shortLabel: 'H1' },\n { value: 'h2', shortLabel: 'H2' },\n { value: 'h3', shortLabel: 'H3' },\n { value: 'h4', shortLabel: 'H4' },\n { value: 'h5', shortLabel: 'H5' },\n { value: 'h6', shortLabel: 'H6' },\n];\n\nexport function getBlockTypeLabel(t: Lex4Translations, blockType: BlockType): string {\n switch (blockType) {\n case 'h1':\n return t.toolbar.heading1;\n case 'h2':\n return t.toolbar.heading2;\n case 'h3':\n return t.toolbar.heading3;\n case 'h4':\n return t.toolbar.heading4;\n case 'h5':\n return t.toolbar.heading5;\n case 'h6':\n return t.toolbar.heading6;\n default:\n return t.toolbar.paragraph;\n }\n}\n\nfunction getBlockTypeShortLabel(blockType: BlockType): string {\n return BLOCK_TYPE_OPTIONS.find((option) => option.value === blockType)?.shortLabel ?? 'P';\n}\n\ninterface BlockTypePickerProps {\n value: BlockType;\n onChange: (blockType: BlockType) => void;\n}\n\nexport const BlockTypePicker: React.FC<BlockTypePickerProps> = ({ value, onChange }) => {\n const t = useTranslations();\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleEscape);\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleEscape);\n };\n }, [open]);\n\n return (\n <div\n ref={containerRef}\n className=\"lex4-block-type-picker\"\n data-testid=\"block-type-picker\"\n >\n <button\n type=\"button\"\n className={`lex4-block-type-trigger${open ? ' open' : ''}`}\n data-testid=\"block-type-selector\"\n aria-label={t.toolbar.blockType}\n aria-expanded={open}\n aria-haspopup=\"menu\"\n title={getBlockTypeLabel(t, value)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setOpen((current) => !current)}\n >\n <span\n className={`lex4-block-type-trigger-code${value === 'paragraph' ? '' : ' heading'}`}\n >\n {getBlockTypeShortLabel(value)}\n </span>\n <ChevronDown size={14} className={`lex4-block-type-trigger-chevron${open ? ' open' : ''}`} />\n </button>\n\n {open && (\n <div\n className=\"lex4-block-type-menu\"\n role=\"menu\"\n data-testid=\"block-type-menu\"\n >\n {BLOCK_TYPE_OPTIONS.map((option) => {\n const label = getBlockTypeLabel(t, option.value);\n const active = option.value === value;\n\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n className={`lex4-block-type-item${active ? ' active' : ''}`}\n data-testid={`block-type-option-${option.value}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n onChange(option.value);\n setOpen(false);\n }}\n >\n <span\n className={`lex4-block-type-item-code${option.value === 'paragraph' ? '' : ' heading'}${active ? ' active' : ''}`}\n >\n {option.shortLabel}\n </span>\n <span className=\"lex4-block-type-item-label\">\n {label}\n </span>\n <span className=\"lex4-block-type-item-check\" aria-hidden=\"true\">\n {active ? <Check size={14} /> : null}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { FileText } from 'lucide-react';\nimport { useTranslations } from '../i18n';\n\ninterface HeaderFooterToggleProps {\n enabled: boolean;\n onToggle: (enabled: boolean) => void;\n showLabel?: boolean;\n}\n\nexport const HeaderFooterToggle: React.FC<HeaderFooterToggleProps> = ({\n enabled,\n onToggle,\n showLabel = true,\n}) => {\n const t = useTranslations();\n\n return (\n <label\n className=\"lex4-hf-toggle\"\n data-testid=\"header-footer-toggle\"\n >\n <FileText size={14} className=\"lex4-hf-toggle-icon\" />\n {showLabel && (\n <span className=\"lex4-hf-toggle-label\">\n {t.headerFooter.label}\n </span>\n )}\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t.headerFooter.label}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => onToggle(!enabled)}\n className=\"lex4-hf-switch\"\n style={{ backgroundColor: enabled ? 'var(--color-primary)' : 'var(--color-muted)' }}\n data-testid=\"header-footer-switch\"\n title={t.headerFooter.label}\n >\n <span className=\"lex4-hf-switch-knob\" />\n </button>\n </label>\n );\n};\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { CopyPlus, Eraser, Settings2, Trash2 } from 'lucide-react';\nimport { useTranslations } from '../i18n';\nimport type { PageCounterMode } from '../types/document';\n\ninterface HeaderFooterActionsProps {\n activePageId: string | null;\n pageCounterMode: PageCounterMode;\n onPageCounterModeChange: (mode: PageCounterMode) => void;\n onCopyHeaderToAll: () => void;\n onCopyFooterToAll: () => void;\n onClearHeader: () => void;\n onClearFooter: () => void;\n onClearAllHeaders: () => void;\n onClearAllFooters: () => void;\n}\n\nconst PAGE_COUNTER_OPTIONS: PageCounterMode[] = ['none', 'header', 'footer', 'both'];\n\nexport const HeaderFooterActions: React.FC<HeaderFooterActionsProps> = ({\n activePageId,\n pageCounterMode,\n onPageCounterModeChange,\n onCopyHeaderToAll,\n onCopyFooterToAll,\n onClearHeader,\n onClearFooter,\n onClearAllHeaders,\n onClearAllFooters,\n}) => {\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const hasActivePage = activePageId !== null;\n const t = useTranslations();\n\n const close = useCallback(() => setOpen(false), []);\n\n useEffect(() => {\n if (!open) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n close();\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open, close]);\n\n const handleAction = (action: () => void) => {\n action();\n close();\n };\n\n return (\n <div ref={containerRef} style={{ position: 'relative' }} data-testid=\"header-footer-actions\">\n <button\n type=\"button\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => setOpen(!open)}\n className=\"lex4-settings-trigger lex4-settings-trigger-icon\"\n data-testid=\"header-footer-menu-trigger\"\n aria-expanded={open}\n aria-haspopup=\"true\"\n aria-label={t.headerFooter.settingsLabel}\n title={t.headerFooter.settingsLabel}\n >\n <Settings2 size={14} />\n </button>\n\n {open && (\n <div\n className=\"lex4-settings-menu\"\n role=\"menu\"\n data-testid=\"header-footer-menu\"\n >\n <SectionLabel>{t.headerFooter.pageCounter}</SectionLabel>\n <div className=\"lex4-settings-counter-grid\" data-testid=\"page-counter-mode\">\n {PAGE_COUNTER_OPTIONS.map((value) => (\n <button\n key={value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={pageCounterMode === value}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => onPageCounterModeChange(value)}\n className=\"lex4-settings-counter-btn\"\n data-testid={`page-counter-${value}`}\n >\n {t.headerFooter.pageCounterModes[value]}\n </button>\n ))}\n </div>\n\n <MenuDivider />\n\n <SectionLabel>{t.headerFooter.headerSection}</SectionLabel>\n <MenuItem\n icon={<CopyPlus size={14} />}\n label={t.headerFooter.copyToAllPages}\n onClick={() => handleAction(onCopyHeaderToAll)}\n disabled={!hasActivePage}\n testId=\"copy-header-all\"\n />\n <MenuItem\n icon={<Eraser size={14} />}\n label={t.headerFooter.clearThisPage}\n onClick={() => handleAction(onClearHeader)}\n disabled={!hasActivePage}\n testId=\"clear-header\"\n />\n <MenuItem\n icon={<Trash2 size={14} />}\n label={t.headerFooter.clearAll}\n onClick={() => handleAction(onClearAllHeaders)}\n testId=\"clear-all-headers\"\n />\n\n <MenuDivider />\n\n <SectionLabel>{t.headerFooter.footerSection}</SectionLabel>\n <MenuItem\n icon={<CopyPlus size={14} />}\n label={t.headerFooter.copyToAllPages}\n onClick={() => handleAction(onCopyFooterToAll)}\n disabled={!hasActivePage}\n testId=\"copy-footer-all\"\n />\n <MenuItem\n icon={<Eraser size={14} />}\n label={t.headerFooter.clearThisPage}\n onClick={() => handleAction(onClearFooter)}\n disabled={!hasActivePage}\n testId=\"clear-footer\"\n />\n <MenuItem\n icon={<Trash2 size={14} />}\n label={t.headerFooter.clearAll}\n onClick={() => handleAction(onClearAllFooters)}\n testId=\"clear-all-footers\"\n />\n </div>\n )}\n </div>\n );\n};\n\nconst SectionLabel: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"lex4-settings-label\">\n {children}\n </div>\n);\n\ninterface MenuItemProps {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n testId: string;\n}\n\nconst MenuItem: React.FC<MenuItemProps> = ({ icon, label, onClick, disabled, testId }) => (\n <button\n type=\"button\"\n role=\"menuitem\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={onClick}\n disabled={disabled}\n className=\"lex4-settings-item\"\n data-testid={testId}\n >\n {icon}\n {label}\n </button>\n);\n\nconst MenuDivider: React.FC = () => (\n <div className=\"lex4-settings-divider\" />\n);\n","import React, { useCallback } from 'react';\nimport { useDocument } from '../context/document-context';\nimport { useToolbarConfig } from '../context/toolbar-config';\nimport { useTranslations, interpolate } from '../i18n';\nimport type { PageCounterMode } from '../types/document';\nimport { HeaderFooterToggle } from './HeaderFooterToggle';\nimport { HeaderFooterActions } from './HeaderFooterActions';\n\nexport const CanvasControls: React.FC = () => {\n const { document, dispatch, activePageId, runHistoryAction } = useDocument();\n const toolbarConfig = useToolbarConfig();\n const t = useTranslations();\n\n const runCanvasAction = useCallback((label: string, callback: () => void) => {\n runHistoryAction(\n {\n label,\n source: 'toolbar',\n region: 'document',\n },\n callback,\n );\n }, [runHistoryAction]);\n\n const handleToggle = useCallback((enabled: boolean) => {\n runCanvasAction(\n enabled ? t.history.actions.enabledHeadersFooters : t.history.actions.disabledHeadersFooters,\n () => {\n dispatch({ type: 'SET_HEADER_FOOTER_ENABLED', enabled });\n },\n );\n }, [dispatch, runCanvasAction, t.history.actions.disabledHeadersFooters, t.history.actions.enabledHeadersFooters]);\n\n const handleCopyHeaderToAll = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.copiedHeaderToAll, () => {\n dispatch({ type: 'COPY_HEADER_TO_ALL', sourcePageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.copiedHeaderToAll]);\n\n const handleCopyFooterToAll = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.copiedFooterToAll, () => {\n dispatch({ type: 'COPY_FOOTER_TO_ALL', sourcePageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.copiedFooterToAll]);\n\n const handleClearHeader = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.clearedHeader, () => {\n dispatch({ type: 'CLEAR_HEADER', pageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.clearedHeader]);\n\n const handleClearFooter = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.clearedFooter, () => {\n dispatch({ type: 'CLEAR_FOOTER', pageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.clearedFooter]);\n\n const handleClearAllHeaders = useCallback(() => {\n runCanvasAction(t.history.actions.clearedAllHeaders, () => {\n dispatch({ type: 'CLEAR_ALL_HEADERS' });\n });\n }, [dispatch, runCanvasAction, t.history.actions.clearedAllHeaders]);\n\n const handleClearAllFooters = useCallback(() => {\n runCanvasAction(t.history.actions.clearedAllFooters, () => {\n dispatch({ type: 'CLEAR_ALL_FOOTERS' });\n });\n }, [dispatch, runCanvasAction, t.history.actions.clearedAllFooters]);\n\n const handlePageCounterModeChange = useCallback((mode: PageCounterMode) => {\n runCanvasAction(interpolate(t.history.actions.pageCounterSet, { value: mode }), () => {\n dispatch({ type: 'SET_PAGE_COUNTER_MODE', mode });\n });\n }, [dispatch, runCanvasAction, t.history.actions.pageCounterSet]);\n\n if (!toolbarConfig.headerFooter.visible) {\n return null;\n }\n\n return (\n <div className=\"lex4-toolbar-group lex4-toolbar-group-gap\" data-testid=\"header-footer-controls\">\n <HeaderFooterToggle\n enabled={document.headerFooterEnabled}\n onToggle={handleToggle}\n showLabel={toolbarConfig.headerFooter.showLabel}\n />\n\n {document.headerFooterEnabled && (\n <HeaderFooterActions\n activePageId={activePageId}\n pageCounterMode={document.pageCounterMode}\n onPageCounterModeChange={handlePageCounterModeChange}\n onCopyHeaderToAll={handleCopyHeaderToAll}\n onCopyFooterToAll={handleCopyFooterToAll}\n onClearHeader={handleClearHeader}\n onClearFooter={handleClearFooter}\n onClearAllHeaders={handleClearAllHeaders}\n onClearAllFooters={handleClearAllFooters}\n />\n )}\n </div>\n );\n};\n","import React, { useCallback, useEffect, useState } from 'react';\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n $selectAll,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n type LexicalEditor,\n} from 'lexical';\nimport {\n Undo2,\n Redo2,\n Bold,\n Italic,\n Underline,\n Strikethrough,\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n ListOrdered,\n List,\n IndentIncrease,\n IndentDecrease,\n History,\n Type,\n ALargeSmall,\n} from 'lucide-react';\nimport { useDocument } from '../context/document-context';\nimport { useToolbarConfig } from '../context/toolbar-config';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { SUPPORTED_FONTS } from '../lexical/plugins/font-plugin';\nimport { applyFontFamily, type FontFamily } from '../lexical/plugins/font-plugin';\nimport {\n applyFontSize,\n DEFAULT_FONT_SIZE,\n SUPPORTED_FONT_SIZES,\n type FontSize,\n} from '../lexical/plugins/font-size-plugin';\nimport {\n toggleBold,\n toggleItalic,\n toggleUnderline,\n toggleStrikethrough,\n setAlignment,\n} from '../lexical/commands/format-commands';\nimport { insertList, indentContent, outdentContent } from '../lexical/commands/list-commands';\nimport {\n getActiveBlockType,\n setBlockType,\n type BlockType,\n} from '../lexical/commands/block-commands';\nimport {\n applyFontFamilyToSelectedVariables,\n applyFontSizeToSelectedVariables,\n getSelectedVariableNodes,\n readSelectedVariableFormatting,\n toggleSelectedVariableFormat,\n} from '../variables/variable-formatting';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n} from '../utils/text-style';\nimport { debug } from '../utils/debug';\nimport { BlockTypePicker, getBlockTypeLabel } from './BlockTypePicker';\nimport { CanvasControls } from './CanvasControls';\n\nexport const Toolbar: React.FC = () => {\n const {\n activeEditor,\n canRedo,\n canUndo,\n editorRegistry,\n globalSelectionActive,\n historySidebarOpen,\n redo,\n runHistoryAction,\n setHistorySidebarOpen,\n undo,\n } = useDocument();\n const { toolbarItems, toolbarEndItems } = useExtensions();\n const toolbarConfig = useToolbarConfig();\n const t = useTranslations();\n const [activeBlockType, setActiveBlockType] = useState<BlockType>('paragraph');\n const [activeFontFamily, setActiveFontFamily] = useState<FontFamily>('Calibri');\n const [activeFontSize, setActiveFontSize] = useState<number>(DEFAULT_FONT_SIZE);\n\n const normalizeFontFamily = useCallback((fontFamily?: string): FontFamily => {\n if (fontFamily && SUPPORTED_FONTS.includes(fontFamily as FontFamily)) {\n return fontFamily as FontFamily;\n }\n return 'Calibri';\n }, []);\n\n const withBodySelection = useCallback(\n (editor: LexicalEditor, action: (targetEditor: LexicalEditor) => void) => {\n editor.update(() => {\n $selectAll();\n });\n action(editor);\n },\n [],\n );\n\n const applyToBodyEditors = useCallback(\n (action: (targetEditor: LexicalEditor) => void) => {\n const targetEditors = globalSelectionActive\n ? editorRegistry.all()\n : activeEditor\n ? [activeEditor]\n : [];\n\n targetEditors.forEach(editor => {\n if (globalSelectionActive) {\n withBodySelection(editor, action);\n } else {\n action(editor);\n }\n });\n },\n [activeEditor, editorRegistry, globalSelectionActive, withBodySelection],\n );\n\n const runToolbarAction = useCallback(\n (label: string, callback: () => void) => {\n runHistoryAction(\n {\n label,\n source: 'toolbar',\n region: 'document',\n },\n callback,\n );\n },\n [runHistoryAction],\n );\n\n useEffect(() => {\n if (!activeEditor) {\n setActiveBlockType('paragraph');\n setActiveFontFamily('Calibri');\n setActiveFontSize(DEFAULT_FONT_SIZE);\n return;\n }\n\n const updateSelectionState = () => {\n const selectedVariables = getSelectedVariableNodes(activeEditor);\n if (selectedVariables.length > 0) {\n const formatting = readSelectedVariableFormatting(activeEditor);\n setActiveBlockType('paragraph');\n setActiveFontFamily(normalizeFontFamily(formatting.fontFamily));\n setActiveFontSize(formatting.fontSize ?? DEFAULT_FONT_SIZE);\n return;\n }\n\n setActiveBlockType(getActiveBlockType(activeEditor));\n\n let nextFontFamily: FontFamily = 'Calibri';\n let nextFontSize: number = DEFAULT_FONT_SIZE;\n activeEditor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n const textNode = selection.getNodes().find($isTextNode);\n if (!textNode) {\n return;\n }\n\n const style = textNode.getStyle();\n nextFontFamily = normalizeFontFamily(extractFontFamilyFromStyle(style));\n nextFontSize = extractFontSizePtFromStyle(style) ?? DEFAULT_FONT_SIZE;\n });\n\n setActiveFontFamily(nextFontFamily);\n setActiveFontSize(nextFontSize);\n };\n\n updateSelectionState();\n const unregisterSelectionChange = activeEditor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n updateSelectionState();\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n const unregisterUpdateListener = activeEditor.registerUpdateListener(() => {\n updateSelectionState();\n });\n\n return () => {\n unregisterSelectionChange();\n unregisterUpdateListener();\n };\n }, [activeEditor, normalizeFontFamily]);\n\n const handleBold = useCallback(() => {\n debug('toolbar', `bold (globalSelection=${globalSelectionActive}, editors=${editorRegistry.all().length}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.boldApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'bold')) {\n return;\n }\n applyToBodyEditors(toggleBold);\n });\n }, [activeEditor, applyToBodyEditors, editorRegistry, globalSelectionActive, runToolbarAction, t.history.actions.boldApplied]);\n\n const handleItalic = useCallback(() => {\n debug('toolbar', `italic (globalSelection=${globalSelectionActive}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.italicApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'italic')) {\n return;\n }\n applyToBodyEditors(toggleItalic);\n });\n }, [activeEditor, applyToBodyEditors, globalSelectionActive, runToolbarAction, t.history.actions.italicApplied]);\n\n const handleUnderline = useCallback(() => {\n debug('toolbar', `underline (globalSelection=${globalSelectionActive}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.underlineApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'underline')) {\n return;\n }\n applyToBodyEditors(toggleUnderline);\n });\n }, [activeEditor, applyToBodyEditors, globalSelectionActive, runToolbarAction, t.history.actions.underlineApplied]);\n\n const handleStrikethrough = useCallback(() => {\n debug('toolbar', `strikethrough (globalSelection=${globalSelectionActive}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.strikethroughApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'strikethrough')) {\n return;\n }\n applyToBodyEditors(toggleStrikethrough);\n });\n }, [activeEditor, applyToBodyEditors, globalSelectionActive, runToolbarAction, t.history.actions.strikethroughApplied]);\n\n const handleAlignLeft = useCallback(() => {\n runToolbarAction(t.history.actions.alignedLeft, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'left'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.alignedLeft]);\n\n const handleAlignCenter = useCallback(() => {\n runToolbarAction(t.history.actions.alignedCenter, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'center'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.alignedCenter]);\n\n const handleAlignRight = useCallback(() => {\n runToolbarAction(t.history.actions.alignedRight, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'right'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.alignedRight]);\n\n const handleAlignJustify = useCallback(() => {\n runToolbarAction(t.history.actions.justifiedText, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'justify'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.justifiedText]);\n\n const handleListNumber = useCallback(() => {\n runToolbarAction(t.history.actions.insertedNumberedList, () => {\n applyToBodyEditors(editor => insertList(editor, 'number'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.insertedNumberedList]);\n\n const handleListBullet = useCallback(() => {\n runToolbarAction(t.history.actions.insertedBulletList, () => {\n applyToBodyEditors(editor => insertList(editor, 'bullet'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.insertedBulletList]);\n\n const handleIndent = useCallback(() => {\n runToolbarAction(t.history.actions.indentedContent, () => {\n applyToBodyEditors(indentContent);\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.indentedContent]);\n\n const handleOutdent = useCallback(() => {\n runToolbarAction(t.history.actions.outdentedContent, () => {\n applyToBodyEditors(outdentContent);\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.outdentedContent]);\n\n const handleFontChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const fontFamily = e.target.value as FontFamily;\n runToolbarAction(interpolate(t.history.actions.fontChanged, { value: fontFamily }), () => {\n if (activeEditor && applyFontFamilyToSelectedVariables(activeEditor, fontFamily)) {\n return;\n }\n applyToBodyEditors(editor => applyFontFamily(editor, fontFamily));\n });\n },\n [activeEditor, applyToBodyEditors, runToolbarAction, t.history.actions.fontChanged],\n );\n\n const handleFontSizeChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const size = parseInt(e.target.value, 10) as FontSize;\n runToolbarAction(interpolate(t.history.actions.fontSizeChanged, { value: String(size) }), () => {\n if (activeEditor && applyFontSizeToSelectedVariables(activeEditor, size)) {\n return;\n }\n applyToBodyEditors(editor => applyFontSize(editor, size));\n });\n },\n [activeEditor, applyToBodyEditors, runToolbarAction, t.history.actions.fontSizeChanged],\n );\n\n const handleBlockTypeChange = useCallback(\n (blockType: BlockType) => {\n runToolbarAction(\n interpolate(t.history.actions.blockTypeChanged, { value: getBlockTypeLabel(t, blockType) }),\n () => {\n applyToBodyEditors(editor => setBlockType(editor, blockType));\n },\n );\n },\n [\n applyToBodyEditors,\n runToolbarAction,\n t.history.actions.blockTypeChanged,\n t,\n ],\n );\n\n const handleToggleHistory = useCallback(() => {\n setHistorySidebarOpen(!historySidebarOpen);\n }, [historySidebarOpen, setHistorySidebarOpen]);\n\n return (\n <div\n className=\"lex4-toolbar\"\n data-testid=\"toolbar\"\n >\n <div className=\"lex4-toolbar-row\">\n <div className=\"lex4-toolbar-group\" data-testid=\"history-controls\">\n <ToolbarIconButton\n title={t.toolbar.undo}\n testId=\"btn-undo\"\n disabled={!canUndo}\n onClick={undo}\n >\n <Undo2 size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton\n title={t.toolbar.redo}\n testId=\"btn-redo\"\n disabled={!canRedo}\n onClick={redo}\n >\n <Redo2 size={15} />\n </ToolbarIconButton>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\">\n <BlockTypePicker\n value={activeBlockType}\n onChange={handleBlockTypeChange}\n />\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group-gap\">\n <Type size={14} className=\"lex4-toolbar-icon\" />\n <select\n className=\"lex4-toolbar-select\"\n data-testid=\"font-selector\"\n value={activeFontFamily}\n onChange={handleFontChange}\n >\n {SUPPORTED_FONTS.map(font => (\n <option key={font} value={font} style={{ fontFamily: font }}>\n {font}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"lex4-toolbar-group-gap\">\n <ALargeSmall size={14} className=\"lex4-toolbar-icon\" />\n <select\n className=\"lex4-toolbar-select lex4-toolbar-select-narrow\"\n data-testid=\"font-size-selector\"\n value={String(activeFontSize)}\n onChange={handleFontSizeChange}\n >\n {SUPPORTED_FONT_SIZES.map(size => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\" data-testid=\"format-group\">\n <ToolbarIconButton title={t.toolbar.bold} testId=\"btn-bold\" onClick={handleBold}>\n <Bold size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.italic} testId=\"btn-italic\" onClick={handleItalic}>\n <Italic size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.underline} testId=\"btn-underline\" onClick={handleUnderline}>\n <Underline size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.strikethrough} testId=\"btn-strike\" onClick={handleStrikethrough}>\n <Strikethrough size={15} />\n </ToolbarIconButton>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\" data-testid=\"align-group\">\n <ToolbarIconButton title={t.toolbar.alignLeft} testId=\"btn-align-left\" onClick={handleAlignLeft}>\n <AlignLeft size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.alignCenter} testId=\"btn-align-center\" onClick={handleAlignCenter}>\n <AlignCenter size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.alignRight} testId=\"btn-align-right\" onClick={handleAlignRight}>\n <AlignRight size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.justify} testId=\"btn-align-justify\" onClick={handleAlignJustify}>\n <AlignJustify size={15} />\n </ToolbarIconButton>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\" data-testid=\"list-group\">\n <ToolbarIconButton title={t.toolbar.numberedList} testId=\"btn-list-number\" onClick={handleListNumber}>\n <ListOrdered size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.bulletList} testId=\"btn-list-bullet\" onClick={handleListBullet}>\n <List size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.indent} testId=\"btn-indent\" onClick={handleIndent}>\n <IndentIncrease size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.outdent} testId=\"btn-outdent\" onClick={handleOutdent}>\n <IndentDecrease size={15} />\n </ToolbarIconButton>\n </div>\n\n {toolbarItems.length > 0 && (\n <>\n <Divider />\n {toolbarItems.map((ToolbarItem, idx) => (\n <ToolbarItem key={idx} />\n ))}\n </>\n )}\n\n <Divider />\n\n <CanvasControls />\n\n <div className=\"lex4-toolbar-end\">\n {toolbarEndItems.map((EndItem, idx) => (\n <EndItem key={idx} />\n ))}\n {toolbarConfig.history.visible && (\n <button\n type=\"button\"\n className={`lex4-toolbar-toggle-btn${historySidebarOpen ? ' active' : ''}`}\n onMouseDown={(e) => e.preventDefault()}\n onClick={handleToggleHistory}\n data-testid=\"toggle-history-sidebar\"\n title={historySidebarOpen ? t.toolbar.closeHistory : t.toolbar.openHistory}\n aria-label={historySidebarOpen ? t.toolbar.closeHistory : t.toolbar.openHistory}\n >\n <History size={14} />\n {toolbarConfig.history.showLabel && t.toolbar.history}\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n\ninterface ToolbarIconButtonProps {\n title: string;\n testId: string;\n disabled?: boolean;\n active?: boolean;\n onClick?: () => void;\n children: React.ReactNode;\n}\n\nconst ToolbarIconButton: React.FC<ToolbarIconButtonProps> = ({\n title,\n testId,\n disabled = false,\n active = false,\n onClick,\n children,\n}) => (\n <button\n type=\"button\"\n title={title}\n aria-label={title}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={onClick}\n className={`lex4-toolbar-btn${active ? ' active' : ''}`}\n data-testid={testId}\n >\n {children}\n </button>\n);\n\nconst Divider: React.FC = () => (\n <div className=\"lex4-toolbar-separator\" />\n);\n","import {\n A4_HEIGHT_PX,\n PAGE_MARGIN_TOP_PX,\n PAGE_MARGIN_BOTTOM_PX,\n} from './dimensions';\n\nexport function computeBodyHeight(\n headerHeight: number,\n footerHeight: number,\n): number {\n const verticalMargins = PAGE_MARGIN_TOP_PX + PAGE_MARGIN_BOTTOM_PX;\n return A4_HEIGHT_PX - headerHeight - footerHeight - verticalMargins;\n}\n\n/**\n * Computes the content area height based on whether\n * headers/footers are enabled.\n */\nexport function computeContentAreaHeight(\n headerFooterEnabled: boolean,\n headerHeight: number,\n footerHeight: number,\n): number {\n if (!headerFooterEnabled) {\n return computeBodyHeight(0, 0);\n }\n return computeBodyHeight(headerHeight, footerHeight);\n}\n","import type { SerializedEditorState, SerializedLexicalNode } from 'lexical';\n\n/**\n * Utilities for splitting and merging Lexical editor states.\n *\n * A SerializedEditorState has shape:\n * { root: { children: [...], type: \"root\", ... } }\n *\n * Content flow between pages is achieved by manipulating\n * the root.children array — extracting, splitting, merging\n * top-level block nodes.\n */\n\n/** Extract all top-level nodes from a serialized editor state */\nexport function getTopLevelNodes(state: SerializedEditorState | null): SerializedLexicalNode[] {\n if (!state) return [];\n return (state.root as any).children ?? [];\n}\n\n/** Count top-level nodes in a serialized editor state */\nexport function countTopLevelNodes(state: SerializedEditorState | null): number {\n return getTopLevelNodes(state).length;\n}\n\n/**\n * Create a SerializedEditorState from a list of top-level nodes.\n * Uses a standard root wrapper.\n */\nexport function createEditorStateFromNodes(\n nodes: SerializedLexicalNode[],\n): SerializedEditorState {\n return {\n root: {\n children: nodes,\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState;\n}\n\n/**\n * Split a serialized editor state at a given node index.\n *\n * Returns [before, after] where:\n * - before contains nodes 0..splitIndex-1\n * - after contains nodes splitIndex..end\n */\nexport function splitEditorState(\n state: SerializedEditorState | null,\n splitIndex: number,\n): [SerializedEditorState | null, SerializedEditorState | null] {\n const nodes = getTopLevelNodes(state);\n\n if (splitIndex <= 0) {\n return [null, state];\n }\n if (splitIndex >= nodes.length) {\n return [state, null];\n }\n\n const before = nodes.slice(0, splitIndex);\n const after = nodes.slice(splitIndex);\n\n return [\n before.length > 0 ? createEditorStateFromNodes(before) : null,\n after.length > 0 ? createEditorStateFromNodes(after) : null,\n ];\n}\n\n/**\n * Merge two serialized editor states by concatenating their top-level nodes.\n * Returns a new state with all nodes from both states.\n */\nexport function mergeEditorStates(\n stateA: SerializedEditorState | null,\n stateB: SerializedEditorState | null,\n): SerializedEditorState | null {\n const nodesA = getTopLevelNodes(stateA);\n const nodesB = getTopLevelNodes(stateB);\n\n const all = [...nodesA, ...nodesB];\n if (all.length === 0) return null;\n\n return createEditorStateFromNodes(all);\n}\n\n/**\n * Append nodes to the end of a serialized editor state.\n */\nexport function appendNodes(\n state: SerializedEditorState | null,\n nodes: SerializedLexicalNode[],\n): SerializedEditorState {\n const existing = getTopLevelNodes(state);\n return createEditorStateFromNodes([...existing, ...nodes]);\n}\n\n/**\n * Split a serialized block node's children at a given child offset.\n *\n * Returns two copies of the block: the first has children [0, offset),\n * the second has children [offset, end). Both keep the same node type,\n * format, direction, indent, and version.\n *\n * Returns null pair if the offset is out of range.\n */\nexport function splitBlockNode(\n block: SerializedLexicalNode,\n childOffset: number,\n): [SerializedLexicalNode | null, SerializedLexicalNode | null] {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const children: SerializedLexicalNode[] = (block as any).children ?? [];\n\n if (childOffset <= 0) return [null, structuredClone(block)];\n if (childOffset >= children.length) return [structuredClone(block), null];\n\n const before = children.slice(0, childOffset);\n const after = children.slice(childOffset);\n\n const makeCopy = (kids: SerializedLexicalNode[]): SerializedLexicalNode => {\n const copy = structuredClone(block);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (copy as any).children = kids;\n return copy;\n };\n\n return [makeCopy(before), makeCopy(after)];\n}\n\n/**\n * Remove the last N nodes from a serialized editor state.\n * Returns [trimmedState, removedNodes].\n */\nexport function removeLastNodes(\n state: SerializedEditorState | null,\n count: number,\n): [SerializedEditorState | null, SerializedLexicalNode[]] {\n const nodes = getTopLevelNodes(state);\n if (count >= nodes.length) {\n return [null, [...nodes]];\n }\n\n const kept = nodes.slice(0, nodes.length - count);\n const removed = nodes.slice(nodes.length - count);\n\n return [\n kept.length > 0 ? createEditorStateFromNodes(kept) : null,\n removed,\n ];\n}\n\n/**\n * Remove the first N nodes from a serialized editor state.\n * Returns [removedNodes, remainingState].\n */\nexport function removeFirstNodes(\n state: SerializedEditorState | null,\n count: number,\n): [SerializedLexicalNode[], SerializedEditorState | null] {\n const nodes = getTopLevelNodes(state);\n if (count >= nodes.length) {\n return [[...nodes], null];\n }\n\n const removed = nodes.slice(0, count);\n const remaining = nodes.slice(count);\n\n return [\n removed,\n remaining.length > 0 ? createEditorStateFromNodes(remaining) : null,\n ];\n}\n","import { useCallback, useRef } from 'react';\nimport type { SerializedEditorState } from 'lexical';\nimport type { DocumentAction } from '../context/document-context';\nimport { computeBodyHeight } from '../constants/page-layout';\nimport {\n getTopLevelNodes,\n splitEditorState,\n splitBlockNode,\n mergeEditorStates,\n createEditorStateFromNodes,\n} from '../utils/editor-state-utils';\nimport type { Lex4Document, PageState } from '../types/document';\nimport { createEmptyPage, createPageFromTemplate } from '../types/document';\n\n/**\n * usePagination — Orchestrates content flow between pages.\n *\n * When a page body overflows, this hook:\n * 1. Measures which nodes fit within the body height\n * 2. Splits the editor state at the overflow point\n * 3. Moves overflow content to the next page (creating it if needed)\n * 4. Cascades forward through all subsequent pages\n *\n * When a page body underflows (content deleted), it:\n * 1. Checks if the next page has content that fits\n * 2. Pulls content back from the next page\n * 3. Removes empty trailing pages\n */\nexport function usePagination(\n document: Lex4Document,\n dispatch: React.Dispatch<DocumentAction>,\n) {\n const reflowingRef = useRef(false);\n const pendingReflowRef = useRef(false);\n\n /**\n * Estimate how many top-level nodes fit within a given pixel height.\n *\n * Since we don't have DOM measurements at this point (the nodes may not\n * be rendered yet), we use a heuristic: assume each top-level paragraph\n * is approximately 24px (one line of text). This is imperfect but\n * provides a reasonable starting split point. The ResizeObserver in\n * PageBody will trigger another reflow if the estimate was wrong.\n */\n const estimateNodesFitting = useCallback(\n (\n state: SerializedEditorState | null,\n bodyHeight: number,\n ): number => {\n const nodes = getTopLevelNodes(state);\n if (nodes.length === 0) return 0;\n\n const estimatedLineHeight = 24;\n let usedHeight = 0;\n let fitCount = 0;\n\n for (const _node of nodes) {\n usedHeight += estimatedLineHeight;\n if (usedHeight > bodyHeight) break;\n fitCount++;\n }\n\n // At least one node must stay on the current page\n return Math.max(1, fitCount);\n },\n [],\n );\n\n /**\n * Handle overflow on a specific page.\n * Splits content and pushes overflow to the next page.\n */\n const handlePageOverflow = useCallback(\n (pageIndex: number) => {\n if (reflowingRef.current) {\n pendingReflowRef.current = true;\n return;\n }\n\n reflowingRef.current = true;\n\n try {\n const pages = document.pages;\n const page = pages[pageIndex];\n if (!page) return;\n\n const headerH = document.headerFooterEnabled ? page.headerHeight : 0;\n const footerH = document.headerFooterEnabled ? page.footerHeight : 0;\n const bodyHeight = computeBodyHeight(headerH, footerH);\n\n const nodes = getTopLevelNodes(page.bodyState);\n if (nodes.length <= 1) {\n // Single block overflow — attempt heuristic mid-block split on\n // the serialized node. The real DOM-based split in OverflowPlugin\n // will correct this on render if the estimate is off.\n if (nodes.length === 1) {\n const singleNode = nodes[0];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const children = (singleNode as any).children;\n if (children && children.length > 1) {\n const estimatedLineHeight = 24;\n const maxChildren = Math.max(1, Math.floor(bodyHeight / estimatedLineHeight));\n if (maxChildren < children.length) {\n const [keepBlock, overflowBlock] = splitBlockNode(singleNode, maxChildren);\n if (keepBlock && overflowBlock) {\n const keepState = createEditorStateFromNodes([keepBlock]);\n const overflowState = createEditorStateFromNodes([overflowBlock]);\n\n const nextPage = pages[pageIndex + 1];\n if (nextPage) {\n const mergedBody = mergeEditorStates(overflowState, nextPage.bodyState);\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: pages.map((p, i) => {\n if (i === pageIndex) return { ...p, bodyState: keepState };\n if (i === pageIndex + 1) return { ...p, bodyState: mergedBody };\n return p;\n }),\n },\n });\n } else {\n const newPage: PageState = {\n ...createPageFromTemplate({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n }),\n bodyState: overflowState,\n };\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: [\n ...pages.map((p, i) =>\n i === pageIndex ? { ...p, bodyState: keepState } : p,\n ),\n newPage,\n ],\n },\n });\n }\n }\n }\n }\n }\n return;\n }\n\n const fitCount = estimateNodesFitting(page.bodyState, bodyHeight);\n if (fitCount >= nodes.length) return; // Everything fits\n\n const [keepState, overflowState] = splitEditorState(page.bodyState, fitCount);\n\n if (!overflowState) return; // Nothing to overflow\n\n // Get or create the next page\n const nextPage = pages[pageIndex + 1];\n if (nextPage) {\n // Merge overflow into the beginning of the next page\n const mergedBody = mergeEditorStates(overflowState, nextPage.bodyState);\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: pages.map((p, i) => {\n if (i === pageIndex) return { ...p, bodyState: keepState };\n if (i === pageIndex + 1) return { ...p, bodyState: mergedBody };\n return p;\n }),\n },\n });\n } else {\n // Create a new page with overflow content\n const newPage: PageState = {\n ...createPageFromTemplate({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n }),\n bodyState: overflowState,\n };\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: [\n ...pages.map((p, i) =>\n i === pageIndex ? { ...p, bodyState: keepState } : p,\n ),\n newPage,\n ],\n },\n });\n }\n } finally {\n reflowingRef.current = false;\n\n if (pendingReflowRef.current) {\n pendingReflowRef.current = false;\n // Schedule another reflow on next tick\n setTimeout(() => handlePageOverflow(pageIndex), 0);\n }\n }\n },\n [document, dispatch, estimateNodesFitting],\n );\n\n /**\n * Handle underflow — try to pull content from the next page.\n */\n const handlePageUnderflow = useCallback(\n (pageIndex: number) => {\n if (reflowingRef.current) return;\n\n const pages = document.pages;\n const page = pages[pageIndex];\n const nextPage = pages[pageIndex + 1];\n\n if (!page || !nextPage) return;\n\n const nextNodes = getTopLevelNodes(nextPage.bodyState);\n if (nextNodes.length === 0) {\n // Next page is empty — remove it (unless it's the only page)\n if (pages.length > 1) {\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: pages.filter((_, i) => i !== pageIndex + 1),\n },\n });\n }\n return;\n }\n\n // Try to pull the first node from the next page\n const headerH = document.headerFooterEnabled ? page.headerHeight : 0;\n const footerH = document.headerFooterEnabled ? page.footerHeight : 0;\n const bodyHeight = computeBodyHeight(headerH, footerH);\n\n const currentNodes = getTopLevelNodes(page.bodyState);\n const estimatedCurrentHeight = currentNodes.length * 24;\n const remainingSpace = bodyHeight - estimatedCurrentHeight;\n\n if (remainingSpace > 24) {\n // Pull the first node from next page\n const [pulled, remaining] = [nextNodes.slice(0, 1), nextNodes.slice(1)];\n\n const updatedCurrent = mergeEditorStates(\n page.bodyState,\n createEditorStateFromNodes(pulled),\n );\n const updatedNext =\n remaining.length > 0 ? createEditorStateFromNodes(remaining) : null;\n\n const newPages = pages.map((p, i) => {\n if (i === pageIndex) return { ...p, bodyState: updatedCurrent };\n if (i === pageIndex + 1) return { ...p, bodyState: updatedNext };\n return p;\n });\n\n // Remove empty trailing pages\n while (newPages.length > 1) {\n const last = newPages[newPages.length - 1];\n if (getTopLevelNodes(last.bodyState).length === 0) {\n newPages.pop();\n } else {\n break;\n }\n }\n\n dispatch({\n type: 'SET_DOCUMENT',\n document: { ...document, pages: newPages },\n });\n }\n },\n [document, dispatch],\n );\n\n /**\n * Full document reflow — recalculate all pages from scratch.\n * Used after toggle changes or major content operations.\n */\n const reflowAll = useCallback(() => {\n if (reflowingRef.current) return;\n reflowingRef.current = true;\n\n try {\n const pages = document.pages;\n\n // Collect all body content across all pages\n const allNodes = pages.flatMap(p => getTopLevelNodes(p.bodyState));\n if (allNodes.length === 0) {\n // Ensure at least one page\n if (pages.length !== 1) {\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: [pages[0] ?? createEmptyPage()],\n },\n });\n }\n return;\n }\n\n // Distribute nodes across pages\n const newPages: PageState[] = [];\n let remainingNodes = [...allNodes];\n let pageIdx = 0;\n\n while (remainingNodes.length > 0) {\n const existingPage = pages[pageIdx];\n const headerH = document.headerFooterEnabled\n ? (existingPage?.headerHeight ?? 0)\n : 0;\n const footerH = document.headerFooterEnabled\n ? (existingPage?.footerHeight ?? 0)\n : 0;\n const bodyHeight = computeBodyHeight(headerH, footerH);\n const estimatedLineHeight = 24;\n const maxNodes = Math.max(1, Math.floor(bodyHeight / estimatedLineHeight));\n\n const pageNodes = remainingNodes.slice(0, maxNodes);\n remainingNodes = remainingNodes.slice(maxNodes);\n\n const basePage = existingPage ?? createPageFromTemplate({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n });\n newPages.push({\n ...basePage,\n bodyState: createEditorStateFromNodes(pageNodes),\n });\n\n pageIdx++;\n }\n\n dispatch({\n type: 'SET_DOCUMENT',\n document: { ...document, pages: newPages },\n });\n } finally {\n reflowingRef.current = false;\n }\n }, [document, dispatch]);\n\n return {\n handlePageOverflow,\n handlePageUnderflow,\n reflowAll,\n };\n}\n","import type { EditorThemeClasses } from 'lexical';\n\n/**\n * Lexical theme configuration — maps Lexical CSS class names\n * to stable Lex4 class strings for consistent styling.\n */\nexport const lexicalTheme: EditorThemeClasses = {\n root: 'lex4-root',\n paragraph: 'lex4-paragraph',\n heading: {\n h1: 'lex4-heading lex4-heading-h1',\n h2: 'lex4-heading lex4-heading-h2',\n h3: 'lex4-heading lex4-heading-h3',\n h4: 'lex4-heading lex4-heading-h4',\n h5: 'lex4-heading lex4-heading-h5',\n h6: 'lex4-heading lex4-heading-h6',\n },\n text: {\n bold: 'lex4-text-bold',\n italic: 'lex4-text-italic',\n underline: 'lex4-text-underline',\n strikethrough: 'lex4-text-strikethrough',\n underlineStrikethrough: 'lex4-text-underline lex4-text-strikethrough',\n },\n list: {\n nested: {\n listitem: 'lex4-listitem-nested',\n },\n ol: 'lex4-list lex4-list-ordered',\n ul: 'lex4-list lex4-list-unordered',\n listitem: 'lex4-listitem',\n listitemChecked: 'lex4-listitem-checked',\n listitemUnchecked: 'lex4-listitem-unchecked',\n },\n quote: 'lex4-quote',\n};\n","import type { InitialConfigType } from '@lexical/react/LexicalComposer';\nimport type { EditorThemeClasses, Klass, LexicalNode } from 'lexical';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\nimport { ListNode, ListItemNode } from '@lexical/list';\n\nimport { lexicalTheme } from './theme';\n\nexport type EditorMode = 'body' | 'header' | 'footer';\n\nconst DEFAULT_NODES: Klass<LexicalNode>[] = [HeadingNode, QuoteNode, ListNode, ListItemNode];\n\n/**\n * Creates a Lexical editor configuration for the given mode.\n *\n * Each mode gets its own namespace to avoid conflicts when\n * multiple Lexical editors coexist on the same page.\n *\n * @param extraNodes - Additional node classes contributed by extensions\n * @param themeOverrides - Theme class overrides from extensions\n */\nexport function createEditorConfig(\n mode: EditorMode,\n pageId?: string,\n extraNodes: Klass<LexicalNode>[] = [],\n themeOverrides: Partial<EditorThemeClasses> = {},\n): InitialConfigType {\n const namespace = pageId ? `lex4-${mode}-${pageId}` : `lex4-${mode}`;\n\n return {\n namespace,\n theme: { ...lexicalTheme, ...themeOverrides },\n nodes: [...DEFAULT_NODES, ...extraNodes],\n onError: (error: Error) => {\n console.error(`[Lex4 ${mode} editor error]`, error);\n },\n };\n}\n","import React, { useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_LOW, KEY_TAB_COMMAND } from 'lexical';\nimport { indentContent, outdentContent } from '../commands/list-commands';\n\n/**\n * TabIndentPlugin — handles Tab and Shift+Tab for indentation shortcuts.\n *\n * List items use Lexical's native nesting behavior. Regular paragraphs use the\n * editor's first-line indent behavior.\n */\nexport const TabIndentPlugin: React.FC = () => {\n const [editor] = useLexicalComposerContext();\n\n const handleTab = useCallback(\n (event: KeyboardEvent) => {\n event.preventDefault();\n if (event.shiftKey) {\n outdentContent(editor);\n } else {\n indentContent(editor);\n }\n return true;\n },\n [editor],\n );\n\n React.useEffect(() => {\n return editor.registerCommand(KEY_TAB_COMMAND, handleTab, COMMAND_PRIORITY_LOW);\n }, [editor, handleTab]);\n\n return null;\n};\n","import React, { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { $getRoot, $isElementNode, $isParagraphNode, type ElementNode } from 'lexical';\n\nconst FIRST_LINE_INDENT_PX = 40;\n\nfunction visitElements(node: ElementNode, callback: (element: ElementNode) => void): void {\n callback(node);\n\n for (const child of node.getChildren()) {\n if ($isElementNode(child)) {\n visitElements(child, callback);\n }\n }\n}\n\n/**\n * Applies first-line paragraph indentation in the DOM while leaving\n * Lexical's serialized paragraph indent levels intact.\n */\nexport const ParagraphIndentPlugin: React.FC = () => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const syncParagraphIndents = () => editor.getEditorState().read(() => {\n visitElements($getRoot(), node => {\n if (!$isParagraphNode(node)) {\n return;\n }\n\n const element = editor.getElementByKey(node.getKey());\n if (!(element instanceof HTMLElement)) {\n return;\n }\n\n const indent = node.getIndent();\n element.style.paddingInlineStart = '0px';\n element.style.textIndent = indent > 0 ? `${indent * FIRST_LINE_INDENT_PX}px` : '';\n });\n });\n\n syncParagraphIndents();\n\n return editor.registerUpdateListener(() => {\n syncParagraphIndents();\n });\n }, [editor]);\n\n return null;\n};\n","import React from 'react';\n\n/**\n * PastePlugin — placeholder for paste normalization.\n *\n * Overflow detection after paste is handled by the OverflowPlugin\n * which monitors content size changes via ResizeObserver.\n */\nexport const PastePlugin: React.FC = () => {\n return null;\n};\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $createRangeSelectionFromDom,\n $getRoot,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n FOCUS_COMMAND,\n} from 'lexical';\nimport type { LexicalEditor } from 'lexical';\nimport { useDocument } from '../../context/document-context';\nimport type { CaretPosition } from '../../types/history';\nimport { debug } from '../../utils/debug';\n\ninterface ActiveEditorPluginProps {\n pageId: string;\n region: CaretPosition['region'];\n onFocus?: (editor: LexicalEditor) => void;\n}\n\nfunction resolveTextOffset(root: HTMLElement, targetOffset: number): { node: Node; offset: number } {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n let remaining = targetOffset;\n let currentNode = walker.nextNode();\n let lastTextNode: Node | null = null;\n\n while (currentNode) {\n const textLength = currentNode.textContent?.length ?? 0;\n if (remaining <= textLength) {\n return { node: currentNode, offset: remaining };\n }\n\n remaining -= textLength;\n lastTextNode = currentNode;\n currentNode = walker.nextNode();\n }\n\n if (lastTextNode) {\n return {\n node: lastTextNode,\n offset: lastTextNode.textContent?.length ?? 0,\n };\n }\n\n return {\n node: root,\n offset: root.childNodes.length,\n };\n}\n\n/**\n * ActiveEditorPlugin — Registers the editor in the document context on focus.\n *\n * This enables the toolbar to dispatch commands (bold, italic, etc.)\n * to whichever editor the user is currently editing.\n */\nexport const ActiveEditorPlugin: React.FC<ActiveEditorPluginProps> = ({\n pageId,\n region,\n onFocus,\n}) => {\n const [editor] = useLexicalComposerContext();\n const {\n consumePendingCaretPosition,\n consumePendingFocusAtEnd,\n focusAtEndVersion,\n setActiveEditor,\n setActivePageId,\n } = useDocument();\n\n useEffect(() => {\n const caretPosition: CaretPosition = { pageId, region };\n const selectionToRestore = consumePendingCaretPosition(caretPosition);\n if (selectionToRestore === undefined) {\n return;\n }\n\n requestAnimationFrame(() => {\n setActivePageId(pageId);\n setActiveEditor(editor, caretPosition);\n editor.focus();\n if (!selectionToRestore) {\n return;\n }\n\n requestAnimationFrame(() => {\n const rootElement = editor.getRootElement();\n const domSelection = window.getSelection();\n if (!rootElement || !domSelection) {\n return;\n }\n\n const anchorPoint = resolveTextOffset(rootElement, selectionToRestore.anchorTextOffset);\n const focusPoint = resolveTextOffset(rootElement, selectionToRestore.focusTextOffset);\n const range = document.createRange();\n range.setStart(anchorPoint.node, anchorPoint.offset);\n range.setEnd(focusPoint.node, focusPoint.offset);\n\n domSelection.removeAllRanges();\n domSelection.addRange(range);\n\n editor.update(() => {\n const nextSelection = $createRangeSelectionFromDom(window.getSelection(), editor);\n if (nextSelection) {\n $setSelection(nextSelection);\n }\n });\n });\n });\n }, [consumePendingCaretPosition, editor, pageId, region, setActiveEditor, setActivePageId]);\n\n useEffect(() => {\n const caretPosition: CaretPosition = { pageId, region };\n if (!consumePendingFocusAtEnd(caretPosition)) {\n return;\n }\n\n requestAnimationFrame(() => {\n setActivePageId(pageId);\n setActiveEditor(editor, caretPosition);\n editor.focus(() => {\n editor.update(() => {\n $getRoot().selectEnd();\n });\n });\n });\n }, [\n consumePendingFocusAtEnd,\n editor,\n focusAtEndVersion,\n pageId,\n region,\n setActiveEditor,\n setActivePageId,\n ]);\n\n useEffect(() => {\n const caretPosition: CaretPosition = { pageId, region };\n const markEditorActive = () => {\n setActivePageId(pageId);\n setActiveEditor(editor, caretPosition);\n onFocus?.(editor);\n };\n\n return editor.registerRootListener((rootElement, prevRootElement) => {\n prevRootElement?.removeEventListener('focusin', markEditorActive);\n prevRootElement?.removeEventListener('mousedown', markEditorActive);\n prevRootElement?.removeEventListener('pointerdown', markEditorActive);\n rootElement?.addEventListener('focusin', markEditorActive);\n rootElement?.addEventListener('mousedown', markEditorActive);\n rootElement?.addEventListener('pointerdown', markEditorActive);\n });\n }, [editor, onFocus, pageId, region, setActiveEditor, setActivePageId]);\n\n useEffect(() => {\n return editor.registerCommand(\n FOCUS_COMMAND,\n () => {\n debug('focus', `editor focused (ns=${editor.getKey()})`);\n setActivePageId(pageId);\n setActiveEditor(editor, { pageId, region });\n onFocus?.(editor);\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, onFocus, pageId, region, setActiveEditor, setActivePageId]);\n\n return null;\n};\n","import {\n $getRoot,\n $isElementNode,\n $isTextNode,\n $getNearestNodeFromDOMNode,\n $splitNode,\n type LexicalNode,\n type SerializedLexicalNode,\n type ElementNode,\n} from 'lexical';\nimport { $isListNode } from '@lexical/list';\nimport { debug, debugWarn } from '../../utils/debug';\n\n/**\n * Result of finding a split point inside a block element.\n */\ninterface DomSplitPoint {\n /** The DOM Text node containing the split offset */\n textNode: Text;\n /** Character offset within the text node */\n offset: number;\n}\n\n/**\n * Finds the character position inside a block element where content\n * crosses the available height boundary.\n *\n * Uses a binary search with Range.getBoundingClientRect() for efficiency.\n * Returns the offset backed up to the nearest word boundary.\n *\n * @returns The DOM text node and offset, or null if no valid split found\n */\nexport function findMidBlockSplitPoint(\n blockElement: HTMLElement,\n availableHeight: number,\n): DomSplitPoint | null {\n const blockRect = blockElement.getBoundingClientRect();\n const maxBottom = blockRect.top + availableHeight;\n\n // Collect all text nodes in the block\n const textNodes: Text[] = [];\n const walker = document.createTreeWalker(blockElement, NodeFilter.SHOW_TEXT);\n let walkNode: Text | null;\n while ((walkNode = walker.nextNode() as Text | null)) {\n if (walkNode.length > 0) {\n textNodes.push(walkNode);\n }\n }\n\n if (textNodes.length === 0) return null;\n\n // Find the text node that contains the split boundary\n const range = document.createRange();\n\n for (const textNode of textNodes) {\n // Quick check: does this text node cross the boundary?\n range.selectNodeContents(textNode);\n const nodeRect = range.getBoundingClientRect();\n\n if (nodeRect.bottom <= maxBottom) {\n continue; // Entire text node fits\n }\n\n if (nodeRect.top >= maxBottom) {\n // This text node starts after the boundary — split at offset 0\n return backupToWordBoundary(textNode, 0);\n }\n\n // This text node crosses the boundary — binary search for exact offset\n let low = 0;\n let high = textNode.length;\n\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n range.setStart(textNode, 0);\n range.setEnd(textNode, mid + 1);\n const testRect = range.getBoundingClientRect();\n\n if (testRect.bottom > maxBottom) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // 'low' is the first character that doesn't fit\n return backupToWordBoundary(textNode, low);\n }\n\n return null;\n}\n\n/**\n * Backs up a split offset to the nearest word boundary (whitespace).\n * Ensures at least one character remains on each side.\n */\nfunction backupToWordBoundary(\n textNode: Text,\n offset: number,\n): DomSplitPoint | null {\n const text = textNode.textContent || '';\n if (offset <= 0 || offset >= text.length) {\n // Can't back up — split at the raw offset if valid\n if (offset > 0 && offset < text.length) {\n return { textNode, offset };\n }\n // offset is at an edge — try the raw value\n if (offset > 0) return { textNode, offset };\n return null;\n }\n\n // Scan backwards for whitespace\n let adjusted = offset;\n while (adjusted > 0 && !/\\s/.test(text[adjusted - 1])) {\n adjusted--;\n }\n\n // If backing up to 0 would leave nothing on this page, use original offset\n if (adjusted <= 0) {\n adjusted = offset;\n }\n\n return { textNode, offset: adjusted };\n}\n\n/**\n * Recursively serializes a Lexical node and all its children.\n */\nfunction serializeNodeTree(node: LexicalNode): SerializedLexicalNode {\n const json = node.exportJSON();\n if ($isElementNode(node)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (json as any).children = node.getChildren().map(serializeNodeTree);\n }\n return json;\n}\n\n/**\n * Finds the split point for a ListNode by checking which ListItem\n * crosses the height boundary.\n *\n * @returns The child index to split at, or -1 if no valid split\n */\nfunction findListSplitIndex(\n listElement: HTMLElement,\n availableHeight: number,\n): number {\n const listRect = listElement.getBoundingClientRect();\n const maxBottom = listRect.top + availableHeight;\n const children = Array.from(listElement.children) as HTMLElement[];\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const childRect = child.getBoundingClientRect();\n if (childRect.bottom > maxBottom && i > 0) {\n return i;\n }\n }\n\n return -1;\n}\n\n/**\n * Performs a mid-block split on the first overflowing block in the editor.\n *\n * Handles two cases:\n * 1. Paragraph/Heading: splits at a text offset using Range measurement\n * 2. List: splits at a ListItem boundary\n *\n * Must be called inside an editor.update() context.\n *\n * @returns Serialized overflow nodes, or null if split wasn't possible\n */\nexport function performMidBlockSplit(\n rootElement: HTMLElement,\n availableHeight: number,\n overflowBlockIndex: number,\n): SerializedLexicalNode[] | null {\n const root = $getRoot();\n const allChildren = root.getChildren();\n const blockNode = allChildren[overflowBlockIndex];\n\n if (!blockNode || !$isElementNode(blockNode)) {\n debugWarn('overflow', 'target node is not an ElementNode');\n return null;\n }\n\n const blockElements = Array.from(rootElement.children) as HTMLElement[];\n const blockElement = blockElements[overflowBlockIndex];\n if (!blockElement) {\n debugWarn('overflow', 'no DOM element for block index');\n return null;\n }\n\n // Compute available height for this specific block\n const blockTop = blockElement.offsetTop;\n const heightForBlock = availableHeight - blockTop;\n\n if (heightForBlock <= 0) {\n debugWarn('overflow', 'no space for block');\n return null;\n }\n\n // Try list splitting first\n if ($isListNode(blockNode)) {\n return splitListNode(blockNode as ElementNode, blockElement, heightForBlock);\n }\n\n // Paragraph/Heading splitting via text measurement\n return splitParagraphNode(blockNode as ElementNode, blockElement, heightForBlock);\n}\n\n/**\n * Splits a ListNode at a ListItem boundary.\n */\nfunction splitListNode(\n listNode: ElementNode,\n listElement: HTMLElement,\n availableHeight: number,\n): SerializedLexicalNode[] | null {\n const splitIndex = findListSplitIndex(listElement, availableHeight);\n if (splitIndex <= 0) {\n debug('overflow', 'cannot split list — first item exceeds height');\n return null;\n }\n\n const [, overflowList] = $splitNode(listNode, splitIndex);\n\n // Serialize the overflow list and all subsequent siblings\n const overflowNodes: SerializedLexicalNode[] = [];\n const toRemove: LexicalNode[] = [];\n\n overflowNodes.push(serializeNodeTree(overflowList));\n toRemove.push(overflowList);\n\n // Collect remaining siblings after the overflow list\n let nextSibling = overflowList.getNextSibling();\n while (nextSibling) {\n overflowNodes.push(serializeNodeTree(nextSibling));\n toRemove.push(nextSibling);\n nextSibling = nextSibling.getNextSibling();\n }\n\n for (const node of toRemove) {\n node.remove();\n }\n\n debug('overflow', `split list at item ${splitIndex}, extracted ${overflowNodes.length} overflow nodes`);\n return overflowNodes;\n}\n\n/**\n * Splits a paragraph or heading node at a text boundary.\n */\nfunction splitParagraphNode(\n blockNode: ElementNode,\n blockElement: HTMLElement,\n availableHeight: number,\n): SerializedLexicalNode[] | null {\n const splitPoint = findMidBlockSplitPoint(blockElement, availableHeight);\n if (!splitPoint) {\n debug('overflow', 'no valid split point found in paragraph');\n return null;\n }\n\n // Map DOM text node to Lexical TextNode\n const lexicalNode = $getNearestNodeFromDOMNode(splitPoint.textNode);\n if (!lexicalNode || !$isTextNode(lexicalNode)) {\n debugWarn('overflow', 'could not map DOM text node to Lexical TextNode');\n return null;\n }\n\n // Split the text node\n const [, afterText] = lexicalNode.splitText(splitPoint.offset);\n if (!afterText) {\n debugWarn('overflow', 'splitText returned no second half');\n return null;\n }\n\n // Find afterText's index in the parent\n const parent = afterText.getParent();\n if (!parent || !$isElementNode(parent)) {\n debugWarn('overflow', 'split text has no element parent');\n return null;\n }\n\n // Walk up from the text to find the direct child of blockNode\n let directChild: LexicalNode = afterText;\n let directChildParent = parent;\n\n while (directChildParent && directChildParent.getKey() !== blockNode.getKey()) {\n directChild = directChildParent;\n const next = directChildParent.getParent();\n if (!next || !$isElementNode(next)) {\n debugWarn('overflow', 'could not find block node in parent chain');\n return null;\n }\n directChildParent = next;\n }\n\n // Now directChild is the child of blockNode that contains (or is) afterText\n const splitChildIndex = blockNode.getChildren().indexOf(directChild);\n\n if (splitChildIndex <= 0) {\n debug('overflow', 'split index is 0 or not found — nothing to keep on this page');\n return null;\n }\n\n // If the direct child is not afterText itself, we need to split intermediate nodes\n if (directChild !== afterText) {\n // Split each level from the text's parent up to (but not including) blockNode\n let current: ElementNode = parent;\n let childToSplitAt: LexicalNode = afterText;\n\n while (current.getKey() !== blockNode.getKey()) {\n const childIdx = current.getChildren().indexOf(childToSplitAt);\n if (childIdx > 0) {\n $splitNode(current, childIdx);\n }\n childToSplitAt = current;\n const next = current.getParent();\n if (!next || !$isElementNode(next)) break;\n current = next;\n }\n }\n\n // Re-find the split index after potential intermediate splits\n // Find the child of blockNode that contains afterText\n let finalSplitChild: LexicalNode = afterText;\n let p = afterText.getParent();\n while (p && p.getKey() !== blockNode.getKey()) {\n finalSplitChild = p;\n p = p.getParent() as ElementNode | null;\n }\n const finalSplitIndex = blockNode.getChildren().indexOf(finalSplitChild);\n\n if (finalSplitIndex <= 0) {\n debug('overflow', 'final split index is 0 or not found — nothing to keep on this page');\n return null;\n }\n\n const [, overflowBlock] = $splitNode(blockNode, finalSplitIndex);\n\n // Serialize the overflow block and any subsequent nodes\n const overflowNodes: SerializedLexicalNode[] = [];\n const toRemove: LexicalNode[] = [];\n\n overflowNodes.push(serializeNodeTree(overflowBlock));\n toRemove.push(overflowBlock);\n\n // Collect remaining siblings after the split\n let nextSibling = overflowBlock.getNextSibling();\n while (nextSibling) {\n overflowNodes.push(serializeNodeTree(nextSibling));\n toRemove.push(nextSibling);\n nextSibling = nextSibling.getNextSibling();\n }\n\n for (const node of toRemove) {\n node.remove();\n }\n\n debug(\n 'overflow',\n `split paragraph at offset ${splitPoint.offset}, extracted ${overflowNodes.length} overflow nodes`,\n );\n return overflowNodes;\n}\n","import { useEffect, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getRoot,\n $isElementNode,\n type LexicalNode,\n type SerializedEditorState,\n type SerializedLexicalNode,\n} from 'lexical';\nimport { debug, debugWarn } from '../../utils/debug';\nimport { performMidBlockSplit } from '../utils/mid-block-split';\n\n/**\n * Recursively serializes a Lexical node and all its children.\n * ElementNode.exportJSON() returns children: [] by default —\n * the recursive walk must be done manually.\n */\nfunction serializeNodeTree(node: LexicalNode): SerializedLexicalNode {\n const json = node.exportJSON();\n if ($isElementNode(node)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (json as any).children = node.getChildren().map(serializeNodeTree);\n }\n return json;\n}\n\ninterface OverflowPluginProps {\n /** Called with the serialized overflow content that must go to the next page */\n onOverflow: (\n overflowContent: SerializedEditorState,\n cause: 'paste' | 'content',\n ) => void;\n}\n\n/** Debounce delay for typing-triggered overflow checks (ms) */\nconst OVERFLOW_DEBOUNCE_MS = 300;\n\n/**\n * OverflowPlugin — Detects content overflow inside a Lexical editor\n * and automatically extracts overflow nodes.\n *\n * Uses registerRootListener to reliably get the root element (handles\n * the case where the root is not yet available on first render).\n *\n * Measures child element positions via getBoundingClientRect() relative\n * to the container, which works regardless of CSS overflow settings.\n *\n * Debounces overflow checks during normal typing (300ms) to avoid\n * extracting only the empty trailing paragraph. Paste and external\n * state changes (e.g. setEditorState) trigger immediate checks.\n */\nexport const OverflowPlugin: React.FC<OverflowPluginProps> = ({\n onOverflow,\n}) => {\n const [editor] = useLexicalComposerContext();\n const processingRef = useRef(false);\n const onOverflowRef = useRef(onOverflow);\n onOverflowRef.current = onOverflow;\n\n useEffect(() => {\n let observer: ResizeObserver | null = null;\n let unregisterUpdateListener: (() => void) | null = null;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const checkOverflow = (\n rootElement: HTMLElement,\n container: HTMLElement,\n cause: 'paste' | 'content',\n ) => {\n if (processingRef.current) return;\n\n const availableHeight = container.clientHeight;\n if (availableHeight <= 0) return;\n\n // Use scrollHeight for reliable overflow detection — unaffected by\n // scroll position (getBoundingClientRect is affected when the browser\n // scrolls overflow:hidden containers to follow the cursor after paste).\n const contentHeight = rootElement.scrollHeight;\n\n // No overflow if all content fits (+2px tolerance for sub-pixel rounding)\n if (contentHeight <= availableHeight + 2) return;\n\n const children = Array.from(rootElement.children) as HTMLElement[];\n if (children.length === 0) return;\n\n if (children.length <= 1) {\n debug('overflow', `single block overflows (content=${contentHeight}px > available=${availableHeight}px) — attempting mid-block split`);\n\n processingRef.current = true;\n\n editor.update(\n () => {\n const overflowNodes = performMidBlockSplit(rootElement, availableHeight, 0);\n if (!overflowNodes || overflowNodes.length === 0) {\n debug('overflow', 'mid-block split not possible for single block');\n processingRef.current = false;\n return;\n }\n\n const overflowState: SerializedEditorState = {\n root: {\n children: overflowNodes,\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState;\n\n debug('overflow', `mid-block split extracted ${overflowNodes.length} overflow nodes from single block`);\n\n setTimeout(() => {\n onOverflowRef.current(overflowState, cause);\n processingRef.current = false;\n }, 0);\n },\n { tag: 'overflow-split' },\n );\n return;\n }\n\n processingRef.current = true;\n\n debug('overflow', `OVERFLOW detected: content=${contentHeight}px available=${availableHeight}px children=${children.length}`);\n\n // Find the first child whose bottom exceeds the available height.\n // Uses offsetTop (relative to offsetParent, unaffected by scroll)\n // instead of getBoundingClientRect (which shifts with scroll).\n let splitIndex = children.length;\n let firstBlockOverflows = false;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const childBottom = child.offsetTop + child.offsetHeight;\n\n if (childBottom > availableHeight) {\n if (i === 0) {\n // First block itself overflows — attempt mid-block split on it,\n // then fall through to extract remaining blocks after it\n firstBlockOverflows = true;\n splitIndex = 1; // everything after block 0 overflows\n } else {\n splitIndex = i;\n }\n debug('overflow', `split at index ${i === 0 ? '0 (mid-block)' : i} (childBottom=${childBottom}px > ${availableHeight}px)`);\n break;\n }\n }\n\n if (splitIndex >= children.length) {\n debugWarn('overflow', 'no valid split point found — all children fit individually');\n processingRef.current = false;\n return;\n }\n\n editor.update(\n () => {\n const root = $getRoot();\n const allChildren = root.getChildren();\n\n if (splitIndex >= allChildren.length) {\n debugWarn('overflow', `splitIndex=${splitIndex} >= Lexical children=${allChildren.length} — mismatch`);\n processingRef.current = false;\n return;\n }\n\n let overflowNodes: SerializedLexicalNode[] = [];\n\n // If the first block itself overflows, try mid-block split on it\n if (firstBlockOverflows) {\n const midBlockOverflow = performMidBlockSplit(rootElement, availableHeight, 0);\n if (midBlockOverflow && midBlockOverflow.length > 0) {\n overflowNodes.push(...midBlockOverflow);\n debug('overflow', `mid-block split on first block extracted ${midBlockOverflow.length} nodes`);\n } else {\n debug('overflow', 'mid-block split failed on first block — keeping it whole');\n }\n\n // Serialize and remove remaining blocks after the first\n const freshChildren = root.getChildren();\n const toRemove = freshChildren.slice(1);\n for (const node of toRemove) {\n overflowNodes.push(serializeNodeTree(node));\n }\n for (const node of toRemove) {\n node.remove();\n }\n } else {\n const toRemove = allChildren.slice(splitIndex);\n for (const node of toRemove) {\n overflowNodes.push(serializeNodeTree(node));\n }\n for (const node of toRemove) {\n node.remove();\n }\n }\n\n if (overflowNodes.length === 0) {\n processingRef.current = false;\n return;\n }\n\n debug('overflow', `extracted ${overflowNodes.length} overflow nodes total`);\n\n const overflowState: SerializedEditorState = {\n root: {\n children: overflowNodes,\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState;\n\n setTimeout(() => {\n onOverflowRef.current(overflowState, cause);\n processingRef.current = false;\n }, 0);\n },\n { tag: 'overflow-split' },\n );\n };\n\n const setupObservers = (rootElement: HTMLElement) => {\n // Clean up any previous observers\n if (observer) observer.disconnect();\n if (unregisterUpdateListener) unregisterUpdateListener();\n if (debounceTimer) clearTimeout(debounceTimer);\n\n const container = rootElement.closest('.lex4-page-body') as HTMLElement | null;\n if (!container) {\n debugWarn('overflow', 'no .lex4-page-body container found');\n return;\n }\n\n debug('overflow', `observers attached (ns=${editor.getKey()})`);\n\n const immediateCheck = () => {\n requestAnimationFrame(() => checkOverflow(rootElement, container, 'content'));\n };\n\n const pasteCheck = () => {\n requestAnimationFrame(() => checkOverflow(rootElement, container, 'paste'));\n };\n\n const debouncedCheck = () => {\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(immediateCheck, OVERFLOW_DEBOUNCE_MS);\n };\n\n // ResizeObserver fires on actual layout changes — debounce to\n // avoid constant checks during typing\n observer = new ResizeObserver(debouncedCheck);\n observer.observe(rootElement);\n observer.observe(container);\n\n unregisterUpdateListener = editor.registerUpdateListener(({ tags }) => {\n if (tags.has('overflow-split')) return;\n\n // Paste and external state changes trigger immediate overflow check.\n // Normal typing is debounced to avoid extracting only the cursor paragraph.\n if (tags.has('paste')) {\n debug('overflow', `paste check (tags=${Array.from(tags).join(',')})`);\n pasteCheck();\n } else if (tags.has('collaboration') || tags.has('historic')) {\n debug('overflow', `immediate check (tags=${Array.from(tags).join(',')})`);\n immediateCheck();\n } else {\n debouncedCheck();\n }\n });\n\n // Initial check after setup (immediate — handles mount with initial content)\n immediateCheck();\n };\n\n // registerRootListener fires immediately with current root (if any)\n // and again whenever the root element changes — handles the case\n // where getRootElement() returns null on first render\n const unregisterRootListener = editor.registerRootListener(\n (rootElement: HTMLElement | null) => {\n if (rootElement) {\n debug('overflow', `rootListener: root available (ns=${editor.getKey()})`);\n setupObservers(rootElement);\n } else {\n debug('overflow', `rootListener: root detached (ns=${editor.getKey()})`);\n if (observer) observer.disconnect();\n if (unregisterUpdateListener) unregisterUpdateListener();\n if (debounceTimer) clearTimeout(debounceTimer);\n observer = null;\n unregisterUpdateListener = null;\n debounceTimer = null;\n }\n },\n );\n\n return () => {\n unregisterRootListener();\n if (observer) observer.disconnect();\n if (unregisterUpdateListener) unregisterUpdateListener();\n if (debounceTimer) clearTimeout(debounceTimer);\n };\n }, [editor]);\n\n return null;\n};\n","import { useEffect, useMemo } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n COMMAND_PRIORITY_LOW,\n CONTROLLED_TEXT_INSERTION_COMMAND,\n FORMAT_ELEMENT_COMMAND,\n FORMAT_TEXT_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_DOWN_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n} from 'lexical';\n\nimport { useDocument } from '../../context/document-context';\nimport { useTranslations, interpolate } from '../../i18n';\nimport type { HistoryActionDescriptor, HistoryRegion } from '../../types/history';\n\ninterface HistoryCapturePluginProps {\n pageId: string;\n region: Exclude<HistoryRegion, 'document'>;\n}\n\nexport const HistoryCapturePlugin: React.FC<HistoryCapturePluginProps> = ({ pageId, region }) => {\n const [editor] = useLexicalComposerContext();\n const { document, queueHistoryAction } = useDocument();\n const t = useTranslations();\n\n const context = useMemo(() => {\n const pageNumber = document.pages.findIndex(page => page.id === pageId);\n return {\n pageNumber: pageNumber >= 0 ? pageNumber + 1 : null,\n source: region,\n };\n }, [document.pages, pageId, region]);\n\n const createPageLabel = useMemo(() => {\n return (r: HistoryCapturePluginProps['region'], pageNumber: number | null): string => {\n if (r === 'body') {\n return pageNumber ? interpolate(t.regions.page, { page: pageNumber }) : t.regions.body;\n }\n const regionLabel = r === 'header' ? t.regions.header : t.regions.footer;\n return pageNumber\n ? `${regionLabel} ${interpolate(t.regions.page, { page: pageNumber })}`\n : regionLabel;\n };\n }, [t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n CONTROLLED_TEXT_INSERTION_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.typedText));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (event.metaKey || event.ctrlKey || event.altKey) {\n return false;\n }\n\n if (event.key.length !== 1) {\n return false;\n }\n\n queueHistoryAction(buildDescriptor(t.historyLabels.typedText));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n const text = event.clipboardData?.getData('text/plain') ?? '';\n if (text.trim().length === 0) {\n return false;\n }\n queueHistoryAction(buildDescriptor(t.historyLabels.pastedContent));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.insertedLineBreak));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.deletedBackward));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_DELETE_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.deletedForward));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n FORMAT_TEXT_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.formattedText));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n FORMAT_ELEMENT_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.formattedParagraph));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n return null;\n};\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n COMMAND_PRIORITY_HIGH,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_DOWN_COMMAND,\n} from 'lexical';\n\ninterface PageBoundaryPluginProps {\n onBackspaceAtStart: () => void;\n onDeleteAtEnd: () => void;\n onMoveToPreviousPage: () => void;\n onMoveToNextPage: () => void;\n}\n\ninterface CollapsedTextPosition {\n textOffset: number;\n totalTextLength: number;\n}\n\nfunction getCollapsedTextPosition(rootElement: HTMLElement | null): CollapsedTextPosition | null {\n const domSelection = window.getSelection();\n if (!rootElement || !domSelection || domSelection.rangeCount === 0 || !domSelection.isCollapsed) {\n return null;\n }\n\n const range = domSelection.getRangeAt(0);\n if (!rootElement.contains(range.startContainer)) {\n return null;\n }\n\n const offsetRange = document.createRange();\n offsetRange.setStart(rootElement, 0);\n offsetRange.setEnd(range.startContainer, range.startOffset);\n\n const contentRange = document.createRange();\n contentRange.selectNodeContents(rootElement);\n\n return {\n textOffset: offsetRange.toString().length,\n totalTextLength: contentRange.toString().length,\n };\n}\n\nexport const PageBoundaryPlugin: React.FC<PageBoundaryPluginProps> = ({\n onBackspaceAtStart,\n onDeleteAtEnd,\n onMoveToPreviousPage,\n onMoveToNextPage,\n}) => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n () => {\n const position = getCollapsedTextPosition(editor.getRootElement());\n if (!position || position.textOffset !== 0) {\n return false;\n }\n\n onBackspaceAtStart();\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n ), [editor, onBackspaceAtStart]);\n\n useEffect(() => editor.registerCommand(\n KEY_DELETE_COMMAND,\n () => {\n const position = getCollapsedTextPosition(editor.getRootElement());\n if (!position || position.textOffset !== position.totalTextLength) {\n return false;\n }\n\n onDeleteAtEnd();\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n ), [editor, onDeleteAtEnd]);\n\n useEffect(() => editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {\n return false;\n }\n\n const position = getCollapsedTextPosition(editor.getRootElement());\n if (!position) {\n return false;\n }\n\n if ((event.key === 'ArrowLeft' || event.key === 'ArrowUp') && position.textOffset === 0) {\n event.preventDefault();\n onMoveToPreviousPage();\n return true;\n }\n\n if (\n (event.key === 'ArrowRight' || event.key === 'ArrowDown')\n && position.textOffset === position.totalTextLength\n ) {\n event.preventDefault();\n onMoveToNextPage();\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_HIGH,\n ), [editor, onMoveToNextPage, onMoveToPreviousPage]);\n\n return null;\n};\n","import React, { useCallback, useEffect, useMemo } from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { ListPlugin } from '@lexical/react/LexicalListPlugin';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport type { EditorState, SerializedEditorState } from 'lexical';\n\nimport { createEditorConfig } from '../lexical/editor-setup';\nimport { TabIndentPlugin } from '../lexical/plugins/tab-indent-plugin';\nimport { ParagraphIndentPlugin } from '../lexical/plugins/paragraph-indent-plugin';\nimport { PastePlugin } from '../lexical/plugins/paste-plugin';\nimport { ActiveEditorPlugin } from '../lexical/plugins/active-editor-plugin';\nimport { OverflowPlugin } from '../lexical/plugins/overflow-plugin';\nimport { HistoryCapturePlugin } from '../lexical/plugins/history-capture-plugin';\nimport { PageBoundaryPlugin } from '../lexical/plugins/page-boundary-plugin';\nimport { useDocument } from '../context/document-context';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations } from '../i18n';\nimport { debug, shortId } from '../utils/debug';\n\ninterface PageBodyProps {\n pageId: string;\n initialBodyState?: SerializedEditorState | null;\n onBodyChange?: (state: SerializedEditorState) => void;\n onOverflow?: (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => void;\n onFocus?: () => void;\n onBackspaceAtStart?: () => void;\n onDeleteAtEnd?: () => void;\n onMoveToPreviousPage?: () => void;\n onMoveToNextPage?: () => void;\n readOnly?: boolean;\n}\n\n/**\n * EditorRegistryPlugin — Registers the editor in the document-level\n * editor registry so other pages can directly push content into it.\n */\nconst EditorRegistryPlugin: React.FC<{ pageId: string }> = ({ pageId }) => {\n const [editor] = useLexicalComposerContext();\n const { editorRegistry } = useDocument();\n\n useEffect(() => {\n editorRegistry.register(pageId, editor);\n debug('registry', `registered editor for page ${shortId(pageId)}`);\n return () => {\n editorRegistry.unregister(pageId, editor);\n debug('registry', `unregistered editor for page ${shortId(pageId)}`);\n };\n }, [editor, pageId, editorRegistry]);\n\n return null;\n};\n\n/**\n * PageBody — Lexical editor instance for one page's body content.\n *\n * Each page gets its own Lexical editor. The OverflowPlugin\n * handles splitting content when it exceeds the available height.\n *\n * Extension-contributed body plugins are rendered inside the LexicalComposer.\n */\nexport const PageBody: React.FC<PageBodyProps> = ({\n pageId,\n initialBodyState,\n onBodyChange,\n onOverflow,\n onFocus,\n onBackspaceAtStart,\n onDeleteAtEnd,\n onMoveToPreviousPage,\n onMoveToNextPage,\n readOnly = false,\n}) => {\n const { nodes, bodyPlugins, themeOverrides } = useExtensions();\n const t = useTranslations();\n\n const config = useMemo(\n () => {\n const baseConfig = {\n ...createEditorConfig('body', pageId, nodes, themeOverrides),\n editable: !readOnly,\n };\n\n if (initialBodyState) {\n debug('page', `PageBody ${shortId(pageId)}: initializing with ${initialBodyState.root?.children?.length ?? 0} children`);\n return {\n ...baseConfig,\n editorState: JSON.stringify(initialBodyState),\n };\n }\n\n debug('page', `PageBody ${shortId(pageId)}: initializing empty`);\n return baseConfig;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally only use initialBodyState at mount time\n [pageId, readOnly, nodes, themeOverrides],\n );\n\n const handleChange = useCallback(\n (editorState: EditorState) => {\n const serialized = editorState.toJSON();\n onBodyChange?.(serialized);\n },\n [onBodyChange],\n );\n\n const handleOverflow = useCallback(\n (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => {\n debug('page', `PageBody ${shortId(pageId)}: overflow callback fired with ${overflowContent.root?.children?.length ?? 0} children`);\n onOverflow?.(overflowContent, cause);\n },\n [onOverflow, pageId],\n );\n\n return (\n <div\n className=\"lex4-page-body\"\n data-testid={`page-body-${pageId}`}\n onFocus={onFocus}\n >\n <LexicalComposer initialConfig={config}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n className=\"lex4-page-body-editable\"\n />\n }\n placeholder={\n <div className=\"lex4-page-placeholder\">\n {t.body.placeholder}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <ListPlugin />\n <ParagraphIndentPlugin />\n <TabIndentPlugin />\n <PastePlugin />\n <EditorRegistryPlugin pageId={pageId} />\n <ActiveEditorPlugin pageId={pageId} region=\"body\" />\n {!readOnly && <HistoryCapturePlugin pageId={pageId} region=\"body\" />}\n {!readOnly && onBackspaceAtStart && onDeleteAtEnd && onMoveToPreviousPage && onMoveToNextPage && (\n <PageBoundaryPlugin\n onBackspaceAtStart={onBackspaceAtStart}\n onDeleteAtEnd={onDeleteAtEnd}\n onMoveToPreviousPage={onMoveToPreviousPage}\n onMoveToNextPage={onMoveToNextPage}\n />\n )}\n <OverflowPlugin onOverflow={handleOverflow} />\n {bodyPlugins.map((Plugin, idx) => (\n <Plugin key={idx} />\n ))}\n <OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n </LexicalComposer>\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_CRITICAL, KEY_ENTER_COMMAND, PASTE_COMMAND } from 'lexical';\nimport { debug } from '../../utils/debug';\n\n/**\n * HeightLimitPlugin — Prevents editing that would push content beyond\n * a maximum height. Instead of clipping overflow, this plugin reverts\n * any change that makes the editor's scrollHeight exceed maxHeight.\n *\n * Works by:\n * 1. Blocking Enter key when already at max height\n * 2. Saving editor state before each update, reverting if scrollHeight exceeds limit\n * 3. Truncating paste content that would overflow\n */\nexport function HeightLimitPlugin({ maxHeight, channel }: { maxHeight: number; channel: 'header' | 'footer' }) {\n const [editor] = useLexicalComposerContext();\n const lastGoodStateRef = useRef<string | null>(null);\n const isRevertingRef = useRef(false);\n\n useEffect(() => {\n // Save initial state as \"last good\"\n lastGoodStateRef.current = JSON.stringify(editor.getEditorState().toJSON());\n\n // Intercept Enter key when at max height\n const removeEnterCommand = editor.registerCommand(\n KEY_ENTER_COMMAND,\n () => {\n const root = editor.getRootElement();\n if (root && root.scrollHeight >= maxHeight) {\n debug(channel, `blocked Enter — scrollHeight ${root.scrollHeight}px >= max ${maxHeight}px`);\n return true; // Prevent the Enter\n }\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n // Intercept paste when at max height\n const removePasteCommand = editor.registerCommand(\n PASTE_COMMAND,\n () => {\n const root = editor.getRootElement();\n if (root && root.scrollHeight >= maxHeight) {\n debug(channel, `blocked paste — scrollHeight ${root.scrollHeight}px >= max ${maxHeight}px`);\n return true; // Prevent the paste\n }\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n // After each update, check if content exceeds max height and revert if so\n const removeUpdateListener = editor.registerUpdateListener(({ editorState, prevEditorState }) => {\n if (isRevertingRef.current) return;\n\n const root = editor.getRootElement();\n if (!root) return;\n\n // Use requestAnimationFrame to read DOM after paint\n requestAnimationFrame(() => {\n if (root.scrollHeight > maxHeight) {\n debug(channel, `reverting — scrollHeight ${root.scrollHeight}px > max ${maxHeight}px`);\n const restoreState =\n JSON.stringify(prevEditorState.toJSON()) || lastGoodStateRef.current;\n if (!restoreState) {\n return;\n }\n isRevertingRef.current = true;\n\n editor.setEditorState(editor.parseEditorState(restoreState));\n\n isRevertingRef.current = false;\n } else {\n // Content fits — save as last good state\n lastGoodStateRef.current = JSON.stringify(editorState.toJSON());\n }\n });\n });\n\n return () => {\n removeEnterCommand();\n removePasteCommand();\n removeUpdateListener();\n };\n }, [editor, maxHeight, channel]);\n\n return null;\n}\n","import React, { useCallback, useMemo, useRef } from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';\nimport type { EditorState, SerializedEditorState } from 'lexical';\n\nimport { createEditorConfig } from '../lexical/editor-setup';\nimport { MAX_HEADER_HEIGHT_PX } from '../constants/dimensions';\nimport { ActiveEditorPlugin } from '../lexical/plugins/active-editor-plugin';\nimport { HeightLimitPlugin } from '../lexical/plugins/height-limit-plugin';\nimport { HistoryCapturePlugin } from '../lexical/plugins/history-capture-plugin';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations } from '../i18n';\nimport { debug, shortId } from '../utils/debug';\n\ninterface PageHeaderProps {\n pageId: string;\n initialHeaderState?: SerializedEditorState | null;\n pageCounterLabel?: string;\n onHeaderChange?: (state: SerializedEditorState, height: number) => void;\n}\n\n/**\n * PageHeader — Mini Lexical editor for a page's header region.\n *\n * Constrained to MAX_HEADER_HEIGHT_PX. Uses overflow: clip to prevent\n * the browser from scrolling the container to follow the cursor.\n * Remounts via key={syncVersion} when content is copied/cleared externally.\n */\nexport const PageHeader: React.FC<PageHeaderProps> = ({\n pageId,\n initialHeaderState,\n pageCounterLabel,\n onHeaderChange,\n}) => {\n const hasPageCounter = !!pageCounterLabel;\n const { nodes, themeOverrides } = useExtensions();\n const t = useTranslations();\n const config = useMemo(\n () => {\n const baseConfig = createEditorConfig('header', pageId, nodes, themeOverrides);\n if (initialHeaderState) {\n return { ...baseConfig, editorState: JSON.stringify(initialHeaderState) };\n }\n return baseConfig;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- syncVersion forces remount via key, only used at init\n [pageId, nodes, themeOverrides],\n );\n\n const contentRef = useRef<HTMLDivElement>(null);\n\n const handleChange = useCallback(\n (editorState: EditorState) => {\n requestAnimationFrame(() => {\n const el = contentRef.current;\n if (el) {\n if (el.scrollHeight > MAX_HEADER_HEIGHT_PX) {\n debug(\n 'header',\n `page ${shortId(pageId)}: skipped external sync at ${el.scrollHeight}px > max ${MAX_HEADER_HEIGHT_PX}px`,\n );\n return;\n }\n const height = Math.min(el.scrollHeight, MAX_HEADER_HEIGHT_PX);\n debug('header', `page ${shortId(pageId)}: height=${height}px (scrollH=${el.scrollHeight})`);\n onHeaderChange?.(editorState.toJSON(), height);\n }\n });\n },\n [onHeaderChange, pageId],\n );\n\n return (\n <div\n className=\"lex4-page-header\"\n style={{ maxHeight: MAX_HEADER_HEIGHT_PX, overflow: 'clip' }}\n data-testid={`page-header-${pageId}`}\n >\n <LexicalComposer initialConfig={config}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n ref={contentRef}\n className={`lex4-page-hf-editable${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}\n />\n }\n placeholder={\n <div className={`lex4-page-hf-placeholder${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}>\n {t.header.placeholder}</div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <ActiveEditorPlugin pageId={pageId} region=\"header\" />\n <HistoryCapturePlugin pageId={pageId} region=\"header\" />\n <HeightLimitPlugin maxHeight={MAX_HEADER_HEIGHT_PX} channel=\"header\" />\n <OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n </LexicalComposer>\n {pageCounterLabel && (\n <div\n className=\"lex4-page-counter\"\n data-testid={`page-counter-header-${pageId}`}\n >\n {pageCounterLabel}\n </div>\n )}\n </div>\n );\n};","import React, { useCallback, useMemo, useRef } from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';\nimport type { EditorState, SerializedEditorState } from 'lexical';\n\nimport { createEditorConfig } from '../lexical/editor-setup';\nimport { MAX_FOOTER_HEIGHT_PX } from '../constants/dimensions';\nimport { ActiveEditorPlugin } from '../lexical/plugins/active-editor-plugin';\nimport { HeightLimitPlugin } from '../lexical/plugins/height-limit-plugin';\nimport { HistoryCapturePlugin } from '../lexical/plugins/history-capture-plugin';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations } from '../i18n';\nimport { debug, shortId } from '../utils/debug';\n\ninterface PageFooterProps {\n pageId: string;\n initialFooterState?: SerializedEditorState | null;\n pageCounterLabel?: string;\n onFooterChange?: (state: SerializedEditorState, height: number) => void;\n}\n\n/**\n * PageFooter — Mini Lexical editor for a page's footer region.\n *\n * Constrained to MAX_FOOTER_HEIGHT_PX. Uses overflow: clip to prevent\n * the browser from scrolling the container to follow the cursor.\n * Remounts via key={syncVersion} when content is copied/cleared externally.\n */\nexport const PageFooter: React.FC<PageFooterProps> = ({\n pageId,\n initialFooterState,\n pageCounterLabel,\n onFooterChange,\n}) => {\n const hasPageCounter = !!pageCounterLabel;\n const { nodes, themeOverrides } = useExtensions();\n const t = useTranslations();\n const config = useMemo(\n () => {\n const baseConfig = createEditorConfig('footer', pageId, nodes, themeOverrides);\n if (initialFooterState) {\n return { ...baseConfig, editorState: JSON.stringify(initialFooterState) };\n }\n return baseConfig;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- syncVersion forces remount via key, only used at init\n [pageId, nodes, themeOverrides],\n );\n\n const contentRef = useRef<HTMLDivElement>(null);\n\n const handleChange = useCallback(\n (editorState: EditorState) => {\n requestAnimationFrame(() => {\n const el = contentRef.current;\n if (el) {\n if (el.scrollHeight > MAX_FOOTER_HEIGHT_PX) {\n debug(\n 'footer',\n `page ${shortId(pageId)}: skipped external sync at ${el.scrollHeight}px > max ${MAX_FOOTER_HEIGHT_PX}px`,\n );\n return;\n }\n const height = Math.min(el.scrollHeight, MAX_FOOTER_HEIGHT_PX);\n debug('footer', `page ${shortId(pageId)}: height=${height}px (scrollH=${el.scrollHeight})`);\n onFooterChange?.(editorState.toJSON(), height);\n }\n });\n },\n [onFooterChange, pageId],\n );\n\n return (\n <div\n className=\"lex4-page-footer\"\n style={{ maxHeight: MAX_FOOTER_HEIGHT_PX, overflow: 'clip' }}\n data-testid={`page-footer-${pageId}`}\n >\n <LexicalComposer initialConfig={config}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n ref={contentRef}\n className={`lex4-page-hf-editable${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}\n />\n }\n placeholder={\n <div className={`lex4-page-hf-placeholder${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}>\n {t.footer.placeholder}</div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <ActiveEditorPlugin pageId={pageId} region=\"footer\" />\n <HistoryCapturePlugin pageId={pageId} region=\"footer\" />\n <HeightLimitPlugin maxHeight={MAX_FOOTER_HEIGHT_PX} channel=\"footer\" />\n <OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n </LexicalComposer>\n {pageCounterLabel && (\n <div\n className=\"lex4-page-counter\"\n data-testid={`page-counter-footer-${pageId}`}\n >\n {pageCounterLabel}\n </div>\n )}\n </div>\n );\n};","import React, { useCallback } from 'react';\nimport { A4_WIDTH_PX, A4_HEIGHT_PX, PAGE_MARGIN_TOP_PX, PAGE_MARGIN_BOTTOM_PX, PAGE_MARGIN_LEFT_PX, PAGE_MARGIN_RIGHT_PX } from '../constants/dimensions';\nimport { useDocument } from '../context/document-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { PageBody } from './PageBody';\nimport { PageHeader } from './PageHeader';\nimport { PageFooter } from './PageFooter';\nimport type { SerializedEditorState } from 'lexical';\n\ninterface PageViewProps {\n pageId: string;\n pageIndex: number;\n onOverflow?: (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => void;\n onBackspaceAtStart?: (pageIndex: number, pageId: string) => void;\n onDeleteAtEnd?: (pageIndex: number, pageId: string) => void;\n onMoveToPreviousPage?: (pageIndex: number) => void;\n onMoveToNextPage?: (pageIndex: number) => void;\n}\n\n/**\n * PageView — A single A4 page with header, body, and footer regions.\n *\n * Dimensions are always exactly A4 (794 × 1123 px).\n * Header and footer are only rendered when the global toggle is on.\n * Uses CSS flexbox: header/footer are flex-shrink-0, body is flex-1.\n */\nexport const PageView: React.FC<PageViewProps> = React.memo(({\n pageId,\n pageIndex,\n onOverflow,\n onBackspaceAtStart,\n onDeleteAtEnd,\n onMoveToPreviousPage,\n onMoveToNextPage,\n}) => {\n const { document, dispatch, editorRegistry, setActiveEditor, setActivePageId } = useDocument();\n const t = useTranslations();\n const page = document.pages.find(p => p.id === pageId);\n const showHeaderFooter = document.headerFooterEnabled;\n const pageCounterMode = document.pageCounterMode;\n const pageCounterLabel = interpolate(t.pageCounter.format, {\n current: pageIndex + 1,\n total: document.pages.length,\n });\n\n if (!page) return null;\n\n const handleBodyChange = useCallback(\n (bodyState: SerializedEditorState) => {\n dispatch({ type: 'UPDATE_PAGE_BODY', pageId, bodyState });\n },\n [dispatch, pageId],\n );\n\n const handleHeaderChange = useCallback(\n (headerState: SerializedEditorState, height: number) => {\n dispatch({ type: 'UPDATE_PAGE_HEADER_CONTENT', pageId, headerState, height });\n },\n [dispatch, pageId],\n );\n\n const handleFooterChange = useCallback(\n (footerState: SerializedEditorState, height: number) => {\n dispatch({ type: 'UPDATE_PAGE_FOOTER_CONTENT', pageId, footerState, height });\n },\n [dispatch, pageId],\n );\n\n const handleFocus = useCallback(() => {\n setActivePageId(pageId);\n const editor = editorRegistry.get(pageId);\n if (editor) {\n setActiveEditor(editor, { pageId, region: 'body' });\n }\n }, [editorRegistry, pageId, setActiveEditor, setActivePageId]);\n\n const handleOverflow = useCallback(\n (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => {\n onOverflow?.(overflowContent, cause);\n },\n [onOverflow],\n );\n\n return (\n <div\n className=\"lex4-page\"\n style={{\n width: A4_WIDTH_PX,\n height: A4_HEIGHT_PX,\n paddingTop: PAGE_MARGIN_TOP_PX,\n paddingBottom: PAGE_MARGIN_BOTTOM_PX,\n paddingLeft: PAGE_MARGIN_LEFT_PX,\n paddingRight: PAGE_MARGIN_RIGHT_PX,\n }}\n data-testid={`page-${pageIndex}`}\n data-page-id={pageId}\n >\n {showHeaderFooter && (\n <PageHeader\n key={`header-${page.headerSyncVersion}`}\n pageId={pageId}\n initialHeaderState={page.headerState}\n pageCounterLabel={pageCounterMode === 'header' || pageCounterMode === 'both' ? pageCounterLabel : undefined}\n onHeaderChange={handleHeaderChange}\n />\n )}\n\n <PageBody\n key={`body-${page.bodySyncVersion}`}\n pageId={pageId}\n initialBodyState={page.bodyState}\n onBodyChange={handleBodyChange}\n onOverflow={handleOverflow}\n onFocus={handleFocus}\n onBackspaceAtStart={() => onBackspaceAtStart?.(pageIndex, pageId)}\n onDeleteAtEnd={() => onDeleteAtEnd?.(pageIndex, pageId)}\n onMoveToPreviousPage={() => onMoveToPreviousPage?.(pageIndex)}\n onMoveToNextPage={() => onMoveToNextPage?.(pageIndex)}\n />\n\n {showHeaderFooter && (\n <PageFooter\n key={`footer-${page.footerSyncVersion}`}\n pageId={pageId}\n initialFooterState={page.footerState}\n pageCounterLabel={pageCounterMode === 'footer' || pageCounterMode === 'both' ? pageCounterLabel : undefined}\n onFooterChange={handleFooterChange}\n />\n )}\n </div>\n );\n});\n\nPageView.displayName = 'PageView';\n","import React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { $getRoot } from 'lexical';\nimport type { SerializedEditorState, LexicalEditor } from 'lexical';\n\nimport { useDocument } from '../context/document-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { computeBodyHeight } from '../constants/page-layout';\nimport { usePagination } from '../hooks/use-pagination';\nimport { PageView } from './PageView';\nimport { createPageFromTemplate } from '../types/document';\nimport { debug, shortId } from '../utils/debug';\n\n/**\n * DocumentView — Scrollable container rendering all pages vertically.\n *\n * Provides the page-layout visual with pages centered on a gray background\n * with gaps between pages. Handles overflow content from pages by\n * creating new pages or prepending to existing next pages.\n */\nexport const DocumentView: React.FC = () => {\n const {\n document,\n dispatch,\n editorRegistry,\n requestFocusAtEnd,\n runHistoryAction,\n setActiveEditor,\n setActivePageId,\n } = useDocument();\n const t = useTranslations();\n const { handlePageUnderflow, reflowAll } = usePagination(document, dispatch);\n const previousBodyHeightsRef = useRef<number[] | null>(null);\n const pasteOverflowSequenceRef = useRef(false);\n const pasteOverflowReleaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const defaultPageTemplate = useMemo(\n () => ({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n }),\n [\n document.defaultFooterHeight,\n document.defaultFooterState,\n document.defaultHeaderHeight,\n document.defaultHeaderState,\n ],\n );\n\n const bodyHeights = useMemo(\n () => document.pages.map(page => computeBodyHeight(\n document.headerFooterEnabled ? page.headerHeight : 0,\n document.headerFooterEnabled ? page.footerHeight : 0,\n )),\n [document.headerFooterEnabled, document.pages],\n );\n\n useEffect(() => {\n const previousBodyHeights = previousBodyHeightsRef.current;\n previousBodyHeightsRef.current = bodyHeights;\n\n if (!previousBodyHeights) {\n return;\n }\n\n const bodySpaceExpanded = bodyHeights.some((height, index) => {\n const previousHeight = previousBodyHeights[index];\n return previousHeight !== undefined && height > previousHeight;\n });\n\n if (bodySpaceExpanded) {\n debug('page', 'body space expanded — running full reflow');\n reflowAll();\n }\n }, [bodyHeights, reflowAll]);\n\n useEffect(\n () => () => {\n if (pasteOverflowReleaseTimerRef.current) {\n clearTimeout(pasteOverflowReleaseTimerRef.current);\n }\n },\n [],\n );\n\n const focusBodyEditor = useCallback(\n (pageId: string, boundary: 'start' | 'end') => {\n let attempts = 0;\n\n const focusWhenReady = () => {\n const editor = editorRegistry.get(pageId);\n if (!editor) {\n if (attempts < 4) {\n attempts += 1;\n requestAnimationFrame(focusWhenReady);\n }\n return;\n }\n\n const caretPosition = { pageId, region: 'body' as const };\n setActivePageId(pageId);\n setActiveEditor(editor as LexicalEditor, caretPosition);\n editor.focus(() => {\n editor.update(() => {\n if (boundary === 'start') {\n $getRoot().selectStart();\n } else {\n $getRoot().selectEnd();\n }\n });\n });\n };\n\n requestAnimationFrame(focusWhenReady);\n },\n [editorRegistry, setActiveEditor, setActivePageId],\n );\n\n const handlePageOverflow = useCallback(\n (\n pageIndex: number,\n overflowContent: SerializedEditorState,\n cause: 'paste' | 'content',\n ) => {\n const nextPageIndex = pageIndex + 1;\n const overflowChildCount = overflowContent.root?.children?.length ?? 0;\n debug('page', `handlePageOverflow: pageIndex=${pageIndex} overflowChildren=${overflowChildCount} totalPages=${document.pages.length}`);\n\n if (cause === 'paste') {\n pasteOverflowSequenceRef.current = true;\n }\n\n if (pasteOverflowSequenceRef.current) {\n if (pasteOverflowReleaseTimerRef.current) {\n clearTimeout(pasteOverflowReleaseTimerRef.current);\n }\n pasteOverflowReleaseTimerRef.current = setTimeout(() => {\n pasteOverflowSequenceRef.current = false;\n pasteOverflowReleaseTimerRef.current = null;\n }, 800);\n }\n\n if (nextPageIndex < document.pages.length) {\n // Prepend overflow content to the next page's editor directly\n const nextPage = document.pages[nextPageIndex];\n const nextEditor = editorRegistry.get(nextPage.id);\n\n if (nextEditor) {\n const currentState = nextEditor.getEditorState().toJSON();\n const existingChildren = currentState.root?.children ?? [];\n const overflowChildren = overflowContent.root?.children ?? [];\n\n debug('page', `prepending ${overflowChildren.length} nodes to existing page ${shortId(nextPage.id)} (had ${existingChildren.length} children)`);\n\n const mergedState: SerializedEditorState = {\n root: {\n ...currentState.root,\n children: [...overflowChildren, ...existingChildren],\n },\n } as SerializedEditorState;\n\n const newEditorState = nextEditor.parseEditorState(JSON.stringify(mergedState));\n nextEditor.setEditorState(newEditorState);\n if (pasteOverflowSequenceRef.current) {\n requestFocusAtEnd({ pageId: nextPage.id, region: 'body' });\n }\n } else {\n debug('page', `editor not found in registry for page ${shortId(nextPage.id)} — falling back to ADD_PAGE`);\n const newPage = createPageFromTemplate(defaultPageTemplate);\n newPage.bodyState = overflowContent;\n runHistoryAction(\n {\n label: 'Overflow created new page',\n source: 'overflow',\n region: 'document',\n },\n () => {\n dispatch({ type: 'ADD_PAGE', afterIndex: pageIndex, page: newPage });\n },\n );\n if (pasteOverflowSequenceRef.current) {\n requestFocusAtEnd({ pageId: newPage.id, region: 'body' });\n }\n }\n } else {\n // Create a new page with the overflow content as initial state\n const newPage = createPageFromTemplate(defaultPageTemplate);\n newPage.bodyState = overflowContent;\n debug('page', `creating new page ${shortId(newPage.id)} with ${overflowChildCount} overflow children`);\n runHistoryAction(\n {\n label: 'Overflow created new page',\n source: 'overflow',\n region: 'document',\n },\n () => {\n dispatch({ type: 'ADD_PAGE', page: newPage });\n },\n );\n if (pasteOverflowSequenceRef.current) {\n requestFocusAtEnd({ pageId: newPage.id, region: 'body' });\n }\n }\n },\n [defaultPageTemplate, document.pages, dispatch, editorRegistry, requestFocusAtEnd, runHistoryAction],\n );\n\n const handleBackspaceAtPageStart = useCallback(\n (pageIndex: number, pageId: string) => {\n if (pageIndex <= 0) {\n return;\n }\n\n const previousPage = document.pages[pageIndex - 1];\n if (!previousPage) {\n return;\n }\n\n runHistoryAction(\n {\n label: `${t.historyLabels.deletedBackward} - ${interpolate(t.regions.page, { page: pageIndex + 1 })}`,\n source: 'body',\n pageId,\n region: 'body',\n },\n () => {\n handlePageUnderflow(pageIndex - 1);\n },\n );\n\n focusBodyEditor(previousPage.id, 'end');\n },\n [document.pages, focusBodyEditor, handlePageUnderflow, runHistoryAction],\n );\n\n const handleDeleteAtPageEnd = useCallback(\n (pageIndex: number, pageId: string) => {\n const currentPage = document.pages[pageIndex];\n const nextPage = document.pages[pageIndex + 1];\n if (!currentPage || !nextPage) {\n return;\n }\n\n runHistoryAction(\n {\n label: `${t.historyLabels.deletedForward} - ${interpolate(t.regions.page, { page: pageIndex + 1 })}`,\n source: 'body',\n pageId,\n region: 'body',\n },\n () => {\n handlePageUnderflow(pageIndex);\n },\n );\n\n focusBodyEditor(currentPage.id, 'end');\n },\n [document.pages, focusBodyEditor, handlePageUnderflow, runHistoryAction],\n );\n\n const handleMoveToPreviousPage = useCallback(\n (pageIndex: number) => {\n if (pageIndex <= 0) {\n return;\n }\n\n const previousPage = document.pages[pageIndex - 1];\n if (!previousPage) {\n return;\n }\n\n focusBodyEditor(previousPage.id, 'end');\n },\n [document.pages, focusBodyEditor],\n );\n\n const handleMoveToNextPage = useCallback(\n (pageIndex: number) => {\n const nextPage = document.pages[pageIndex + 1];\n if (!nextPage) {\n return;\n }\n\n focusBodyEditor(nextPage.id, 'start');\n },\n [document.pages, focusBodyEditor],\n );\n\n return (\n <div\n className=\"lex4-document-view\"\n data-testid=\"document-view\"\n tabIndex={-1}\n >\n {document.pages.map((page, index) => (\n <PageView\n key={page.id}\n pageId={page.id}\n pageIndex={index}\n onOverflow={(content, cause) => handlePageOverflow(index, content, cause)}\n onBackspaceAtStart={handleBackspaceAtPageStart}\n onDeleteAtEnd={handleDeleteAtPageEnd}\n onMoveToPreviousPage={handleMoveToPreviousPage}\n onMoveToNextPage={handleMoveToNextPage}\n />\n ))}\n </div>\n );\n};\n","/**\n * Document AST types — the backend integration contract.\n *\n * These types define the clean, Lexical-independent AST\n * that consumers receive when calling getDocumentAst().\n * Backend teams can use these types directly without any\n * knowledge of Lexical or React internals.\n *\n * @version 1.0.0\n */\n\nexport const AST_VERSION = '1.0.0' as const;\n\n// ---------------------------------------------------------------------------\n// Top-level document\n// ---------------------------------------------------------------------------\n\nexport interface DocumentAst {\n version: typeof AST_VERSION;\n page: PageFormatAst;\n headerFooter: HeaderFooterConfigAst;\n pages: PageAst[];\n metadata: DocumentMetadataAst;\n}\n\nexport interface PageFormatAst {\n format: 'A4';\n widthMm: number;\n heightMm: number;\n margins: MarginsAst;\n}\n\nexport interface MarginsAst {\n topMm: number;\n rightMm: number;\n bottomMm: number;\n leftMm: number;\n}\n\nexport interface HeaderFooterConfigAst {\n enabled: boolean;\n pageCounterMode: 'none' | 'header' | 'footer' | 'both';\n defaultHeader: ContentAst | null;\n defaultFooter: ContentAst | null;\n}\n\nexport interface DocumentMetadataAst {\n variables: Record<string, VariableDefinitionAst>;\n}\n\n// ---------------------------------------------------------------------------\n// Page\n// ---------------------------------------------------------------------------\n\nexport interface PageAst {\n pageIndex: number;\n body: BlockNodeAst[];\n header: ContentAst | null;\n footer: ContentAst | null;\n}\n\n// ---------------------------------------------------------------------------\n// Content container\n// ---------------------------------------------------------------------------\n\nexport interface ContentAst {\n blocks: BlockNodeAst[];\n}\n\n// ---------------------------------------------------------------------------\n// Block nodes\n// ---------------------------------------------------------------------------\n\nexport type BlockNodeAst =\n | ParagraphAst\n | HeadingAst\n | ListAst\n | BlockQuoteAst;\n\nexport type Alignment = 'left' | 'center' | 'right' | 'justify';\n\nexport interface ParagraphAst {\n type: 'paragraph';\n alignment?: Alignment;\n indent?: number;\n children: InlineNodeAst[];\n}\n\nexport interface HeadingAst {\n type: 'heading';\n level: 1 | 2 | 3 | 4 | 5 | 6;\n alignment?: Alignment;\n children: InlineNodeAst[];\n}\n\nexport interface ListAst {\n type: 'list';\n listType: 'ordered' | 'unordered';\n items: ListItemAst[];\n}\n\nexport interface ListItemAst {\n type: 'list-item';\n children: InlineNodeAst[];\n nestedList?: ListAst;\n}\n\nexport interface BlockQuoteAst {\n type: 'blockquote';\n children: InlineNodeAst[];\n}\n\n// ---------------------------------------------------------------------------\n// Inline nodes\n// ---------------------------------------------------------------------------\n\nexport type InlineNodeAst =\n | TextRunAst\n | VariableAst\n | LineBreakAst;\n\nexport interface TextMarks {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n fontFamily?: string;\n fontSize?: number;\n}\n\nexport interface TextRunAst {\n type: 'text';\n text: string;\n marks?: TextMarks;\n}\n\nexport interface VariableAst {\n type: 'variable';\n key: string;\n marks?: TextMarks;\n}\n\nexport interface LineBreakAst {\n type: 'linebreak';\n}\n\n// ---------------------------------------------------------------------------\n// Variable definitions (shared with variables/types.ts)\n// ---------------------------------------------------------------------------\n\nexport interface VariableDefinitionAst {\n key: string;\n label: string;\n description?: string;\n valueType?: 'string' | 'number' | 'date' | 'boolean';\n group?: string;\n}\n\n// ---------------------------------------------------------------------------\n// REST payload\n// ---------------------------------------------------------------------------\n\nexport interface SaveDocumentRequest {\n document: DocumentAst;\n exportTarget?: 'pdf' | 'docx';\n documentId?: string;\n metadata?: Record<string, string>;\n}\n","/**\n * Inline mapper — Converts Lexical serialized inline nodes to AST inline nodes.\n *\n * Handles:\n * - TextNode → TextRunAst (decodes format bitmask + parses CSS style)\n * - VariableNode → VariableAst\n * - LineBreakNode → LineBreakAst\n */\n\nimport type { InlineNodeAst, TextMarks, TextRunAst, VariableAst, LineBreakAst } from './types';\nimport type { SerializedVariableNode } from '../variables/variable-node';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n} from '../utils/text-style';\n\n// Lexical format bitmask constants\nconst IS_BOLD = 1;\nconst IS_ITALIC = 2;\nconst IS_STRIKETHROUGH = 4;\nconst IS_UNDERLINE = 8;\n\n/** Serialized Lexical text node shape (subset of fields we need). */\ninterface SerializedTextNode {\n type: 'text';\n text: string;\n format: number;\n style?: string;\n [key: string]: unknown;\n}\n\ninterface SerializedLineBreak {\n type: 'linebreak';\n [key: string]: unknown;\n}\n\ntype SerializedInlineNode = SerializedTextNode | SerializedVariableNode | SerializedLineBreak;\n\n/**\n * Decodes Lexical's format bitmask into named boolean marks.\n */\nexport function decodeFormatBitmask(format: number): Pick<TextMarks, 'bold' | 'italic' | 'underline' | 'strikethrough'> {\n const marks: Pick<TextMarks, 'bold' | 'italic' | 'underline' | 'strikethrough'> = {};\n if (format & IS_BOLD) marks.bold = true;\n if (format & IS_ITALIC) marks.italic = true;\n if (format & IS_UNDERLINE) marks.underline = true;\n if (format & IS_STRIKETHROUGH) marks.strikethrough = true;\n return marks;\n}\n\n/**\n * Extracts font-family from a CSS style string.\n */\nexport function extractFontFamily(style: string): string | undefined {\n return extractFontFamilyFromStyle(style);\n}\n\n/**\n * Extracts font-size (in pt) from a CSS style string.\n */\nexport function extractFontSizePt(style: string): number | undefined {\n return extractFontSizePtFromStyle(style);\n}\n\n/**\n * Builds TextMarks from a Lexical format bitmask and style string.\n */\nexport function buildTextMarks(format: number, style?: string): TextMarks | undefined {\n const formatMarks = decodeFormatBitmask(format);\n const fontFamily = style ? extractFontFamily(style) : undefined;\n const fontSize = style ? extractFontSizePt(style) : undefined;\n\n const marks: TextMarks = {\n ...formatMarks,\n ...(fontFamily ? { fontFamily } : {}),\n ...(fontSize ? { fontSize } : {}),\n };\n\n return Object.keys(marks).length > 0 ? marks : undefined;\n}\n\n/**\n * Maps a single serialized Lexical inline node to an AST inline node.\n */\nexport function mapInlineNode(node: SerializedInlineNode): InlineNodeAst {\n switch (node.type) {\n case 'text':\n return mapTextNode(node as SerializedTextNode);\n case 'variable-node':\n return mapVariableNode(node as SerializedVariableNode);\n case 'linebreak':\n return mapLineBreak();\n default:\n // Fallback: treat unknown inline nodes as empty text\n return { type: 'text', text: '' };\n }\n}\n\nfunction mapTextNode(node: SerializedTextNode): TextRunAst {\n const marks = buildTextMarks(node.format, node.style);\n return {\n type: 'text',\n text: node.text,\n ...(marks ? { marks } : {}),\n };\n}\n\nfunction mapVariableNode(node: SerializedVariableNode): VariableAst {\n const marks = buildTextMarks(node.format ?? 0, node.style);\n return {\n type: 'variable',\n key: node.variableKey,\n ...(marks ? { marks } : {}),\n };\n}\n\nfunction mapLineBreak(): LineBreakAst {\n return { type: 'linebreak' };\n}\n\n/**\n * Maps an array of serialized Lexical inline nodes to AST inline nodes.\n */\nexport function mapInlineNodes(nodes: SerializedInlineNode[]): InlineNodeAst[] {\n return nodes.map(mapInlineNode);\n}\n","/**\n * Block mapper — Converts Lexical serialized block nodes to AST block nodes.\n *\n * Handles:\n * - ParagraphNode → ParagraphAst\n * - HeadingNode → HeadingAst\n * - ListNode → ListAst\n * - ListItemNode → ListItemAst (with nested list support)\n * - QuoteNode → BlockQuoteAst\n */\n\nimport type {\n BlockNodeAst,\n ParagraphAst,\n HeadingAst,\n ListAst,\n ListItemAst,\n BlockQuoteAst,\n Alignment,\n InlineNodeAst,\n} from './types';\nimport { mapInlineNodes } from './inline-mapper';\n\n// Lexical format bitmask for element alignment\nconst ALIGN_LEFT = 1;\nconst ALIGN_CENTER = 2;\nconst ALIGN_RIGHT = 3;\nconst ALIGN_JUSTIFY = 4;\n\n/** Generic serialized Lexical element node shape. */\ninterface SerializedElementNode {\n type: string;\n children?: SerializedElementNode[];\n format?: number | string;\n indent?: number;\n direction?: string;\n tag?: string;\n listType?: string;\n start?: number;\n value?: number;\n [key: string]: unknown;\n}\n\nfunction decodeAlignment(format: number | string | undefined): Alignment | undefined {\n if (typeof format === 'string') {\n if (['left', 'center', 'right', 'justify'].includes(format)) {\n return format as Alignment;\n }\n return undefined;\n }\n if (typeof format !== 'number' || format === 0) return undefined;\n switch (format) {\n case ALIGN_LEFT: return 'left';\n case ALIGN_CENTER: return 'center';\n case ALIGN_RIGHT: return 'right';\n case ALIGN_JUSTIFY: return 'justify';\n default: return undefined;\n }\n}\n\n/**\n * Maps a single serialized Lexical block node to an AST block node.\n */\nexport function mapBlockNode(node: SerializedElementNode): BlockNodeAst {\n switch (node.type) {\n case 'paragraph':\n return mapParagraph(node);\n case 'heading':\n return mapHeading(node);\n case 'list':\n return mapList(node);\n case 'quote':\n return mapBlockQuote(node);\n default:\n // Fallback: treat as paragraph with empty children\n return {\n type: 'paragraph',\n children: mapInlineChildren(node),\n };\n }\n}\n\nfunction mapParagraph(node: SerializedElementNode): ParagraphAst {\n const alignment = decodeAlignment(node.format);\n const indent = node.indent && node.indent > 0 ? node.indent : undefined;\n return {\n type: 'paragraph',\n ...(alignment ? { alignment } : {}),\n ...(indent ? { indent } : {}),\n children: mapInlineChildren(node),\n };\n}\n\nfunction mapHeading(node: SerializedElementNode): HeadingAst {\n const alignment = decodeAlignment(node.format);\n const tagMatch = node.tag?.match(/^h([1-6])$/);\n const level = tagMatch ? (parseInt(tagMatch[1], 10) as 1 | 2 | 3 | 4 | 5 | 6) : 1;\n return {\n type: 'heading',\n level,\n ...(alignment ? { alignment } : {}),\n children: mapInlineChildren(node),\n };\n}\n\nfunction mapList(node: SerializedElementNode): ListAst {\n const listType = node.listType === 'number' ? 'ordered' : 'unordered';\n const items = (node.children ?? [])\n .filter(c => c.type === 'listitem')\n .map(mapListItem);\n return {\n type: 'list',\n listType,\n items,\n };\n}\n\nfunction mapListItem(node: SerializedElementNode): ListItemAst {\n const inlineChildren: InlineNodeAst[] = [];\n let nestedList: ListAst | undefined;\n\n for (const child of node.children ?? []) {\n if (child.type === 'list') {\n nestedList = mapList(child);\n } else {\n // Inline children\n const mapped = mapInlineNodes([child as never]);\n inlineChildren.push(...mapped);\n }\n }\n\n return {\n type: 'list-item',\n children: inlineChildren,\n ...(nestedList ? { nestedList } : {}),\n };\n}\n\nfunction mapBlockQuote(node: SerializedElementNode): BlockQuoteAst {\n return {\n type: 'blockquote',\n children: mapInlineChildren(node),\n };\n}\n\n/** Extracts inline children from a block node. */\nfunction mapInlineChildren(node: SerializedElementNode): InlineNodeAst[] {\n if (!node.children || node.children.length === 0) return [];\n return mapInlineNodes(node.children as never[]);\n}\n\n/**\n * Maps an array of serialized Lexical block nodes to AST block nodes.\n */\nexport function mapBlockNodes(nodes: SerializedElementNode[]): BlockNodeAst[] {\n return nodes.map(mapBlockNode);\n}\n","/**\n * Content mapper — Converts a Lexical SerializedEditorState to AST content.\n *\n * This module bridges the gap between Lexical's serialized state\n * (which has a root → children hierarchy) and the flat BlockNodeAst[]\n * used in the AST contract.\n */\n\nimport type { SerializedEditorState } from 'lexical';\nimport type { BlockNodeAst, ContentAst } from './types';\nimport { mapBlockNodes } from './block-mapper';\n\n/**\n * Converts a Lexical SerializedEditorState into a ContentAst.\n *\n * Returns null if the state is null/undefined (e.g. disabled header).\n */\nexport function mapEditorStateToContent(\n state: SerializedEditorState | null | undefined,\n): ContentAst | null {\n if (!state || !state.root || !state.root.children) {\n return null;\n }\n\n const blocks = mapBlockNodes(state.root.children as never[]);\n return { blocks };\n}\n\n/**\n * Converts a Lexical SerializedEditorState to flat BlockNodeAst[].\n *\n * Used for body content where we need the array directly\n * rather than wrapped in a ContentAst.\n */\nexport function mapEditorStateToBlocks(\n state: SerializedEditorState | null | undefined,\n): BlockNodeAst[] {\n if (!state || !state.root || !state.root.children) {\n return [];\n }\n\n return mapBlockNodes(state.root.children as never[]);\n}\n","/**\n * Document serializer — Converts a Lex4Document to a DocumentAst.\n *\n * This is the top-level serialization pipeline that orchestrates\n * all sub-mappers (inline, block, content) to produce the final\n * AST contract object.\n */\n\nimport type {\n DocumentAst,\n PageAst,\n VariableDefinitionAst,\n DocumentMetadataAst,\n} from './types';\nimport { AST_VERSION } from './types';\nimport type { Lex4Document } from '../types/document';\nimport type { VariableDefinition } from '../variables/types';\nimport { mapEditorStateToBlocks, mapEditorStateToContent } from './content-mapper';\nimport {\n PAGE_MARGIN_TOP_PX,\n PAGE_MARGIN_BOTTOM_PX,\n PAGE_MARGIN_LEFT_PX,\n PAGE_MARGIN_RIGHT_PX,\n PX_PER_MM,\n} from '../constants';\n\nconst MARGIN_TOP_MM = Math.round((PAGE_MARGIN_TOP_PX / PX_PER_MM) * 10) / 10;\nconst MARGIN_BOTTOM_MM = Math.round((PAGE_MARGIN_BOTTOM_PX / PX_PER_MM) * 10) / 10;\nconst MARGIN_LEFT_MM = Math.round((PAGE_MARGIN_LEFT_PX / PX_PER_MM) * 10) / 10;\nconst MARGIN_RIGHT_MM = Math.round((PAGE_MARGIN_RIGHT_PX / PX_PER_MM) * 10) / 10;\n\n/**\n * Serializes a Lex4Document into a clean, backend-friendly DocumentAst.\n *\n * @param document - The current editor document state\n * @param variableDefinitions - Optional variable definitions for metadata\n */\nexport function serializeDocument(\n document: Lex4Document,\n variableDefinitions: VariableDefinition[] = [],\n): DocumentAst {\n const pages: PageAst[] = document.pages.map((page, index) =>\n serializePage(page, index),\n );\n\n const metadata = buildMetadata(variableDefinitions);\n\n return {\n version: AST_VERSION,\n page: {\n format: 'A4',\n widthMm: 210,\n heightMm: 297,\n margins: {\n topMm: MARGIN_TOP_MM,\n rightMm: MARGIN_RIGHT_MM,\n bottomMm: MARGIN_BOTTOM_MM,\n leftMm: MARGIN_LEFT_MM,\n },\n },\n headerFooter: {\n enabled: document.headerFooterEnabled,\n pageCounterMode: document.pageCounterMode,\n defaultHeader: document.pages.length > 0\n ? mapEditorStateToContent(document.pages[0].headerState)\n : null,\n defaultFooter: document.pages.length > 0\n ? mapEditorStateToContent(document.pages[0].footerState)\n : null,\n },\n pages,\n metadata,\n };\n}\n\nfunction serializePage(\n page: { bodyState: import('lexical').SerializedEditorState | null; headerState: import('lexical').SerializedEditorState | null; footerState: import('lexical').SerializedEditorState | null },\n pageIndex: number,\n): PageAst {\n return {\n pageIndex,\n body: mapEditorStateToBlocks(page.bodyState),\n header: mapEditorStateToContent(page.headerState),\n footer: mapEditorStateToContent(page.footerState),\n };\n}\n\nfunction buildMetadata(\n variableDefinitions: VariableDefinition[],\n): DocumentMetadataAst {\n const variables: Record<string, VariableDefinitionAst> = {};\n\n for (const def of variableDefinitions) {\n variables[def.key] = {\n key: def.key,\n label: def.label,\n ...(def.description ? { description: def.description } : {}),\n ...(def.valueType ? { valueType: def.valueType } : {}),\n ...(def.group ? { group: def.group } : {}),\n };\n }\n\n return { variables };\n}\n","/**\n * Payload builder — Wraps a DocumentAst into a REST-ready payload.\n *\n * This module provides a simple helper for consumers to construct\n * a request body suitable for sending to a backend document generation API.\n */\n\nimport type { DocumentAst, SaveDocumentRequest } from './types';\n\nexport interface PayloadOptions {\n /** Target export format */\n exportTarget?: 'pdf' | 'docx';\n /** External document identifier */\n documentId?: string;\n /** Additional metadata for the backend */\n metadata?: Record<string, string>;\n}\n\n/**\n * Builds a SaveDocumentRequest payload from a DocumentAst.\n */\nexport function buildSavePayload(\n ast: DocumentAst,\n options?: PayloadOptions,\n): SaveDocumentRequest {\n return {\n document: ast,\n ...(options?.exportTarget ? { exportTarget: options.exportTarget } : {}),\n ...(options?.documentId ? { documentId: options.documentId } : {}),\n ...(options?.metadata ? { metadata: options.metadata } : {}),\n };\n}\n\n/**\n * Serializes a DocumentAst to a JSON string.\n */\nexport function serializeDocumentJson(ast: DocumentAst): string {\n return JSON.stringify(ast, null, 2);\n}\n","import {\n $createLineBreakNode,\n $createParagraphNode,\n $createTextNode,\n $getSelection,\n $isNodeSelection,\n $isRangeSelection,\n $insertNodes,\n type LexicalEditor,\n type LexicalNode,\n type SerializedEditorState,\n} from 'lexical';\nimport {\n $createHeadingNode,\n $createQuoteNode,\n type HeadingTagType,\n} from '@lexical/rich-text';\nimport { $createListItemNode, $createListNode } from '@lexical/list';\nimport type { Lex4Document } from '../../types/document';\nimport { $createVariableNode } from '../../variables/variable-node';\n\ninterface SerializedLexicalBaseNode {\n type: string;\n children?: SerializedLexicalBaseNode[];\n format?: number | string;\n indent?: number;\n listType?: string;\n start?: number;\n text?: string;\n style?: string;\n variableKey?: string;\n [key: string]: unknown;\n}\n\nfunction appendChildren(\n parent: LexicalNode & { append: (...nodes: LexicalNode[]) => void },\n children: SerializedLexicalBaseNode[] = [],\n): void {\n const nodes = children\n .map(buildLexicalNode)\n .filter((node): node is LexicalNode => node !== null);\n\n if (nodes.length > 0) {\n parent.append(...nodes);\n }\n}\n\nfunction applyElementFormatting(\n node: LexicalNode & { setFormat?: (format: 'left' | 'center' | 'right' | 'justify') => void; setIndent?: (indent: number) => void },\n serializedNode: SerializedLexicalBaseNode,\n): void {\n if (\n typeof serializedNode.format === 'string'\n && ['left', 'center', 'right', 'justify'].includes(serializedNode.format)\n && node.setFormat\n ) {\n node.setFormat(serializedNode.format as 'left' | 'center' | 'right' | 'justify');\n }\n\n if (typeof serializedNode.indent === 'number' && serializedNode.indent > 0 && node.setIndent) {\n node.setIndent(serializedNode.indent);\n }\n}\n\nfunction buildLexicalNode(serializedNode: SerializedLexicalBaseNode): LexicalNode | null {\n switch (serializedNode.type) {\n case 'paragraph': {\n const node = $createParagraphNode();\n applyElementFormatting(node, serializedNode);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'heading': {\n const tag = typeof serializedNode.tag === 'string'\n && /^h[1-6]$/.test(serializedNode.tag)\n ? serializedNode.tag as HeadingTagType\n : 'h1';\n const node = $createHeadingNode(tag);\n applyElementFormatting(node, serializedNode);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'quote': {\n const node = $createQuoteNode();\n applyElementFormatting(node, serializedNode);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'list': {\n const listType = serializedNode.listType === 'number' ? 'number' : 'bullet';\n const node = $createListNode(listType, typeof serializedNode.start === 'number' ? serializedNode.start : 1);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'listitem': {\n const node = $createListItemNode();\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'text': {\n const node = $createTextNode(serializedNode.text ?? '');\n if (typeof serializedNode.format === 'number' && serializedNode.format > 0) {\n node.setFormat(serializedNode.format);\n }\n if (typeof serializedNode.style === 'string' && serializedNode.style.trim() !== '') {\n node.setStyle(serializedNode.style);\n }\n return node;\n }\n case 'linebreak':\n return $createLineBreakNode();\n case 'variable-node':\n return $createVariableNode(\n serializedNode.variableKey ?? '',\n typeof serializedNode.format === 'number' ? serializedNode.format : 0,\n typeof serializedNode.style === 'string' ? serializedNode.style : '',\n );\n default:\n return null;\n }\n}\n\nfunction getBodyChildren(pageState: SerializedEditorState | null): SerializedLexicalBaseNode[] {\n const root = pageState?.root as { children?: SerializedLexicalBaseNode[] } | undefined;\n return root?.children ?? [];\n}\n\nexport function insertDocumentContent(editor: LexicalEditor, document: Lex4Document): boolean {\n let inserted = false;\n\n editor.update(() => {\n const nodes = document.pages.flatMap((page) => getBodyChildren(page.bodyState))\n .map(buildLexicalNode)\n .filter((node): node is LexicalNode => node !== null);\n\n if (nodes.length === 0) {\n return;\n }\n\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n if (selection.isCollapsed()) {\n selection.insertParagraph();\n }\n\n const nextSelection = $getSelection();\n if ($isRangeSelection(nextSelection) || $isNodeSelection(nextSelection)) {\n nextSelection.insertNodes(nodes);\n } else {\n $insertNodes(nodes);\n }\n } else if ($isNodeSelection(selection)) {\n selection.insertNodes(nodes);\n } else {\n $insertNodes(nodes);\n }\n inserted = true;\n });\n\n return inserted;\n}\n","import type { LexicalEditor } from 'lexical';\nimport type { EditorRegistry } from '../context/document-context';\nimport type { CaretPosition } from '../types/history';\n\ninterface ResolveDocumentInsertTargetOptions {\n activeEditor: LexicalEditor | null;\n activeCaretPosition: CaretPosition | null;\n activePageId: string | null;\n editorRegistry: EditorRegistry;\n}\n\nexport function resolveDocumentInsertTarget({\n activeEditor,\n activeCaretPosition,\n activePageId,\n editorRegistry,\n}: ResolveDocumentInsertTargetOptions): LexicalEditor | null {\n if (activeEditor && activeCaretPosition?.region === 'body') {\n return activeEditor;\n }\n\n if (activePageId) {\n return editorRegistry.get(activePageId) ?? null;\n }\n\n return editorRegistry.all()[0] ?? null;\n}\n","import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';\nimport type { Lex4EditorProps } from '../types/editor-props';\nimport type { Lex4EditorHandle } from '../types/editor-handle';\nimport { DocumentProvider } from '../context/document-provider';\nimport { useDocument } from '../context/document-context';\nimport { useTranslations } from '../i18n';\nimport { HistorySidebar } from './HistorySidebar';\nimport { Toolbar } from './Toolbar';\nimport { DocumentView } from './DocumentView';\nimport {\n ExtensionProvider,\n ExtensionStateProvider,\n useExtensions,\n useExtensionContext,\n} from '../extensions/extension-context';\nimport { TranslationsProvider } from '../i18n';\nimport { serializeDocument } from '../ast/document-serializer';\nimport { serializeDocumentJson } from '../ast/payload-builder';\nimport { ToolbarConfigProvider } from '../context/toolbar-config';\nimport { insertDocumentContent } from '../lexical/utils/import-document-content';\nimport { resolveDocumentInsertTarget } from '../utils/document-insert-target';\nimport '../styles.css';\n\nfunction selectEntireDocument(\n rootElement: HTMLDivElement | null,\n selectionBuffer: HTMLTextAreaElement | null,\n) {\n if (!rootElement || !selectionBuffer) {\n return;\n }\n\n const bodyRoots = Array.from(\n rootElement.querySelectorAll<HTMLElement>('[data-testid^=\"page-body-\"] [data-lexical-editor=\"true\"]'),\n );\n\n if (bodyRoots.length === 0) {\n return;\n }\n\n selectionBuffer.value = bodyRoots\n .map(bodyRoot => bodyRoot.innerText.trim())\n .filter(Boolean)\n .join('\\n');\n selectionBuffer.focus();\n selectionBuffer.select();\n}\n\nconst GLOBAL_SELECTION_BACKGROUND = 'hsl(214 95% 87%)';\nconst GLOBAL_SELECTION_FOREGROUND = 'hsl(224 71% 25%)';\n\nfunction isFormFieldTarget(target: EventTarget | null): boolean {\n const element = target as HTMLElement | null;\n const tagName = element?.tagName;\n return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';\n}\n\nconst EditorChrome: React.FC<{\n captureHistoryShortcutsOnWindow: boolean;\n onSave?: Lex4EditorProps['onSave'];\n className?: string;\n}> = ({\n captureHistoryShortcutsOnWindow,\n onSave,\n className,\n}) => {\n const {\n document,\n dispatch,\n globalSelectionActive,\n setGlobalSelectionActive,\n undo,\n redo,\n } = useDocument();\n const { sidePanels, cssVariables, rootClassNames } = useExtensions();\n const rootRef = useRef<HTMLDivElement>(null);\n const selectionBufferRef = useRef<HTMLTextAreaElement>(null);\n\n const clearGlobalSelection = useCallback(() => {\n setGlobalSelectionActive(false);\n selectionBufferRef.current?.blur();\n }, [setGlobalSelectionActive]);\n\n const handleHistoryShortcut = useCallback((event: { key: string; metaKey: boolean; ctrlKey: boolean; shiftKey: boolean; preventDefault: () => void; stopPropagation?: () => void }) => {\n const key = event.key.toLowerCase();\n\n if (key === 'z') {\n event.preventDefault();\n event.stopPropagation?.();\n clearGlobalSelection();\n if (event.shiftKey) {\n redo();\n } else {\n undo();\n }\n return true;\n }\n\n if (key === 'y') {\n event.preventDefault();\n event.stopPropagation?.();\n clearGlobalSelection();\n redo();\n return true;\n }\n\n return false;\n }, [clearGlobalSelection, redo, undo]);\n\n const handleKeyDownCapture = useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement | null;\n const isGlobalSelectionBufferTarget = target === selectionBufferRef.current;\n\n if (!isGlobalSelectionBufferTarget && isFormFieldTarget(target)) {\n return;\n }\n\n const key = event.key.toLowerCase();\n\n if (isGlobalSelectionBufferTarget && (key === 'backspace' || key === 'delete')) {\n event.preventDefault();\n event.stopPropagation();\n dispatch({ type: 'CLEAR_DOCUMENT_CONTENT' });\n clearGlobalSelection();\n return;\n }\n\n const hasModifier = event.metaKey || event.ctrlKey;\n if (!hasModifier) {\n return;\n }\n\n if (key === 'a') {\n event.preventDefault();\n event.stopPropagation();\n requestAnimationFrame(() => {\n const activeElement = window.document.activeElement;\n if (activeElement instanceof HTMLElement && activeElement.isContentEditable) {\n activeElement.blur();\n }\n selectEntireDocument(rootRef.current, selectionBufferRef.current);\n setGlobalSelectionActive(true);\n });\n return;\n }\n\n if (key === 's' && onSave) {\n event.preventDefault();\n event.stopPropagation();\n const ast = serializeDocument(document);\n const json = serializeDocumentJson(ast);\n onSave({ document, ast, json });\n return;\n }\n\n if (handleHistoryShortcut(event)) {\n return;\n }\n }, [\n document,\n dispatch,\n handleHistoryShortcut,\n onSave,\n setGlobalSelectionActive,\n ]);\n\n const handleMouseDownCapture = useCallback((event: React.MouseEvent<HTMLDivElement>) => {\n if (!globalSelectionActive) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n const clickedToolbar = target?.closest('[data-testid=\"toolbar\"]');\n\n if (event.target !== selectionBufferRef.current && !clickedToolbar) {\n clearGlobalSelection();\n }\n }, [clearGlobalSelection, globalSelectionActive]);\n\n useEffect(() => {\n const editableRoots =\n rootRef.current?.querySelectorAll<HTMLElement>(\n '[data-testid^=\"page-body-\"] [data-lexical-editor=\"true\"]',\n ) ?? [];\n\n const root = rootRef.current;\n const styles = root ? getComputedStyle(root) : null;\n const selBg = styles?.getPropertyValue('--color-selection-bg').trim() || GLOBAL_SELECTION_BACKGROUND;\n const selFg = styles?.getPropertyValue('--color-selection-text').trim() || GLOBAL_SELECTION_FOREGROUND;\n\n editableRoots.forEach((editableRoot) => {\n editableRoot.style.backgroundColor = globalSelectionActive ? selBg : '';\n editableRoot.style.color = globalSelectionActive ? selFg : '';\n editableRoot.style.caretColor = globalSelectionActive ? 'transparent' : '';\n });\n }, [globalSelectionActive, document.pages.length]);\n\n useEffect(() => {\n if (!captureHistoryShortcutsOnWindow) {\n return;\n }\n\n const handleWindowKeyDown = (event: KeyboardEvent) => {\n const hasModifier = event.metaKey || event.ctrlKey;\n if (!hasModifier) {\n return;\n }\n\n handleHistoryShortcut(event);\n };\n\n window.addEventListener('keydown', handleWindowKeyDown, { capture: true });\n const handleWindowBeforeInput = (event: InputEvent) => {\n if (event.inputType === 'historyUndo') {\n event.preventDefault();\n clearGlobalSelection();\n undo();\n } else if (event.inputType === 'historyRedo') {\n event.preventDefault();\n clearGlobalSelection();\n redo();\n }\n };\n\n window.addEventListener('beforeinput', handleWindowBeforeInput, { capture: true });\n return () => {\n window.removeEventListener('keydown', handleWindowKeyDown, { capture: true });\n window.removeEventListener('beforeinput', handleWindowBeforeInput, { capture: true });\n };\n }, [captureHistoryShortcutsOnWindow, clearGlobalSelection, handleHistoryShortcut, redo, undo]);\n\n const rootClassName = ['lex4-editor', ...rootClassNames, className].filter(Boolean).join(' ');\n const extensionStyle = Object.keys(cssVariables).length > 0\n ? cssVariables as React.CSSProperties\n : undefined;\n\n return (\n <div\n ref={rootRef}\n className={rootClassName}\n style={extensionStyle}\n data-testid=\"lex4-editor\"\n data-global-selection-active={globalSelectionActive ? 'true' : 'false'}\n onKeyDownCapture={handleKeyDownCapture}\n onMouseDownCapture={handleMouseDownCapture}\n >\n <textarea\n ref={selectionBufferRef}\n aria-hidden=\"true\"\n data-testid=\"global-selection-buffer\"\n readOnly\n tabIndex={-1}\n className=\"lex4-selection-buffer\"\n />\n <Toolbar />\n <div className=\"lex4-canvas\">\n <div className=\"lex4-canvas-scroll\">\n <DocumentView />\n </div>\n {sidePanels.map((Panel, idx) => (\n <Panel key={idx} />\n ))}\n <HistorySidebar />\n </div>\n </div>\n );\n};\n\n/**\n * EditorWithHandle — Inner component that wires the imperative handle.\n * Has access to DocumentProvider and extension contexts.\n */\nconst EditorWithHandle = forwardRef<Lex4EditorHandle, {\n captureHistoryShortcutsOnWindow: boolean;\n onSave?: Lex4EditorProps['onSave'];\n className?: string;\n}>(({ captureHistoryShortcutsOnWindow, onSave, className }, ref) => {\n const {\n document: doc,\n activePageId,\n activeEditor,\n activeCaretPosition,\n editorRegistry,\n historySidebarOpen,\n runHistoryAction,\n setHistorySidebarOpen,\n } = useDocument();\n const { handleFactories } = useExtensions();\n const t = useTranslations();\n const documentRef = useRef(doc);\n const activeEditorRef = useRef(activeEditor);\n const historySidebarOpenRef = useRef(historySidebarOpen);\n const runHistoryActionRef = useRef(runHistoryAction);\n const insertedDocumentContentLabelRef = useRef(t.history.actions.insertedDocumentContent);\n\n useEffect(() => {\n documentRef.current = doc;\n }, [doc]);\n\n useEffect(() => {\n activeEditorRef.current = activeEditor;\n }, [activeEditor]);\n\n useEffect(() => {\n historySidebarOpenRef.current = historySidebarOpen;\n }, [historySidebarOpen]);\n\n useEffect(() => {\n runHistoryActionRef.current = runHistoryAction;\n }, [runHistoryAction]);\n\n useEffect(() => {\n insertedDocumentContentLabelRef.current = t.history.actions.insertedDocumentContent;\n }, [t.history.actions.insertedDocumentContent]);\n\n const getDocument = useCallback(() => documentRef.current, []);\n const getActiveEditor = useCallback(() => activeEditorRef.current, []);\n const extensionCtx = useExtensionContext(getDocument, getActiveEditor);\n const handleRef = useRef<Record<string, (...args: never[]) => unknown>>({});\n const extensionMethodKeysRef = useRef<string[]>([]);\n\n const handle = handleRef.current;\n handle.setHistorySidebarOpen = (open: boolean) => {\n setHistorySidebarOpen(open);\n };\n handle.toggleHistorySidebar = () => {\n setHistorySidebarOpen(!historySidebarOpenRef.current);\n };\n handle.insertDocumentContent = (documentToInsert) => {\n const targetEditor = resolveDocumentInsertTarget({\n activeEditor: activeEditorRef.current,\n activeCaretPosition,\n activePageId,\n editorRegistry,\n });\n if (!targetEditor) {\n return false;\n }\n\n let inserted = false;\n runHistoryActionRef.current(\n {\n label: insertedDocumentContentLabelRef.current,\n source: 'toolbar',\n region: 'document',\n },\n () => {\n inserted = insertDocumentContent(targetEditor, documentToInsert);\n },\n );\n return inserted;\n };\n\n for (const key of extensionMethodKeysRef.current) {\n delete handle[key];\n }\n\n const extensionMethodKeys: string[] = [];\n for (const factory of handleFactories) {\n const methods = factory(extensionCtx);\n for (const [key, method] of Object.entries(methods)) {\n handle[key] = method as (...args: never[]) => unknown;\n extensionMethodKeys.push(key);\n }\n }\n extensionMethodKeysRef.current = extensionMethodKeys;\n\n useImperativeHandle(ref, () => handle as unknown as Lex4EditorHandle, []);\n\n return (\n <EditorChrome\n captureHistoryShortcutsOnWindow={captureHistoryShortcutsOnWindow}\n onSave={onSave}\n className={className}\n />\n );\n});\n\nEditorWithHandle.displayName = 'EditorWithHandle';\n\n/**\n * Lex4Editor — The main public component.\n *\n * A paginated A4 document editor built on Meta Lexical.\n * Each page is a true discrete A4 page with its own Lexical editor instance.\n *\n * Uses an extension system for AST export, variables, and theming.\n * Pass extensions via the `extensions` prop:\n * @example\n * ```tsx\n * <Lex4Editor extensions={[defaultTheme(), astExtension(), variablesExtension(defs)]} />\n * ```\n */\nexport const Lex4Editor = forwardRef<Lex4EditorHandle, Lex4EditorProps>(({\n captureHistoryShortcutsOnWindow = true,\n initialDocument,\n onDocumentChange,\n onSave,\n extensions,\n translations,\n toolbar,\n className,\n}, ref) => {\n return (\n <TranslationsProvider translations={translations}>\n <ToolbarConfigProvider toolbar={toolbar}>\n <ExtensionStateProvider>\n <ExtensionProvider extensions={extensions}>\n <DocumentProvider\n initialDocument={initialDocument}\n onDocumentChange={onDocumentChange}\n >\n <EditorWithHandle\n ref={ref}\n captureHistoryShortcutsOnWindow={captureHistoryShortcutsOnWindow}\n onSave={onSave}\n className={className}\n />\n </DocumentProvider>\n </ExtensionProvider>\n </ExtensionStateProvider>\n </ToolbarConfigProvider>\n </TranslationsProvider>\n );\n});\n\nLex4Editor.displayName = 'Lex4Editor';\n","import { useCallback, useRef, useEffect } from 'react';\n\n/**\n * useOverflowDetection — Debounced overflow detection for a page body.\n *\n * Watches a contentEditable element and fires `onOverflow` when the\n * content height exceeds the allowed body height. Uses a debounce\n * to avoid firing on every keystroke.\n */\nexport function useOverflowDetection(\n bodyHeight: number,\n onOverflow: (() => void) | undefined,\n debounceMs: number = 100,\n) {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const check = useCallback(\n (el: HTMLElement) => {\n if (!onOverflow) return;\n if (el.scrollHeight > bodyHeight + 2) {\n // +2 for sub-pixel rounding\n onOverflow();\n }\n },\n [bodyHeight, onOverflow],\n );\n\n const attachRef = useCallback(\n (el: HTMLElement | null) => {\n // Cleanup previous observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n if (!el || !onOverflow) return;\n\n observerRef.current = new ResizeObserver(() => {\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => check(el), debounceMs);\n });\n observerRef.current.observe(el);\n },\n [check, debounceMs, onOverflow],\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n if (observerRef.current) observerRef.current.disconnect();\n };\n }, []);\n\n return { attachRef };\n}\n","import { useCallback, useRef, useEffect } from 'react';\n\n/**\n * useHeaderFooter — Tracks header/footer height via ResizeObserver\n * and reports changes to the document context.\n *\n * Clamps the reported height to the maximum allowed.\n */\nexport function useHeaderFooter(\n maxHeight: number,\n onHeightChange: (height: number) => void,\n) {\n const observerRef = useRef<ResizeObserver | null>(null);\n const lastHeightRef = useRef<number>(0);\n\n const attachRef = useCallback(\n (el: HTMLElement | null) => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n if (!el) return;\n\n const measure = () => {\n const height = Math.min(el.scrollHeight, maxHeight);\n if (height !== lastHeightRef.current) {\n lastHeightRef.current = height;\n onHeightChange(height);\n }\n };\n\n observerRef.current = new ResizeObserver(measure);\n observerRef.current.observe(el);\n\n // Initial measurement\n measure();\n },\n [maxHeight, onHeightChange],\n );\n\n useEffect(() => {\n return () => {\n if (observerRef.current) observerRef.current.disconnect();\n };\n }, []);\n\n return { attachRef };\n}\n","import type { Lex4Extension, ExtensionContext } from './types';\nimport { serializeDocument } from '../ast/document-serializer';\nimport { buildSavePayload, serializeDocumentJson } from '../ast/payload-builder';\nimport type { PayloadOptions } from '../ast/payload-builder';\nimport type { DocumentAst, SaveDocumentRequest } from '../ast/types';\nimport type { VariableDefinition } from '../variables/types';\n\ndeclare module '../types/editor-handle' {\n interface Lex4EditorHandle {\n getDocumentAst: () => DocumentAst;\n getDocumentJson: () => string;\n buildSavePayload: (options?: PayloadOptions) => SaveDocumentRequest;\n }\n}\n\n/**\n * Creates an AST extension that adds document export capabilities.\n *\n * Handle methods provided:\n * - `getDocumentAst()` — returns the current document as a typed AST\n * - `getDocumentJson()` — returns the AST as a JSON string\n * - `buildSavePayload(options?)` — builds a REST payload wrapping the AST\n *\n * @example\n * ```tsx\n * <Lex4Editor extensions={[astExtension()]} />\n * ```\n */\nexport function astExtension(): Lex4Extension {\n return {\n name: 'ast',\n handleMethods: (ctx: ExtensionContext) => {\n const getDefinitions = (): VariableDefinition[] => {\n return ctx.getExtensionState<VariableDefinition[]>('variableDefinitions') ?? [];\n };\n\n return {\n getDocumentAst: () => {\n const doc = ctx.getDocument();\n return serializeDocument(doc, getDefinitions());\n },\n getDocumentJson: () => {\n const doc = ctx.getDocument();\n const ast = serializeDocument(doc, getDefinitions());\n return serializeDocumentJson(ast);\n },\n buildSavePayload: (options?: Parameters<typeof buildSavePayload>[1]) => {\n const doc = ctx.getDocument();\n const ast = serializeDocument(doc, getDefinitions());\n return buildSavePayload(ast, options);\n },\n };\n },\n };\n}\n","import {\n createCommand,\n type LexicalEditor,\n} from 'lexical';\n\n/**\n * Command to insert a variable node at the current selection.\n * Payload is the variable key string (e.g. \"customer.name\").\n */\nexport const INSERT_VARIABLE_COMMAND = createCommand<string>('INSERT_VARIABLE');\n\n/**\n * Inserts a variable node at the current cursor position.\n */\nexport function insertVariable(editor: LexicalEditor, variableKey: string): void {\n editor.dispatchCommand(INSERT_VARIABLE_COMMAND, variableKey);\n}\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $insertNodes,\n COMMAND_PRIORITY_EDITOR,\n} from 'lexical';\nimport { $createVariableNode } from './variable-node';\nimport { INSERT_VARIABLE_COMMAND } from './variable-commands';\n\n/**\n * VariablePlugin — registers the INSERT_VARIABLE_COMMAND handler.\n *\n * When the command fires, a VariableNode is created and inserted\n * at the current selection position.\n */\nexport const VariablePlugin: React.FC = () => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_VARIABLE_COMMAND,\n (variableKey: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const variableNode = $createVariableNode(variableKey);\n $insertNodes([variableNode]);\n });\n return true;\n },\n COMMAND_PRIORITY_EDITOR,\n );\n }, [editor]);\n\n return null;\n};\n","import React, { useCallback, useMemo, useState } from 'react';\nimport { Search, RefreshCw } from 'lucide-react';\nimport { EditorSidebar } from './EditorSidebar';\nimport { useVariables } from '../variables/variable-context';\nimport { useDocument } from '../context/document-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { INSERT_VARIABLE_COMMAND } from '../variables/variable-commands';\nimport type { VariableDefinition } from '../variables/types';\n\n/**\n * VariablePanel — Right sidebar for browsing and inserting variables.\n *\n * Features:\n * - Search/filter variables by name or key\n * - Grouped list with colored badges\n * - Click-to-insert into the active editor\n * - Refresh button for reloading definitions\n */\nexport const VariablePanel: React.FC<{\n open: boolean;\n onClose: () => void;\n}> = ({ open, onClose }) => {\n const { definitions, refreshDefinitions } = useVariables();\n const { activeEditor, runHistoryAction } = useDocument();\n const t = useTranslations();\n const [filter, setFilter] = useState('');\n const [creating, setCreating] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const [draft, setDraft] = useState<{\n label: string;\n key: string;\n group: string;\n valueType: NonNullable<VariableDefinition['valueType']>;\n }>({\n label: '',\n key: '',\n group: '',\n valueType: 'string',\n });\n\n const filtered = useMemo(() => {\n if (!filter) return definitions;\n const lower = filter.toLowerCase();\n return definitions.filter(\n d => d.key.toLowerCase().includes(lower) || d.label.toLowerCase().includes(lower),\n );\n }, [definitions, filter]);\n\n const grouped = useMemo(() => {\n const groups: Record<string, VariableDefinition[]> = {};\n for (const def of filtered) {\n const g = def.group ?? 'Other';\n if (!groups[g]) groups[g] = [];\n groups[g].push(def);\n }\n return groups;\n }, [filtered]);\n\n const handleInsert = useCallback(\n (key: string) => {\n if (!activeEditor) return;\n runHistoryAction(\n { label: interpolate(t.variables.insertVariable, { key }), source: 'toolbar', region: 'document' },\n () => {\n activeEditor.dispatchCommand(INSERT_VARIABLE_COMMAND, key);\n },\n );\n },\n [activeEditor, runHistoryAction],\n );\n\n const resetCreateState = useCallback(() => {\n setDraft({\n label: '',\n key: '',\n group: '',\n valueType: 'string',\n });\n setCreateError(null);\n setCreating(false);\n }, []);\n\n const handleCreateVariable = useCallback((event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n const label = draft.label.trim();\n const key = draft.key.trim();\n const group = draft.group.trim();\n\n if (!label || !key) {\n setCreateError(t.variables.createVariableMissingFields);\n return;\n }\n\n if (definitions.some(def => def.key === key)) {\n setCreateError(interpolate(t.variables.createVariableDuplicateKey, { key }));\n return;\n }\n\n refreshDefinitions([\n ...definitions,\n {\n key,\n label,\n group: group || undefined,\n valueType: draft.valueType,\n },\n ]);\n\n resetCreateState();\n }, [\n definitions,\n draft.group,\n draft.key,\n draft.label,\n draft.valueType,\n refreshDefinitions,\n resetCreateState,\n t.variables.createVariableDuplicateKey,\n t.variables.createVariableMissingFields,\n ]);\n\n return (\n <EditorSidebar\n title={t.variables.title}\n subtitle={interpolate(t.variables.available, { count: String(definitions.length) })}\n open={open}\n onClose={onClose}\n testId=\"variable-panel\"\n headerActions={\n <button\n type=\"button\"\n className=\"lex4-sidebar-action-btn\"\n title={t.variables.refreshVariables}\n data-testid=\"btn-refresh-variables\"\n >\n <RefreshCw size={12} />\n </button>\n }\n >\n <div className=\"lex4-variable-panel-content\">\n <div className=\"lex4-variable-search-container\">\n <div className=\"lex4-variable-search-wrapper\">\n <Search size={14} className=\"lex4-variable-search-icon\" />\n <input\n type=\"text\"\n className=\"lex4-variable-search-input\"\n placeholder={t.variables.searchPlaceholder}\n data-testid=\"variable-panel-search\"\n value={filter}\n onChange={e => setFilter(e.target.value)}\n />\n </div>\n </div>\n\n <div className=\"lex4-variable-list\">\n {Object.keys(grouped).length === 0 && (\n <div className=\"lex4-variable-list-empty\">{t.variables.noVariablesFound}</div>\n )}\n {Object.entries(grouped).map(([group, defs]) => (\n <div key={group} className=\"lex4-variable-group\" data-variable-group={group}>\n <div className=\"lex4-variable-group-label\">{group}</div>\n <div className=\"lex4-variable-group-items\">\n {defs.map(def => (\n <button\n key={def.key}\n type=\"button\"\n className=\"lex4-variable-list-item\"\n data-testid={`variable-panel-${def.key}`}\n data-variable-group={group}\n onClick={() => handleInsert(def.key)}\n disabled={!activeEditor}\n title={def.key}\n >\n {def.label}\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n\n <div className=\"lex4-variable-create\">\n {creating ? (\n <form className=\"lex4-variable-create-form\" onSubmit={handleCreateVariable}>\n <div className=\"lex4-variable-create-title\">{t.variables.createVariableTitle}</div>\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableLabel}</span>\n <input\n value={draft.label}\n onChange={(e) => {\n setDraft(current => ({ ...current, label: e.target.value }));\n if (createError) {\n setCreateError(null);\n }\n }}\n />\n </label>\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableKey}</span>\n <input\n value={draft.key}\n onChange={(e) => {\n setDraft(current => ({ ...current, key: e.target.value }));\n if (createError) {\n setCreateError(null);\n }\n }}\n />\n </label>\n <div className=\"lex4-variable-create-row\">\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableGroup}</span>\n <input\n value={draft.group}\n onChange={(e) => {\n setDraft(current => ({ ...current, group: e.target.value }));\n }}\n />\n </label>\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableType}</span>\n <select\n value={draft.valueType}\n onChange={(e) => {\n setDraft(current => ({\n ...current,\n valueType: e.target.value as NonNullable<VariableDefinition['valueType']>,\n }));\n }}\n >\n <option value=\"string\">string</option>\n <option value=\"number\">number</option>\n <option value=\"date\">date</option>\n <option value=\"boolean\">boolean</option>\n </select>\n </label>\n </div>\n {createError && <div className=\"lex4-variable-create-error\">{createError}</div>}\n <div className=\"lex4-variable-create-actions\">\n <button type=\"button\" className=\"lex4-variable-create-cancel\" onClick={resetCreateState}>\n {t.variables.createVariableCancel}\n </button>\n <button type=\"submit\" className=\"lex4-variable-create-submit\">\n {t.variables.createVariableSave}\n </button>\n </div>\n </form>\n ) : (\n <button\n type=\"button\"\n className=\"lex4-variable-create-toggle\"\n onClick={() => setCreating(true)}\n >\n + {t.variables.newVariable}\n </button>\n )}\n </div>\n </div>\n </EditorSidebar>\n );\n};\n","import React, { createContext, useContext, useEffect, useState } from 'react';\nimport { Braces } from 'lucide-react';\nimport type { Lex4Extension, ExtensionContext } from './types';\nimport type { VariableDefinition } from '../variables/types';\nimport { VariableNode } from '../variables/variable-node';\nimport { VariablePlugin } from '../variables/variable-plugin';\nimport { VariableProvider, useVariables } from '../variables/variable-context';\nimport { VariablePanel } from '../components/VariablePanel';\nimport { INSERT_VARIABLE_COMMAND } from '../variables/variable-commands';\n\ndeclare module '../types/editor-handle' {\n interface Lex4EditorHandle {\n insertVariable: (key: string) => void;\n refreshVariables: (newDefs: VariableDefinition[]) => void;\n setVariablePanelOpen: (open: boolean) => void;\n toggleVariablePanel: () => void;\n }\n}\nimport { useExtensionState } from './extension-context';\nimport { useTranslations } from '../i18n';\nimport { useToolbarConfig } from '../context/toolbar-config';\n\n// --- Variable panel open/close context ---\n\ninterface VariablePanelState {\n panelOpen: boolean;\n setPanelOpen: (open: boolean) => void;\n}\n\nconst VariablePanelContext = createContext<VariablePanelState>({\n panelOpen: false,\n setPanelOpen: () => {},\n});\n\nexport function useVariablePanelState(): VariablePanelState {\n return useContext(VariablePanelContext);\n}\n\nconst VariablePanelStateProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [panelOpen, setPanelOpen] = useState(false);\n return (\n <VariablePanelContext.Provider value={{ panelOpen, setPanelOpen }}>\n {children}\n </VariablePanelContext.Provider>\n );\n};\n\n/**\n * Toolbar toggle contributed by the variables extension.\n * Opens and closes the variables side panel from the toolbar end area.\n */\nconst VariableToolbarToggle: React.FC = () => {\n const { panelOpen, setPanelOpen } = useVariablePanelState();\n const toolbarConfig = useToolbarConfig();\n const t = useTranslations();\n\n if (!toolbarConfig.variables.visible) {\n return null;\n }\n\n return (\n <button\n type=\"button\"\n className={`lex4-toolbar-toggle-btn${panelOpen ? ' active' : ''}`}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => setPanelOpen(!panelOpen)}\n data-testid=\"toggle-variable-panel\"\n title={panelOpen ? t.variables.closePanel : t.variables.openPanel}\n aria-label={panelOpen ? t.variables.closePanel : t.variables.openPanel}\n >\n <Braces size={14} />\n {toolbarConfig.variables.showLabel && t.variables.title}\n </button>\n );\n};\n\n/**\n * Wrapped VariablePanel that reads open/close state from VariablePanelContext.\n */\nconst VariablePanelWithState: React.FC = () => {\n const { panelOpen, setPanelOpen } = useVariablePanelState();\n return <VariablePanel open={panelOpen} onClose={() => setPanelOpen(false)} />;\n};\n\nconst VariablePanelStateSync: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const { panelOpen, setPanelOpen } = useVariablePanelState();\n const extState = useExtensionState();\n\n useEffect(() => {\n extState.set('variablePanelOpen', panelOpen);\n extState.set('setVariablePanelOpen', setPanelOpen);\n }, [extState, panelOpen, setPanelOpen]);\n\n return <>{children}</>;\n};\n\n/**\n * Syncs the VariableProvider definitions into the extension state store\n * so astExtension can access them when building the AST.\n */\nconst VariableDefinitionsSync: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const { definitions } = useVariables();\n const extState = useExtensionState();\n\n useEffect(() => {\n extState.set('variableDefinitions', definitions);\n }, [definitions, extState]);\n\n return <>{children}</>;\n};\n\n/**\n * Creates a variables extension that adds variable/placeholder support.\n *\n * Contributes:\n * - VariableNode (custom Lexical node)\n * - VariablePlugin (body plugin for insert command handling)\n * - VariableProvider (context provider for variable catalog)\n * - Variables side panel plus toolbar toggle\n * - VariablePanel side panel with toggle state\n * - Handle methods: insertVariable, refreshVariables\n *\n * @param definitions Initial variable definitions to load\n *\n * @example\n * ```tsx\n * const defs = [\n * { key: 'customer.name', label: 'Customer', group: 'Customer', valueType: 'string' },\n * ];\n * <Lex4Editor extensions={[variablesExtension(defs)]} />\n * ```\n */\nexport function variablesExtension(definitions: VariableDefinition[] = []): Lex4Extension {\n const ProviderWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n return (\n <VariablePanelStateProvider>\n <VariableProvider initialDefinitions={definitions}>\n <VariablePanelStateSync>\n <VariableDefinitionsSync>\n {children}\n </VariableDefinitionsSync>\n </VariablePanelStateSync>\n </VariableProvider>\n </VariablePanelStateProvider>\n );\n };\n\n return {\n name: 'variables',\n nodes: [VariableNode],\n bodyPlugins: [VariablePlugin],\n toolbarEndItems: [VariableToolbarToggle],\n sidePanel: VariablePanelWithState,\n provider: ProviderWrapper,\n handleMethods: (ctx: ExtensionContext) => ({\n insertVariable: (key: string) => {\n const editor = ctx.getActiveEditor();\n if (editor) {\n editor.dispatchCommand(INSERT_VARIABLE_COMMAND, key);\n }\n },\n refreshVariables: (newDefs: VariableDefinition[]) => {\n ctx.setExtensionState('variableDefinitions', newDefs);\n },\n setVariablePanelOpen: (open: boolean) => {\n const setter = ctx.getExtensionState<(open: boolean) => void>('setVariablePanelOpen');\n setter?.(open);\n },\n toggleVariablePanel: () => {\n const current = ctx.getExtensionState<boolean>('variablePanelOpen') ?? false;\n const setter = ctx.getExtensionState<(open: boolean) => void>('setVariablePanelOpen');\n setter?.(!current);\n },\n }),\n };\n}\n"],"names":["createContext","useContext","document","useMemo","selection","$createRangeSelectionFromDom","$getSelection","$isRangeSelection","useReducer","useState","useRef","useCallback","$getRoot","useEffect","jsx","forwardRef","createElement","__iconNode","jsxs","jumpToHistoryEntry","$isTextNode","FORMAT_TEXT_COMMAND","FORMAT_ELEMENT_COMMAND","INSERT_ORDERED_LIST_COMMAND","INSERT_UNORDERED_LIST_COMMAND","INDENT_CONTENT_COMMAND","OUTDENT_CONTENT_COMMAND","$setBlocksType","$createParagraphNode","$createHeadingNode","$isHeadingNode","DecoratorNode","useLexicalComposerContext","useLexicalNodeSelection","$isNodeSelection","$getNodeByKey","KEY_BACKSPACE_COMMAND","COMMAND_PRIORITY_LOW","KEY_DELETE_COMMAND","KEY_DOWN_COMMAND","$applyNodeReplacement","$selectAll","SELECTION_CHANGE_COMMAND","AlignLeft","AlignCenter","AlignRight","AlignJustify","IndentIncrease","IndentDecrease","Fragment","keepState","overflowState","nextPage","HeadingNode","QuoteNode","ListNode","ListItemNode","KEY_TAB_COMMAND","$isElementNode","$isParagraphNode","$setSelection","FOCUS_COMMAND","serializeNodeTree","$isListNode","$splitNode","$getNearestNodeFromDOMNode","CONTROLLED_TEXT_INSERTION_COMMAND","PASTE_COMMAND","KEY_ENTER_COMMAND","COMMAND_PRIORITY_HIGH","LexicalComposer","RichTextPlugin","ContentEditable","LexicalErrorBoundary","ListPlugin","OnChangePlugin","COMMAND_PRIORITY_CRITICAL","$createQuoteNode","$createListNode","$createListItemNode","$createTextNode","$createLineBreakNode","$insertNodes","useImperativeHandle","createCommand","COMMAND_PRIORITY_EDITOR"],"mappings":"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","x_google_ignoreList":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46]}
|
|
1
|
+
{"version":3,"file":"lex4-editor.cjs","sources":["../src/types/document.ts","../src/context/document-context.ts","../src/constants/dimensions.ts","../src/utils/debug.ts","../src/context/document-reducer.ts","../src/utils/history-manager.ts","../src/i18n/defaults.ts","../src/i18n/pt-BR.ts","../src/i18n/context.tsx","../../../node_modules/.pnpm/zustand@5.0.13_@types+react@18.3.28_react@18.3.1/node_modules/zustand/esm/vanilla.mjs","../../../node_modules/.pnpm/zustand@5.0.13_@types+react@18.3.28_react@18.3.1/node_modules/zustand/esm/react.mjs","../src/lexical/plugins/font-size-plugin.tsx","../src/context/toolbar-style-store.tsx","../src/context/document-provider.tsx","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/context.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/a-large-small.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/bold.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/braces.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/check.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/chevron-down.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/copy-plus.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eraser.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/file-text.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/history.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/italic.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list-indent-decrease.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list-indent-increase.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list-ordered.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/list.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/redo-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/refresh-cw.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/search.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/settings-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/strikethrough.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-center.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-end.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-justify.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/text-align-start.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/type.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/underline.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/undo-2.js","../../../node_modules/.pnpm/lucide-react@1.8.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/x.js","../src/components/EditorSidebar.tsx","../src/components/HistorySidebar.tsx","../src/context/toolbar-config.tsx","../src/extensions/types.ts","../src/extensions/extension-context.tsx","../src/lexical/plugins/font-plugin.tsx","../src/lexical/commands/format-commands.ts","../src/lexical/commands/list-commands.ts","../src/utils/text-style.ts","../src/variables/variable-context.tsx","../src/variables/variable-node.tsx","../src/variables/variable-formatting.ts","../src/lexical/commands/block-commands.ts","../src/components/BlockTypePicker.tsx","../src/components/HeaderFooterToggle.tsx","../src/components/HeaderFooterActions.tsx","../src/components/CanvasControls.tsx","../src/context/toolbar-style-snapshot.ts","../src/components/Toolbar.tsx","../src/constants/page-layout.ts","../src/utils/editor-state-utils.ts","../src/hooks/use-pagination.ts","../src/lexical/theme.ts","../src/lexical/editor-setup.ts","../src/lexical/plugins/tab-indent-plugin.tsx","../src/lexical/plugins/paragraph-indent-plugin.tsx","../src/lexical/plugins/paste-plugin.tsx","../src/lexical/plugins/active-editor-plugin.tsx","../src/lexical/utils/mid-block-split.ts","../src/lexical/plugins/overflow-plugin.tsx","../src/lexical/plugins/history-capture-plugin.tsx","../src/lexical/plugins/page-boundary-plugin.tsx","../src/components/PageBody.tsx","../src/lexical/plugins/height-limit-plugin.tsx","../src/components/PageHeader.tsx","../src/components/PageFooter.tsx","../src/components/PageView.tsx","../src/components/DocumentView.tsx","../src/ast/types.ts","../src/ast/inline-mapper.ts","../src/ast/block-mapper.ts","../src/ast/content-mapper.ts","../src/ast/document-serializer.ts","../src/ast/payload-builder.ts","../src/lexical/utils/import-document-content.ts","../src/utils/document-insert-target.ts","../src/components/Lex4Editor.tsx","../src/hooks/use-overflow-detection.ts","../src/hooks/use-header-footer.ts","../src/extensions/ast-extension.ts","../src/variables/variable-commands.ts","../src/variables/variable-plugin.tsx","../src/components/VariablePanel.tsx","../src/extensions/variables-extension.tsx"],"sourcesContent":["import type { SerializedEditorState } from 'lexical';\n\nexport type PageCounterMode = 'none' | 'header' | 'footer' | 'both';\n\nexport interface PageChromeTemplate {\n headerState: SerializedEditorState | null;\n footerState: SerializedEditorState | null;\n headerHeight: number;\n footerHeight: number;\n}\n\n/** State for a single page in the document */\nexport interface PageState {\n id: string;\n bodyState: SerializedEditorState | null;\n headerState: SerializedEditorState | null;\n footerState: SerializedEditorState | null;\n headerHeight: number;\n footerHeight: number;\n /** Incremented on external body state changes (reflow/undo) to force editor remount */\n bodySyncVersion: number;\n /** Incremented on external header state changes (copy/clear) to force editor remount */\n headerSyncVersion: number;\n /** Incremented on external footer state changes (copy/clear) to force editor remount */\n footerSyncVersion: number;\n}\n\n/** Top-level document state */\nexport interface Lex4Document {\n pages: PageState[];\n headerFooterEnabled: boolean;\n pageCounterMode: PageCounterMode;\n defaultHeaderState: SerializedEditorState | null;\n defaultFooterState: SerializedEditorState | null;\n defaultHeaderHeight: number;\n defaultFooterHeight: number;\n}\n\n/** Creates a default empty page */\nexport function createEmptyPage(id?: string): PageState {\n return {\n id: id ?? crypto.randomUUID(),\n bodyState: null,\n headerState: null,\n footerState: null,\n headerHeight: 0,\n footerHeight: 0,\n bodySyncVersion: 0,\n headerSyncVersion: 0,\n footerSyncVersion: 0,\n };\n}\n\n/** Creates a new page that inherits header/footer chrome from a document default template. */\nexport function createPageFromTemplate(template?: PageChromeTemplate): PageState {\n return {\n ...createEmptyPage(),\n headerState: template?.headerState ?? null,\n footerState: template?.footerState ?? null,\n headerHeight: template?.headerHeight ?? 0,\n footerHeight: template?.footerHeight ?? 0,\n };\n}\n\n/** Creates a default empty document */\nexport function createEmptyDocument(): Lex4Document {\n return {\n pages: [createEmptyPage()],\n headerFooterEnabled: false,\n pageCounterMode: 'none',\n defaultHeaderState: null,\n defaultFooterState: null,\n defaultHeaderHeight: 0,\n defaultFooterHeight: 0,\n };\n}\n","import { createContext, useContext } from 'react';\nimport type { Lex4Document, PageCounterMode } from '../types/document';\nimport type { LexicalEditor } from 'lexical';\nimport type {\n CaretPosition,\n CaretSelection,\n HistoryActionDescriptor,\n HistoryEntry,\n} from '../types/history';\n\n/** All actions the document reducer can handle */\nexport type DocumentAction =\n | { type: 'ADD_PAGE'; afterIndex?: number; page?: import('../types/document').PageState }\n | { type: 'REMOVE_PAGE'; pageId: string }\n | { type: 'UPDATE_PAGE_BODY'; pageId: string; bodyState: import('lexical').SerializedEditorState | null }\n | {\n type: 'UPDATE_PAGE_HEADER_CONTENT';\n pageId: string;\n headerState: import('lexical').SerializedEditorState | null;\n height: number;\n }\n | {\n type: 'UPDATE_PAGE_FOOTER_CONTENT';\n pageId: string;\n footerState: import('lexical').SerializedEditorState | null;\n height: number;\n }\n | { type: 'UPDATE_PAGE_HEADER'; pageId: string; headerState: import('lexical').SerializedEditorState | null }\n | { type: 'UPDATE_PAGE_FOOTER'; pageId: string; footerState: import('lexical').SerializedEditorState | null }\n | { type: 'SET_HEADER_FOOTER_ENABLED'; enabled: boolean }\n | { type: 'SET_PAGE_COUNTER_MODE'; mode: PageCounterMode }\n | { type: 'COPY_HEADER_TO_ALL'; sourcePageId: string }\n | { type: 'COPY_FOOTER_TO_ALL'; sourcePageId: string }\n | { type: 'CLEAR_HEADER'; pageId: string }\n | { type: 'CLEAR_FOOTER'; pageId: string }\n | { type: 'CLEAR_ALL_HEADERS' }\n | { type: 'CLEAR_ALL_FOOTERS' }\n | { type: 'CLEAR_DOCUMENT_CONTENT' }\n | { type: 'SET_HEADER_HEIGHT'; pageId: string; height: number }\n | { type: 'SET_FOOTER_HEIGHT'; pageId: string; height: number }\n | { type: 'SET_DOCUMENT'; document: Lex4Document };\n\n/** Registry of page editors for direct cross-page content manipulation */\nexport interface EditorRegistry {\n register(pageId: string, editor: LexicalEditor): void;\n unregister(pageId: string, editor?: LexicalEditor): void;\n get(pageId: string): LexicalEditor | undefined;\n all(): LexicalEditor[];\n}\n\n/** Shape of the document context value */\nexport interface DocumentContextValue {\n document: Lex4Document;\n dispatch: React.Dispatch<DocumentAction>;\n activePageId: string | null;\n setActivePageId: (id: string | null) => void;\n activeEditor: LexicalEditor | null;\n activeCaretPosition: CaretPosition | null;\n setActiveEditor: (editor: LexicalEditor | null, caretPosition?: CaretPosition | null) => void;\n consumePendingCaretPosition: (caretPosition: CaretPosition) => CaretSelection | null | undefined;\n consumePendingFocusAtEnd: (caretPosition: CaretPosition) => boolean;\n requestFocusAtEnd: (caretPosition: CaretPosition) => void;\n focusAtEndVersion: number;\n globalSelectionActive: boolean;\n setGlobalSelectionActive: (active: boolean) => void;\n historyEntries: HistoryEntry[];\n historyCursor: number;\n canUndo: boolean;\n canRedo: boolean;\n queueHistoryAction: (action: HistoryActionDescriptor | null) => void;\n runHistoryAction: (action: HistoryActionDescriptor, callback: () => void) => void;\n jumpToHistoryEntry: (entryIndex: number) => void;\n clearHistory: (reason?: string) => void;\n historySidebarOpen: boolean;\n setHistorySidebarOpen: (open: boolean) => void;\n undo: () => void;\n redo: () => void;\n editorRegistry: EditorRegistry;\n}\n\nexport const DocumentContext = createContext<DocumentContextValue | null>(null);\n\n/** Hook to access the document context. Throws if used outside provider. */\nexport function useDocument(): DocumentContextValue {\n const ctx = useContext(DocumentContext);\n if (!ctx) {\n throw new Error('useDocument must be used within a DocumentProvider');\n }\n return ctx;\n}\n","/**\n * A4 page dimensions and layout constants.\n *\n * All values derived from the A4 standard (210mm × 297mm)\n * converted to CSS pixels at 96 DPI.\n */\n\nexport const A4_WIDTH_MM = 210;\nexport const A4_HEIGHT_MM = 297;\n\n/** CSS pixels per millimeter at 96 DPI */\nexport const PX_PER_MM = 96 / 25.4;\n\n/** A4 width in CSS pixels (≈794px) */\nexport const A4_WIDTH_PX = Math.round(A4_WIDTH_MM * PX_PER_MM);\n\n/** A4 height in CSS pixels (≈1123px) */\nexport const A4_HEIGHT_PX = Math.round(A4_HEIGHT_MM * PX_PER_MM);\n\n/** Standard A4 margin: 30mm on all sides (European standard) in CSS pixels */\nexport const PAGE_MARGIN_TOP_PX = Math.round(30 * PX_PER_MM);\nexport const PAGE_MARGIN_BOTTOM_PX = Math.round(30 * PX_PER_MM);\nexport const PAGE_MARGIN_LEFT_PX = Math.round(30 * PX_PER_MM);\nexport const PAGE_MARGIN_RIGHT_PX = Math.round(30 * PX_PER_MM);\n\n/** Maximum header height as a ratio of page height */\nexport const MAX_HEADER_RATIO = 0.2;\n\n/** Maximum footer height as a ratio of page height */\nexport const MAX_FOOTER_RATIO = 0.2;\n\n/** Maximum header height in CSS pixels */\nexport const MAX_HEADER_HEIGHT_PX = Math.round(A4_HEIGHT_PX * MAX_HEADER_RATIO);\n\n/** Maximum footer height in CSS pixels */\nexport const MAX_FOOTER_HEIGHT_PX = Math.round(A4_HEIGHT_PX * MAX_FOOTER_RATIO);\n","/**\n * Lex4 Debug Logger\n *\n * Zero-cost when disabled. Enable in the browser console:\n *\n * localStorage.setItem('lex4:debug', '*') // all channels\n * localStorage.setItem('lex4:debug', 'overflow,reducer') // specific channels\n * window.__LEX4_DEBUG__ = true // all channels (session only)\n *\n * Disable:\n * localStorage.removeItem('lex4:debug')\n * window.__LEX4_DEBUG__ = false\n *\n * Channels:\n * reducer — every dispatched action and resulting state\n * overflow — overflow detection, measurement, split decisions\n * registry — editor registry register/unregister/get\n * page — page creation, initial state loading, body changes\n * toolbar — formatting command dispatches\n * header — header height changes, content changes\n * footer — footer height changes, content changes\n * focus — editor focus changes, active editor/page tracking\n */\n\nexport type DebugChannel =\n | 'reducer'\n | 'overflow'\n | 'registry'\n | 'page'\n | 'toolbar'\n | 'header'\n | 'footer'\n | 'focus';\n\nconst CHANNEL_COLORS: Record<DebugChannel, string> = {\n reducer: '#e91e63',\n overflow: '#ff5722',\n registry: '#9c27b0',\n page: '#2196f3',\n toolbar: '#4caf50',\n header: '#ff9800',\n footer: '#795548',\n focus: '#607d8b',\n};\n\ndeclare global {\n interface Window {\n __LEX4_DEBUG__?: boolean | string;\n }\n}\n\nfunction getFlag(): string | boolean | null {\n if (typeof window === 'undefined') return null;\n\n const win = (window as Window).__LEX4_DEBUG__;\n if (win !== undefined && win !== null) return win;\n\n if (typeof localStorage !== 'undefined') {\n return localStorage.getItem('lex4:debug');\n }\n\n return null;\n}\n\nfunction isEnabled(channel: DebugChannel): boolean {\n const flag = getFlag();\n if (!flag) return false;\n if (flag === true || flag === '*' || flag === 'true') return true;\n\n if (typeof flag === 'string') {\n return flag.split(',').some(s => s.trim() === channel);\n }\n\n return false;\n}\n\n/**\n * Log a debug message on the given channel.\n * No-ops instantly when the channel is disabled.\n */\nexport function debug(channel: DebugChannel, message: string, ...data: unknown[]): void {\n if (!isEnabled(channel)) return;\n\n const color = CHANNEL_COLORS[channel];\n const prefix = `%c[lex4:${channel}]`;\n const style = `color: ${color}; font-weight: bold;`;\n\n if (data.length > 0) {\n console.log(prefix, style, message, ...data);\n } else {\n console.log(prefix, style, message);\n }\n}\n\n/**\n * Log a warning on the given channel.\n */\nexport function debugWarn(channel: DebugChannel, message: string, ...data: unknown[]): void {\n if (!isEnabled(channel)) return;\n\n const color = CHANNEL_COLORS[channel];\n const prefix = `%c[lex4:${channel}]`;\n const style = `color: ${color}; font-weight: bold;`;\n\n if (data.length > 0) {\n console.warn(prefix, style, message, ...data);\n } else {\n console.warn(prefix, style, message);\n }\n}\n\n/** Short-id helper: first 8 chars of a UUID for readable logs */\nexport function shortId(id: string): string {\n return id.substring(0, 8);\n}\n","import type { Lex4Document } from '../types/document';\nimport { createEmptyPage } from '../types/document';\nimport type { DocumentAction } from './document-context';\nimport { MAX_HEADER_HEIGHT_PX, MAX_FOOTER_HEIGHT_PX } from '../constants/dimensions';\nimport { debug, shortId } from '../utils/debug';\n\nfunction serializedStateChanged(\n current: import('lexical').SerializedEditorState | null,\n next: import('lexical').SerializedEditorState | null,\n): boolean {\n return JSON.stringify(current) !== JSON.stringify(next);\n}\n\nfunction withExternalSyncVersions(\n currentDocument: Lex4Document,\n nextDocument: Lex4Document,\n): Lex4Document {\n const currentPages = new Map(currentDocument.pages.map(page => [page.id, page]));\n\n return {\n ...nextDocument,\n pages: nextDocument.pages.map(nextPage => {\n const currentPage = currentPages.get(nextPage.id);\n if (!currentPage) {\n return nextPage;\n }\n\n const bodyChanged = serializedStateChanged(currentPage.bodyState, nextPage.bodyState);\n const headerChanged =\n currentPage.headerHeight !== nextPage.headerHeight ||\n serializedStateChanged(currentPage.headerState, nextPage.headerState);\n const footerChanged =\n currentPage.footerHeight !== nextPage.footerHeight ||\n serializedStateChanged(currentPage.footerState, nextPage.footerState);\n\n return {\n ...nextPage,\n bodySyncVersion: bodyChanged ? currentPage.bodySyncVersion + 1 : currentPage.bodySyncVersion,\n headerSyncVersion: headerChanged ? currentPage.headerSyncVersion + 1 : currentPage.headerSyncVersion,\n footerSyncVersion: footerChanged ? currentPage.footerSyncVersion + 1 : currentPage.footerSyncVersion,\n };\n }),\n };\n}\n\n/**\n * Pure reducer for document state.\n * Handles all page-level and document-level mutations.\n */\nexport function documentReducer(state: Lex4Document, action: DocumentAction): Lex4Document {\n switch (action.type) {\n case 'ADD_PAGE': {\n const newPage = action.page ?? createEmptyPage();\n const pages = [...state.pages];\n const insertAt = action.afterIndex !== undefined ? action.afterIndex + 1 : pages.length;\n pages.splice(insertAt, 0, newPage);\n const hasBody = !!(action.page?.bodyState?.root?.children?.length);\n debug('reducer', `ADD_PAGE id=${shortId(newPage.id)} at=${insertAt} withBody=${hasBody} totalPages=${pages.length}`);\n return { ...state, pages };\n }\n\n case 'REMOVE_PAGE': {\n if (state.pages.length <= 1) {\n debug('reducer', `REMOVE_PAGE id=${shortId(action.pageId)} — skipped (last page)`);\n return state;\n }\n debug('reducer', `REMOVE_PAGE id=${shortId(action.pageId)} remaining=${state.pages.length - 1}`);\n return {\n ...state,\n pages: state.pages.filter(p => p.id !== action.pageId),\n };\n }\n\n case 'UPDATE_PAGE_BODY': {\n const childCount = action.bodyState?.root?.children?.length ?? 0;\n debug('reducer', `UPDATE_PAGE_BODY id=${shortId(action.pageId)} children=${childCount}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, bodyState: action.bodyState } : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_HEADER': {\n debug('reducer', `UPDATE_PAGE_HEADER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, headerState: action.headerState } : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_HEADER_CONTENT': {\n const clamped = Math.min(action.height, MAX_HEADER_HEIGHT_PX);\n debug('reducer', `UPDATE_PAGE_HEADER_CONTENT id=${shortId(action.pageId)} height=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, headerState: action.headerState, headerHeight: clamped }\n : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_FOOTER': {\n debug('reducer', `UPDATE_PAGE_FOOTER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, footerState: action.footerState } : p,\n ),\n };\n }\n\n case 'UPDATE_PAGE_FOOTER_CONTENT': {\n const clamped = Math.min(action.height, MAX_FOOTER_HEIGHT_PX);\n debug('reducer', `UPDATE_PAGE_FOOTER_CONTENT id=${shortId(action.pageId)} height=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, footerState: action.footerState, footerHeight: clamped }\n : p,\n ),\n };\n }\n\n case 'SET_HEADER_FOOTER_ENABLED': {\n debug('reducer', `SET_HEADER_FOOTER_ENABLED enabled=${action.enabled}`);\n return { ...state, headerFooterEnabled: action.enabled };\n }\n\n case 'SET_PAGE_COUNTER_MODE': {\n debug('reducer', `SET_PAGE_COUNTER_MODE mode=${action.mode}`);\n return { ...state, pageCounterMode: action.mode };\n }\n\n case 'COPY_HEADER_TO_ALL': {\n debug('reducer', `COPY_HEADER_TO_ALL from=${shortId(action.sourcePageId)}`);\n const source = state.pages.find(p => p.id === action.sourcePageId);\n if (!source) return state;\n return {\n ...state,\n defaultHeaderState: source.headerState,\n defaultHeaderHeight: source.headerHeight,\n pages: state.pages.map(p => ({\n ...p,\n headerState: source.headerState,\n headerHeight: source.headerHeight,\n headerSyncVersion: p.headerSyncVersion + 1,\n })),\n };\n }\n\n case 'COPY_FOOTER_TO_ALL': {\n debug('reducer', `COPY_FOOTER_TO_ALL from=${shortId(action.sourcePageId)}`);\n const source = state.pages.find(p => p.id === action.sourcePageId);\n if (!source) return state;\n return {\n ...state,\n defaultFooterState: source.footerState,\n defaultFooterHeight: source.footerHeight,\n pages: state.pages.map(p => ({\n ...p,\n footerState: source.footerState,\n footerHeight: source.footerHeight,\n footerSyncVersion: p.footerSyncVersion + 1,\n })),\n };\n }\n\n case 'CLEAR_HEADER': {\n debug('reducer', `CLEAR_HEADER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, headerState: null, headerHeight: 0, headerSyncVersion: p.headerSyncVersion + 1 }\n : p,\n ),\n };\n }\n\n case 'CLEAR_FOOTER': {\n debug('reducer', `CLEAR_FOOTER id=${shortId(action.pageId)}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId\n ? { ...p, footerState: null, footerHeight: 0, footerSyncVersion: p.footerSyncVersion + 1 }\n : p,\n ),\n };\n }\n\n case 'CLEAR_ALL_HEADERS': {\n debug('reducer', 'CLEAR_ALL_HEADERS');\n return {\n ...state,\n defaultHeaderState: null,\n defaultHeaderHeight: 0,\n pages: state.pages.map(p => ({\n ...p, headerState: null, headerHeight: 0, headerSyncVersion: p.headerSyncVersion + 1,\n })),\n };\n }\n\n case 'CLEAR_ALL_FOOTERS': {\n debug('reducer', 'CLEAR_ALL_FOOTERS');\n return {\n ...state,\n defaultFooterState: null,\n defaultFooterHeight: 0,\n pages: state.pages.map(p => ({\n ...p, footerState: null, footerHeight: 0, footerSyncVersion: p.footerSyncVersion + 1,\n })),\n };\n }\n\n case 'CLEAR_DOCUMENT_CONTENT': {\n debug('reducer', 'CLEAR_DOCUMENT_CONTENT');\n const firstPage = state.pages[0];\n return {\n ...state,\n pages: [{\n ...createEmptyPage(firstPage?.id),\n headerState: firstPage?.headerState ?? null,\n footerState: firstPage?.footerState ?? null,\n headerHeight: firstPage?.headerHeight ?? 0,\n footerHeight: firstPage?.footerHeight ?? 0,\n bodySyncVersion: (firstPage?.bodySyncVersion ?? 0) + 1,\n headerSyncVersion: firstPage?.headerSyncVersion ?? 0,\n footerSyncVersion: firstPage?.footerSyncVersion ?? 0,\n }],\n };\n }\n\n case 'SET_HEADER_HEIGHT': {\n const clamped = Math.min(action.height, MAX_HEADER_HEIGHT_PX);\n debug('header', `SET_HEADER_HEIGHT id=${shortId(action.pageId)} raw=${action.height} clamped=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, headerHeight: clamped } : p,\n ),\n };\n }\n\n case 'SET_FOOTER_HEIGHT': {\n const clamped = Math.min(action.height, MAX_FOOTER_HEIGHT_PX);\n debug('footer', `SET_FOOTER_HEIGHT id=${shortId(action.pageId)} raw=${action.height} clamped=${clamped}`);\n return {\n ...state,\n pages: state.pages.map(p =>\n p.id === action.pageId ? { ...p, footerHeight: clamped } : p,\n ),\n };\n }\n\n case 'SET_DOCUMENT': {\n debug('reducer', `SET_DOCUMENT pages=${action.document.pages.length}`);\n return withExternalSyncVersions(state, action.document);\n }\n\n default:\n return state;\n }\n}\n","import type { Lex4Document } from '../types/document';\nimport type {\n CaretPosition,\n CaretSelection,\n HistoryActionDescriptor,\n HistoryEntry,\n HistoryState,\n} from '../types/history';\n\nexport const MAX_HISTORY_ACTIONS = 100;\n\nfunction cloneSnapshot(document: Lex4Document): Lex4Document {\n return structuredClone(document);\n}\n\nfunction createHistoryEntry(\n document: Lex4Document,\n descriptor: HistoryActionDescriptor,\n undoSnapshot: Lex4Document,\n caretPosition: CaretPosition | null,\n caretSelection: CaretSelection | null,\n undoCaretPosition: CaretPosition | null,\n undoCaretSelection: CaretSelection | null,\n): HistoryEntry {\n return {\n ...descriptor,\n id: crypto.randomUUID(),\n snapshot: cloneSnapshot(document),\n undoSnapshot: cloneSnapshot(undoSnapshot),\n timestamp: new Date().toISOString(),\n caretPosition,\n caretSelection,\n undoCaretPosition,\n undoCaretSelection,\n };\n}\n\nexport function createHistoryState(\n document: Lex4Document,\n baseCaretPosition: CaretPosition | null = null,\n): HistoryState {\n return {\n baseSnapshot: cloneSnapshot(document),\n baseCaretPosition,\n entries: [],\n cursor: 0,\n };\n}\n\nexport function getHistorySnapshot(history: HistoryState, cursor = history.cursor): Lex4Document {\n if (cursor <= 0) {\n return cloneSnapshot(history.baseSnapshot);\n }\n\n return cloneSnapshot(history.entries[cursor - 1].snapshot);\n}\n\nexport function clearHistoryState(\n document: Lex4Document,\n baseCaretPosition: CaretPosition | null = null,\n): HistoryState {\n return createHistoryState(document, baseCaretPosition);\n}\n\nexport function recordHistoryEntry(\n history: HistoryState,\n nextDocument: Lex4Document,\n descriptor: HistoryActionDescriptor,\n undoSnapshot: Lex4Document,\n caretPosition: CaretPosition | null,\n caretSelection: CaretSelection | null,\n undoCaretPosition: CaretPosition | null,\n undoCaretSelection: CaretSelection | null,\n): HistoryState {\n const entries = history.entries.slice(0, history.cursor);\n entries.push(createHistoryEntry(\n nextDocument,\n descriptor,\n undoSnapshot,\n caretPosition,\n caretSelection,\n undoCaretPosition,\n undoCaretSelection,\n ));\n\n let baseSnapshot = cloneSnapshot(history.baseSnapshot);\n let baseCaretPosition = history.baseCaretPosition;\n let trimmedEntries = entries;\n\n if (trimmedEntries.length > MAX_HISTORY_ACTIONS) {\n baseSnapshot = cloneSnapshot(trimmedEntries[1].undoSnapshot);\n baseCaretPosition = trimmedEntries[1].undoCaretPosition;\n trimmedEntries = trimmedEntries.slice(1);\n }\n\n return {\n baseSnapshot,\n baseCaretPosition,\n entries: trimmedEntries,\n cursor: trimmedEntries.length,\n };\n}\n\nexport function undoHistory(\n history: HistoryState,\n): {\n history: HistoryState;\n document: Lex4Document;\n caretPosition: CaretPosition | null;\n caretSelection: CaretSelection | null;\n} | null {\n if (history.cursor === 0) {\n return null;\n }\n\n const cursor = history.cursor - 1;\n const nextHistory: HistoryState = {\n ...history,\n cursor,\n };\n\n return {\n history: nextHistory,\n document: cloneSnapshot(history.entries[history.cursor - 1].undoSnapshot),\n caretPosition: history.entries[history.cursor - 1].undoCaretPosition,\n caretSelection: history.entries[history.cursor - 1].undoCaretSelection,\n };\n}\n\nexport function redoHistory(\n history: HistoryState,\n): {\n history: HistoryState;\n document: Lex4Document;\n caretPosition: CaretPosition | null;\n caretSelection: CaretSelection | null;\n} | null {\n if (history.cursor >= history.entries.length) {\n return null;\n }\n\n const cursor = history.cursor + 1;\n const nextHistory: HistoryState = {\n ...history,\n cursor,\n };\n\n return {\n history: nextHistory,\n document: getHistorySnapshot(nextHistory),\n caretPosition: nextHistory.entries[cursor - 1]?.caretPosition ?? nextHistory.baseCaretPosition,\n caretSelection: nextHistory.entries[cursor - 1]?.caretSelection ?? null,\n };\n}\n\nexport function jumpToHistoryEntry(\n history: HistoryState,\n entryIndex: number,\n): {\n history: HistoryState;\n document: Lex4Document;\n caretPosition: CaretPosition | null;\n caretSelection: CaretSelection | null;\n} | null {\n if (entryIndex < 0 || entryIndex >= history.entries.length) {\n return null;\n }\n\n const nextHistory: HistoryState = {\n ...history,\n cursor: entryIndex + 1,\n };\n\n return {\n history: nextHistory,\n document: getHistorySnapshot(nextHistory),\n caretPosition: nextHistory.entries[nextHistory.cursor - 1]?.caretPosition ?? nextHistory.baseCaretPosition,\n caretSelection: nextHistory.entries[nextHistory.cursor - 1]?.caretSelection ?? null,\n };\n}\n","import type { Lex4Translations } from './types';\n\nexport const DEFAULT_TRANSLATIONS: Lex4Translations = {\n toolbar: {\n undo: 'Undo',\n redo: 'Redo',\n bold: 'Bold (Ctrl+B)',\n italic: 'Italic (Ctrl+I)',\n underline: 'Underline (Ctrl+U)',\n strikethrough: 'Strikethrough',\n alignLeft: 'Align Left',\n alignCenter: 'Align Center',\n alignRight: 'Align Right',\n justify: 'Justify',\n numberedList: 'Numbered List',\n bulletList: 'Bullet List',\n indent: 'Indent',\n outdent: 'Outdent',\n history: 'History',\n blockType: 'Block type',\n paragraph: 'Paragraph',\n heading1: 'Heading 1',\n heading2: 'Heading 2',\n heading3: 'Heading 3',\n heading4: 'Heading 4',\n heading5: 'Heading 5',\n heading6: 'Heading 6',\n openHistory: 'Open History',\n closeHistory: 'Close History',\n },\n\n history: {\n title: 'History',\n subtitle: 'Word-style session history (last 100 actions)',\n empty: 'No history yet.',\n clearHistory: 'Clear History',\n actions: {\n enabledHeadersFooters: 'Enabled headers and footers',\n disabledHeadersFooters: 'Disabled headers and footers',\n copiedHeaderToAll: 'Copied header to all pages',\n copiedFooterToAll: 'Copied footer to all pages',\n clearedHeader: 'Cleared header',\n clearedFooter: 'Cleared footer',\n clearedAllHeaders: 'Cleared all headers',\n clearedAllFooters: 'Cleared all footers',\n pageCounterSet: 'Page counter set to {{value}}',\n boldApplied: 'Bold applied',\n italicApplied: 'Italic applied',\n underlineApplied: 'Underline applied',\n strikethroughApplied: 'Strikethrough applied',\n alignedLeft: 'Aligned left',\n alignedCenter: 'Aligned center',\n alignedRight: 'Aligned right',\n justifiedText: 'Justified text',\n insertedNumberedList: 'Inserted numbered list',\n insertedBulletList: 'Inserted bullet list',\n indentedContent: 'Indented content',\n outdentedContent: 'Outdented content',\n fontChanged: 'Font changed to {{value}}',\n fontSizeChanged: 'Font size changed to {{value}}pt',\n blockTypeChanged: 'Block type changed to {{value}}',\n insertedDocumentContent: 'Inserted document content',\n },\n },\n\n variables: {\n title: 'Variables',\n available: '{{count}} available',\n refreshVariables: 'Refresh variables',\n searchPlaceholder: 'Search variables...',\n noVariablesFound: 'No variables found',\n insertVariable: 'Insert variable {{key}}',\n openPanel: 'Open Variables',\n closePanel: 'Close Variables',\n newVariable: 'New variable',\n createVariableTitle: 'Create variable',\n createVariableLabel: 'Label',\n createVariableKey: 'Key',\n createVariableGroup: 'Group',\n createVariableType: 'Type',\n createVariableSave: 'Add variable',\n createVariableCancel: 'Cancel',\n createVariableMissingFields: 'Label and key are required.',\n createVariableDuplicateKey: 'Variable {{key}} already exists.',\n },\n\n header: {\n placeholder: 'Header',\n },\n\n footer: {\n placeholder: 'Footer',\n },\n\n body: {\n placeholder: 'Start typing...',\n },\n\n pageCounter: {\n format: 'Page {{current}} of {{total}}',\n },\n\n regions: {\n body: 'body',\n header: 'header',\n footer: 'footer',\n document: 'document',\n toolbar: 'toolbar',\n overflow: 'overflow',\n history: 'history',\n page: 'Page {{page}}',\n },\n\n headerFooter: {\n label: 'Headers & Footers',\n settingsLabel: 'Header and footer settings',\n pageCounter: 'Page counter',\n pageCounterModes: {\n none: 'None',\n header: 'Header',\n footer: 'Footer',\n both: 'Both',\n },\n headerSection: 'Header',\n footerSection: 'Footer',\n copyToAllPages: 'Copy to all pages',\n clearThisPage: 'Clear this page',\n clearAll: 'Clear all',\n },\n\n sidebar: {\n close: 'Close sidebar',\n },\n\n historyLabels: {\n typedText: 'Typed text',\n pastedContent: 'Pasted content',\n insertedLineBreak: 'Inserted line break',\n deletedBackward: 'Deleted backward',\n deletedForward: 'Deleted forward',\n formattedText: 'Formatted text',\n formattedParagraph: 'Formatted paragraph',\n editedBody: 'Edited body',\n editedHeader: 'Edited header',\n editedFooter: 'Edited footer',\n clearedDocumentBody: 'Cleared document body',\n resizedHeader: 'Resized header',\n resizedFooter: 'Resized footer',\n addedPage: 'Added page',\n removedPage: 'Removed page',\n documentReflow: 'Document reflow',\n updatedDocument: 'Updated document',\n },\n};\n","import type { Lex4Translations } from './types';\n\nexport const PT_BR_TRANSLATIONS: Lex4Translations = {\n toolbar: {\n undo: 'Desfazer',\n redo: 'Refazer',\n bold: 'Negrito (Ctrl+B)',\n italic: 'Itálico (Ctrl+I)',\n underline: 'Sublinhado (Ctrl+U)',\n strikethrough: 'Tachado',\n alignLeft: 'Alinhar à Esquerda',\n alignCenter: 'Centralizar',\n alignRight: 'Alinhar à Direita',\n justify: 'Justificar',\n numberedList: 'Lista Numerada',\n bulletList: 'Lista com Marcadores',\n indent: 'Aumentar Recuo',\n outdent: 'Diminuir Recuo',\n history: 'Histórico',\n blockType: 'Tipo de bloco',\n paragraph: 'Parágrafo',\n heading1: 'Título 1',\n heading2: 'Título 2',\n heading3: 'Título 3',\n heading4: 'Título 4',\n heading5: 'Título 5',\n heading6: 'Título 6',\n openHistory: 'Abrir Histórico',\n closeHistory: 'Fechar Histórico',\n },\n\n history: {\n title: 'Histórico',\n subtitle: 'Histórico de sessão (últimas 100 ações)',\n empty: 'Nenhum histórico ainda.',\n clearHistory: 'Limpar Histórico',\n actions: {\n enabledHeadersFooters: 'Cabeçalhos e rodapés ativados',\n disabledHeadersFooters: 'Cabeçalhos e rodapés desativados',\n copiedHeaderToAll: 'Cabeçalho copiado para todas as páginas',\n copiedFooterToAll: 'Rodapé copiado para todas as páginas',\n clearedHeader: 'Cabeçalho limpo',\n clearedFooter: 'Rodapé limpo',\n clearedAllHeaders: 'Todos os cabeçalhos limpos',\n clearedAllFooters: 'Todos os rodapés limpos',\n pageCounterSet: 'Contador de páginas definido como {{value}}',\n boldApplied: 'Negrito aplicado',\n italicApplied: 'Itálico aplicado',\n underlineApplied: 'Sublinhado aplicado',\n strikethroughApplied: 'Tachado aplicado',\n alignedLeft: 'Alinhado à esquerda',\n alignedCenter: 'Centralizado',\n alignedRight: 'Alinhado à direita',\n justifiedText: 'Texto justificado',\n insertedNumberedList: 'Lista numerada inserida',\n insertedBulletList: 'Lista com marcadores inserida',\n indentedContent: 'Conteúdo recuado',\n outdentedContent: 'Recuo reduzido',\n fontChanged: 'Fonte alterada para {{value}}',\n fontSizeChanged: 'Tamanho da fonte alterado para {{value}}pt',\n blockTypeChanged: 'Tipo de bloco alterado para {{value}}',\n insertedDocumentContent: 'Conteúdo do documento inserido',\n },\n },\n\n variables: {\n title: 'Variáveis',\n available: '{{count}} disponíveis',\n refreshVariables: 'Atualizar variáveis',\n searchPlaceholder: 'Buscar variáveis...',\n noVariablesFound: 'Nenhuma variável encontrada',\n insertVariable: 'Inserir variável {{key}}',\n openPanel: 'Abrir Variáveis',\n closePanel: 'Fechar Variáveis',\n newVariable: 'Nova variável',\n createVariableTitle: 'Criar variável',\n createVariableLabel: 'Rótulo',\n createVariableKey: 'Chave',\n createVariableGroup: 'Grupo',\n createVariableType: 'Tipo',\n createVariableSave: 'Adicionar variável',\n createVariableCancel: 'Cancelar',\n createVariableMissingFields: 'Rótulo e chave são obrigatórios.',\n createVariableDuplicateKey: 'A variável {{key}} já existe.',\n },\n\n header: {\n placeholder: 'Cabeçalho',\n },\n\n footer: {\n placeholder: 'Rodapé',\n },\n\n body: {\n placeholder: 'Comece a digitar...',\n },\n\n pageCounter: {\n format: 'Página {{current}} de {{total}}',\n },\n\n regions: {\n body: 'corpo',\n header: 'cabeçalho',\n footer: 'rodapé',\n document: 'documento',\n toolbar: 'barra de ferramentas',\n overflow: 'estouro',\n history: 'histórico',\n page: 'Página {{page}}',\n },\n\n headerFooter: {\n label: 'Cabeçalhos e Rodapés',\n settingsLabel: 'Configurações de cabeçalho e rodapé',\n pageCounter: 'Contador de páginas',\n pageCounterModes: {\n none: 'Nenhum',\n header: 'Cabeçalho',\n footer: 'Rodapé',\n both: 'Ambos',\n },\n headerSection: 'Cabeçalho',\n footerSection: 'Rodapé',\n copyToAllPages: 'Copiar para todas as páginas',\n clearThisPage: 'Limpar esta página',\n clearAll: 'Limpar tudo',\n },\n\n sidebar: {\n close: 'Fechar barra lateral',\n },\n\n historyLabels: {\n typedText: 'Texto digitado',\n pastedContent: 'Conteúdo colado',\n insertedLineBreak: 'Quebra de linha inserida',\n deletedBackward: 'Exclusão para trás',\n deletedForward: 'Exclusão para frente',\n formattedText: 'Texto formatado',\n formattedParagraph: 'Parágrafo formatado',\n editedBody: 'Corpo editado',\n editedHeader: 'Cabeçalho editado',\n editedFooter: 'Rodapé editado',\n clearedDocumentBody: 'Corpo do documento limpo',\n resizedHeader: 'Cabeçalho redimensionado',\n resizedFooter: 'Rodapé redimensionado',\n addedPage: 'Página adicionada',\n removedPage: 'Página removida',\n documentReflow: 'Redistribuição do documento',\n updatedDocument: 'Documento atualizado',\n },\n};\n","import React, { createContext, useContext, useMemo } from 'react';\nimport type { Lex4Translations } from './types';\nimport { DEFAULT_TRANSLATIONS } from './defaults';\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\nfunction deepMerge<T>(\n target: T,\n source: DeepPartial<T>,\n): T {\n if (typeof target !== 'object' || target === null) {\n return (source ?? target) as T;\n }\n const result = { ...target } as Record<string, unknown>;\n for (const key of Object.keys(source as Record<string, unknown>)) {\n const sourceVal = (source as Record<string, unknown>)[key];\n const targetVal = (target as Record<string, unknown>)[key];\n if (\n sourceVal !== undefined &&\n typeof sourceVal === 'object' &&\n sourceVal !== null &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === 'object' &&\n targetVal !== null\n ) {\n result[key] = deepMerge(targetVal, sourceVal as DeepPartial<typeof targetVal>);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n return result as T;\n}\n\nconst TranslationsContext = createContext<Lex4Translations>(DEFAULT_TRANSLATIONS);\n\n/**\n * Returns the active translations. Use inside any editor component\n * to access localized strings.\n */\nexport function useTranslations(): Lex4Translations {\n return useContext(TranslationsContext);\n}\n\n/**\n * Interpolates `{{key}}` placeholders in a translation string.\n *\n * @example\n * interpolate('Font changed to {{value}}', { value: 'Inter' })\n * // => 'Font changed to Inter'\n */\nexport function interpolate(\n template: string,\n params: Record<string, string | number>,\n): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) =>\n String(params[key] ?? `{{${key}}}`),\n );\n}\n\ninterface TranslationsProviderProps {\n translations?: DeepPartial<Lex4Translations>;\n children: React.ReactNode;\n}\n\n/**\n * TranslationsProvider — merges consumer overrides with DEFAULT_TRANSLATIONS.\n */\nexport const TranslationsProvider: React.FC<TranslationsProviderProps> = ({\n translations,\n children,\n}) => {\n const merged = useMemo(\n () =>\n translations\n ? deepMerge(DEFAULT_TRANSLATIONS, translations)\n : DEFAULT_TRANSLATIONS,\n [translations],\n );\n\n return (\n <TranslationsContext.Provider value={merged}>\n {children}\n </TranslationsContext.Provider>\n );\n};\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","import { useCallback, useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nexport const SUPPORTED_FONT_SIZES = [\n 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72,\n] as const;\n\nexport type FontSize = (typeof SUPPORTED_FONT_SIZES)[number];\n\nexport const DEFAULT_FONT_SIZE: FontSize = 12;\n\n/**\n * Applies a font size to the current text selection by merging\n * into the existing inline CSS style on each selected text node.\n */\nexport function applyFontSize(editor: LexicalEditor, size: FontSize): void {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n const existing = node.getStyle();\n const updated = mergeFontSize(existing, size);\n node.setStyle(updated);\n }\n }\n });\n}\n\nfunction mergeFontSize(existingStyle: string, size: FontSize): string {\n const stripped = existingStyle.replace(/font-size:\\s*[^;]+;?\\s*/g, '').trim();\n const sizeDecl = `font-size: ${size}pt`;\n return stripped ? `${stripped}; ${sizeDecl}` : sizeDecl;\n}\n\nfunction extractFontSize(style: string): number | null {\n const match = style.match(/font-size:\\s*(\\d+(?:\\.\\d+)?)\\s*pt/);\n return match ? parseFloat(match[1]) : null;\n}\n\ninterface FontSizePluginProps {\n onFontSizeChange?: (size: number) => void;\n}\n\n/**\n * FontSizePlugin — tracks the current selection's font size\n * and exposes a callback for the toolbar to display the active size.\n */\nexport const FontSizePlugin: React.FC<FontSizePluginProps> = ({ onFontSizeChange }) => {\n const [editor] = useLexicalComposerContext();\n\n const reportFontSize = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const node = selection.getNodes()[0];\n if ($isTextNode(node)) {\n const style = node.getStyle();\n const size = extractFontSize(style);\n onFontSizeChange?.(size ?? DEFAULT_FONT_SIZE);\n }\n });\n }, [editor, onFontSizeChange]);\n\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n reportFontSize();\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, reportFontSize]);\n\n return null;\n};\n","import React, { createContext, useContext, useRef } from 'react';\nimport type { ElementFormatType } from 'lexical';\nimport { useStore } from 'zustand';\nimport { createStore, type StoreApi } from 'zustand/vanilla';\nimport type { BlockType } from '../lexical/commands/block-types';\nimport type { FontFamily } from '../lexical/plugins/font-plugin';\nimport { DEFAULT_FONT_SIZE } from '../lexical/plugins/font-size-plugin';\n\nexport interface ToolbarStyleSnapshot {\n blockType: BlockType;\n fontFamily: FontFamily;\n fontSize: number;\n alignment: ElementFormatType;\n isBold: boolean;\n isItalic: boolean;\n isUnderline: boolean;\n isStrikethrough: boolean;\n hasSelectedVariable: boolean;\n}\n\nexport const DEFAULT_TOOLBAR_STYLE_SNAPSHOT: ToolbarStyleSnapshot = {\n blockType: 'paragraph',\n fontFamily: 'Inter',\n fontSize: DEFAULT_FONT_SIZE,\n alignment: 'left',\n isBold: false,\n isItalic: false,\n isUnderline: false,\n isStrikethrough: false,\n hasSelectedVariable: false,\n};\n\nexport interface ToolbarStyleStoreState extends ToolbarStyleSnapshot {\n setSnapshot: (snapshot: ToolbarStyleSnapshot) => void;\n reset: () => void;\n}\n\nexport function createToolbarStyleStore(\n initialSnapshot: ToolbarStyleSnapshot = DEFAULT_TOOLBAR_STYLE_SNAPSHOT,\n): StoreApi<ToolbarStyleStoreState> {\n return createStore<ToolbarStyleStoreState>((set) => ({\n ...initialSnapshot,\n setSnapshot: (snapshot) => set(snapshot),\n reset: () => set(DEFAULT_TOOLBAR_STYLE_SNAPSHOT),\n }));\n}\n\nconst ToolbarStyleStoreContext = createContext<StoreApi<ToolbarStyleStoreState> | null>(null);\n\nexport const ToolbarStyleStoreProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const storeRef = useRef<StoreApi<ToolbarStyleStoreState> | null>(null);\n\n if (!storeRef.current) {\n storeRef.current = createToolbarStyleStore();\n }\n\n return (\n <ToolbarStyleStoreContext.Provider value={storeRef.current}>\n {children}\n </ToolbarStyleStoreContext.Provider>\n );\n};\n\nexport function useToolbarStyleStore<T>(selector: (state: ToolbarStyleStoreState) => T): T {\n const store = useContext(ToolbarStyleStoreContext);\n if (!store) {\n throw new Error('useToolbarStyleStore must be used within a ToolbarStyleStoreProvider');\n }\n return useStore(store, selector);\n}\n\nexport function useToolbarStyleStoreApi(): StoreApi<ToolbarStyleStoreState> {\n const store = useContext(ToolbarStyleStoreContext);\n if (!store) {\n throw new Error('useToolbarStyleStoreApi must be used within a ToolbarStyleStoreProvider');\n }\n return store;\n}\n","import React, { useReducer, useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport type { Lex4Document } from '../types/document';\nimport type {\n CaretPosition,\n CaretSelection,\n HistoryActionDescriptor,\n HistoryState,\n} from '../types/history';\nimport { $createRangeSelectionFromDom, $getRoot, $getSelection, $isRangeSelection } from 'lexical';\nimport type { LexicalEditor } from 'lexical';\nimport { createEmptyDocument } from '../types/document';\nimport { DocumentContext, type DocumentAction, type EditorRegistry } from './document-context';\nimport { documentReducer } from './document-reducer';\nimport {\n clearHistoryState,\n createHistoryState,\n jumpToHistoryEntry,\n recordHistoryEntry,\n redoHistory,\n undoHistory,\n} from '../utils/history-manager';\nimport { useTranslations, interpolate } from '../i18n';\nimport type { Lex4Translations } from '../i18n/types';\nimport { ToolbarStyleStoreProvider } from './toolbar-style-store';\n\ninterface DocumentProviderProps {\n initialDocument?: Lex4Document;\n onDocumentChange?: (doc: Lex4Document) => void;\n children: React.ReactNode;\n}\n\nconst HISTORY_RESTORE_SUPPRESSION_MS = 100;\nconst HISTORY_BATCH_FLUSH_MS = 16;\n\nfunction cloneDocumentSnapshot(document: Lex4Document): Lex4Document {\n return structuredClone(document);\n}\n\nfunction captureUndoSnapshot(\n document: Lex4Document,\n activeEditor: LexicalEditor | null,\n caretPosition: CaretPosition | null,\n): Lex4Document {\n const snapshot = cloneDocumentSnapshot(document);\n if (!activeEditor || !caretPosition) {\n return snapshot;\n }\n\n const page = snapshot.pages.find(candidate => candidate.id === caretPosition.pageId);\n if (!page) {\n return snapshot;\n }\n\n const editorState = activeEditor.getEditorState().toJSON();\n if (caretPosition.region === 'body') {\n page.bodyState = editorState;\n } else if (caretPosition.region === 'header') {\n page.headerState = editorState;\n } else {\n page.footerState = editorState;\n }\n\n return snapshot;\n}\n\nfunction captureCaretSelection(editor: LexicalEditor | null): CaretSelection | null {\n if (!editor) {\n return null;\n }\n\n const rootElement = editor.getRootElement();\n const domSelection = window.getSelection();\n const selectionInRoot = (node: Node | null) =>\n !!node && !!rootElement && (node === rootElement || rootElement.contains(node));\n const getTextOffset = (node: Node, offset: number) => {\n if (!rootElement) {\n return 0;\n }\n\n const range = document.createRange();\n range.setStart(rootElement, 0);\n range.setEnd(node, offset);\n return range.toString().length;\n };\n\n let caretSelection: CaretSelection | null = null;\n editor.getEditorState().read(() => {\n const selection = $createRangeSelectionFromDom(window.getSelection(), editor) ?? $getSelection();\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n caretSelection = {\n anchor: {\n key: selection.anchor.key,\n offset: selection.anchor.offset,\n type: selection.anchor.type,\n },\n focus: {\n key: selection.focus.key,\n offset: selection.focus.offset,\n type: selection.focus.type,\n },\n anchorTextOffset:\n domSelection && selectionInRoot(domSelection.anchorNode)\n ? getTextOffset(domSelection.anchorNode!, domSelection.anchorOffset)\n : 0,\n focusTextOffset:\n domSelection && selectionInRoot(domSelection.focusNode)\n ? getTextOffset(domSelection.focusNode!, domSelection.focusOffset)\n : 0,\n format: selection.format,\n style: selection.style,\n };\n });\n\n return caretSelection;\n}\n\nfunction getPageNumber(document: Lex4Document, pageId?: string): number | null {\n if (!pageId) {\n return null;\n }\n\n const index = document.pages.findIndex(page => page.id === pageId);\n return index >= 0 ? index + 1 : null;\n}\n\nfunction describeAction(\n action: DocumentAction,\n document: Lex4Document,\n t: Lex4Translations,\n): HistoryActionDescriptor {\n const pageSuffix = (pageId: string) => {\n const num = getPageNumber(document, pageId);\n return num ? ` - ${interpolate(t.regions.page, { page: num })}` : '';\n };\n\n switch (action.type) {\n case 'UPDATE_PAGE_BODY': {\n return {\n label: t.historyLabels.editedBody + pageSuffix(action.pageId),\n source: 'body',\n pageId: action.pageId,\n region: 'body',\n };\n }\n case 'UPDATE_PAGE_HEADER':\n case 'UPDATE_PAGE_HEADER_CONTENT': {\n return {\n label: t.historyLabels.editedHeader + pageSuffix(action.pageId),\n source: 'header',\n pageId: action.pageId,\n region: 'header',\n };\n }\n case 'UPDATE_PAGE_FOOTER':\n case 'UPDATE_PAGE_FOOTER_CONTENT': {\n return {\n label: t.historyLabels.editedFooter + pageSuffix(action.pageId),\n source: 'footer',\n pageId: action.pageId,\n region: 'footer',\n };\n }\n case 'SET_HEADER_FOOTER_ENABLED':\n return {\n label: action.enabled\n ? t.history.actions.enabledHeadersFooters\n : t.history.actions.disabledHeadersFooters,\n source: 'document',\n region: 'document',\n };\n case 'SET_PAGE_COUNTER_MODE':\n return {\n label: interpolate(t.history.actions.pageCounterSet, { value: action.mode }),\n source: 'document',\n region: 'document',\n };\n case 'COPY_HEADER_TO_ALL':\n return {\n label: t.history.actions.copiedHeaderToAll,\n source: 'toolbar',\n pageId: action.sourcePageId,\n region: 'header',\n };\n case 'COPY_FOOTER_TO_ALL':\n return {\n label: t.history.actions.copiedFooterToAll,\n source: 'toolbar',\n pageId: action.sourcePageId,\n region: 'footer',\n };\n case 'CLEAR_HEADER': {\n return {\n label: t.history.actions.clearedHeader + pageSuffix(action.pageId),\n source: 'toolbar',\n pageId: action.pageId,\n region: 'header',\n };\n }\n case 'CLEAR_FOOTER': {\n return {\n label: t.history.actions.clearedFooter + pageSuffix(action.pageId),\n source: 'toolbar',\n pageId: action.pageId,\n region: 'footer',\n };\n }\n case 'CLEAR_ALL_HEADERS':\n return {\n label: t.history.actions.clearedAllHeaders,\n source: 'toolbar',\n region: 'header',\n };\n case 'CLEAR_ALL_FOOTERS':\n return {\n label: t.history.actions.clearedAllFooters,\n source: 'toolbar',\n region: 'footer',\n };\n case 'CLEAR_DOCUMENT_CONTENT':\n return {\n label: t.historyLabels.clearedDocumentBody,\n source: 'document',\n region: 'document',\n };\n case 'SET_HEADER_HEIGHT': {\n return {\n label: t.historyLabels.resizedHeader + pageSuffix(action.pageId),\n source: 'header',\n pageId: action.pageId,\n region: 'header',\n };\n }\n case 'SET_FOOTER_HEIGHT': {\n return {\n label: t.historyLabels.resizedFooter + pageSuffix(action.pageId),\n source: 'footer',\n pageId: action.pageId,\n region: 'footer',\n };\n }\n case 'ADD_PAGE':\n return {\n label: t.historyLabels.addedPage,\n source: 'overflow',\n region: 'document',\n };\n case 'REMOVE_PAGE':\n return {\n label: t.historyLabels.removedPage,\n source: 'overflow',\n region: 'document',\n };\n case 'SET_DOCUMENT':\n return {\n label: t.historyLabels.documentReflow,\n source: 'overflow',\n region: 'document',\n };\n default:\n return {\n label: t.historyLabels.updatedDocument,\n source: 'document',\n region: 'document',\n };\n }\n}\n\nfunction documentsAreEqual(current: Lex4Document, next: Lex4Document): boolean {\n return JSON.stringify(current) === JSON.stringify(next);\n}\n\nexport const DocumentProvider: React.FC<DocumentProviderProps> = ({\n initialDocument,\n onDocumentChange,\n children,\n}) => {\n const initialSnapshot = initialDocument ?? createEmptyDocument();\n const [document, baseDispatch] = useReducer(documentReducer, initialSnapshot);\n const [historyState, setHistoryState] = useState<HistoryState>(() => createHistoryState(initialSnapshot));\n const documentRef = useRef(document);\n const historyStateRef = useRef(historyState);\n const [activePageId, setActivePageIdRaw] = useState<string | null>(\n initialSnapshot.pages[0]?.id ?? null,\n );\n const activePageIdRef = useRef<string | null>(initialSnapshot.pages[0]?.id ?? null);\n const [globalSelectionActive, setGlobalSelectionActive] = useState(false);\n const [historySidebarOpen, setHistorySidebarOpen] = useState(false);\n const [focusAtEndVersion, setFocusAtEndVersion] = useState(0);\n const t = useTranslations();\n const activeEditorRef = useRef<LexicalEditor | null>(null);\n const activeCaretPositionRef = useRef<CaretPosition | null>(null);\n const pendingCaretPositionRef = useRef<CaretPosition | null>(null);\n const pendingCaretSelectionRef = useRef<CaretSelection | null>(null);\n const pendingFocusAtEndRef = useRef<CaretPosition | null>(null);\n const [, forceUpdate] = useState(0);\n const historySuppressedRef = useRef(false);\n const historyReleaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const historyFlushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingHistoryActionRef = useRef<HistoryActionDescriptor | null>(null);\n const pendingUndoSnapshotRef = useRef<Lex4Document | null>(null);\n const pendingUndoCaretPositionRef = useRef<CaretPosition | null>(null);\n const pendingUndoCaretSelectionRef = useRef<CaretSelection | null>(null);\n const historyBatchRef = useRef<{\n descriptor: HistoryActionDescriptor;\n nextDocument: Lex4Document | null;\n undoSnapshot: Lex4Document | null;\n undoCaretPosition: CaretPosition | null;\n undoCaretSelection: CaretSelection | null;\n hasMutation: boolean;\n } | null>(null);\n\n const editorMapRef = useRef(new Map<string, LexicalEditor>());\n const editorRegistry: EditorRegistry = useMemo(() => ({\n register: (pageId: string, editor: LexicalEditor) => {\n editorMapRef.current.set(pageId, editor);\n },\n unregister: (pageId: string, editor?: LexicalEditor) => {\n const currentEditor = editorMapRef.current.get(pageId);\n if (editor && currentEditor && currentEditor !== editor) {\n return;\n }\n\n editorMapRef.current.delete(pageId);\n },\n get: (pageId: string) => editorMapRef.current.get(pageId),\n all: () => Array.from(editorMapRef.current.values()),\n }), []);\n\n const setActivePageId = useCallback((id: string | null) => {\n activePageIdRef.current = id;\n setActivePageIdRaw(id);\n }, []);\n\n const setActiveEditor = useCallback((\n editor: LexicalEditor | null,\n caretPosition: CaretPosition | null = null,\n ) => {\n activeEditorRef.current = editor;\n activeCaretPositionRef.current = caretPosition;\n forceUpdate(n => n + 1);\n }, []);\n\n const focusEditorAtEnd = useCallback((editor: LexicalEditor, caretPosition: CaretPosition) => {\n requestAnimationFrame(() => {\n setActivePageId(caretPosition.pageId);\n setActiveEditor(editor, caretPosition);\n editor.focus(() => {\n editor.update(() => {\n $getRoot().selectEnd();\n });\n });\n });\n }, [setActiveEditor, setActivePageId]);\n\n const consumePendingCaretPosition = useCallback((caretPosition: CaretPosition) => {\n const pendingCaretPosition = pendingCaretPositionRef.current;\n if (\n !pendingCaretPosition\n || pendingCaretPosition.pageId !== caretPosition.pageId\n || pendingCaretPosition.region !== caretPosition.region\n ) {\n return undefined;\n }\n\n pendingCaretPositionRef.current = null;\n const pendingCaretSelection = pendingCaretSelectionRef.current;\n pendingCaretSelectionRef.current = null;\n return pendingCaretSelection;\n }, []);\n\n const consumePendingFocusAtEnd = useCallback((caretPosition: CaretPosition) => {\n const pendingFocusAtEnd = pendingFocusAtEndRef.current;\n if (\n !pendingFocusAtEnd\n || pendingFocusAtEnd.pageId !== caretPosition.pageId\n || pendingFocusAtEnd.region !== caretPosition.region\n ) {\n return false;\n }\n\n pendingFocusAtEndRef.current = null;\n return true;\n }, []);\n\n const requestFocusAtEnd = useCallback((caretPosition: CaretPosition) => {\n pendingCaretPositionRef.current = null;\n pendingCaretSelectionRef.current = null;\n\n if (caretPosition.region === 'body') {\n const editor = editorRegistry.get(caretPosition.pageId);\n if (editor) {\n pendingFocusAtEndRef.current = null;\n focusEditorAtEnd(editor, caretPosition);\n return;\n }\n }\n\n pendingFocusAtEndRef.current = caretPosition;\n setFocusAtEndVersion(version => version + 1);\n }, [editorRegistry, focusEditorAtEnd]);\n\n const flushHistoryBatch = useCallback(() => {\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n historyFlushTimerRef.current = null;\n }\n\n const batch = historyBatchRef.current;\n historyBatchRef.current = null;\n pendingHistoryActionRef.current = null;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n\n if (!batch || historySuppressedRef.current || !batch.hasMutation || !batch.nextDocument) {\n return;\n }\n\n const undoSnapshot = batch.undoSnapshot ?? batch.nextDocument;\n\n setHistoryState(previousHistory => {\n const nextHistory = recordHistoryEntry(\n previousHistory,\n batch.nextDocument as Lex4Document,\n batch.descriptor,\n undoSnapshot,\n activeCaretPositionRef.current,\n captureCaretSelection(activeEditorRef.current),\n batch.undoCaretPosition,\n batch.undoCaretSelection,\n );\n historyStateRef.current = nextHistory;\n return nextHistory;\n });\n }, []);\n\n const scheduleHistoryBatchFlush = useCallback(() => {\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n }\n\n historyFlushTimerRef.current = setTimeout(() => {\n flushHistoryBatch();\n }, HISTORY_BATCH_FLUSH_MS);\n }, [flushHistoryBatch]);\n\n const queueHistoryAction = useCallback((action: HistoryActionDescriptor | null) => {\n pendingHistoryActionRef.current = action;\n pendingUndoSnapshotRef.current = action\n ? captureUndoSnapshot(\n documentRef.current,\n activeEditorRef.current,\n activeCaretPositionRef.current,\n )\n : null;\n pendingUndoCaretPositionRef.current = action ? activeCaretPositionRef.current : null;\n pendingUndoCaretSelectionRef.current = action ? captureCaretSelection(activeEditorRef.current) : null;\n }, []);\n\n const runHistoryAction = useCallback((action: HistoryActionDescriptor, callback: () => void) => {\n if (historyBatchRef.current) {\n callback();\n return;\n }\n\n historyBatchRef.current = {\n descriptor: action,\n nextDocument: null,\n undoSnapshot: captureUndoSnapshot(\n documentRef.current,\n activeEditorRef.current,\n activeCaretPositionRef.current,\n ),\n undoCaretPosition: activeCaretPositionRef.current,\n undoCaretSelection: captureCaretSelection(activeEditorRef.current),\n hasMutation: false,\n };\n\n pendingHistoryActionRef.current = action;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n\n try {\n callback();\n } finally {\n scheduleHistoryBatchFlush();\n }\n }, [scheduleHistoryBatchFlush]);\n\n const suppressHistoryTemporarily = useCallback(() => {\n historySuppressedRef.current = true;\n pendingHistoryActionRef.current = null;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n historyBatchRef.current = null;\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n historyFlushTimerRef.current = null;\n }\n if (historyReleaseTimerRef.current) {\n clearTimeout(historyReleaseTimerRef.current);\n }\n historyReleaseTimerRef.current = setTimeout(() => {\n historySuppressedRef.current = false;\n historyReleaseTimerRef.current = null;\n }, HISTORY_RESTORE_SUPPRESSION_MS);\n }, []);\n\n const dispatch = useCallback((action: DocumentAction) => {\n const currentDocument = documentRef.current;\n const nextDocument = documentReducer(currentDocument, action);\n const changed = !documentsAreEqual(currentDocument, nextDocument);\n const suppressPassiveBodyHistory =\n action.type === 'UPDATE_PAGE_BODY'\n && action.pageId !== activePageIdRef.current\n && !historyBatchRef.current\n && !pendingHistoryActionRef.current;\n\n documentRef.current = nextDocument;\n\n if (changed && !historySuppressedRef.current && !suppressPassiveBodyHistory) {\n if (historyBatchRef.current) {\n historyBatchRef.current.nextDocument = cloneDocumentSnapshot(nextDocument);\n historyBatchRef.current.hasMutation = true;\n scheduleHistoryBatchFlush();\n } else if (pendingHistoryActionRef.current) {\n historyBatchRef.current = {\n descriptor: pendingHistoryActionRef.current,\n nextDocument: cloneDocumentSnapshot(nextDocument),\n undoSnapshot: pendingUndoSnapshotRef.current,\n undoCaretPosition: pendingUndoCaretPositionRef.current,\n undoCaretSelection: pendingUndoCaretSelectionRef.current,\n hasMutation: true,\n };\n scheduleHistoryBatchFlush();\n } else {\n const descriptor = describeAction(action, currentDocument, t);\n setHistoryState(previousHistory => {\n const nextHistory = recordHistoryEntry(\n previousHistory,\n nextDocument,\n descriptor,\n captureUndoSnapshot(\n currentDocument,\n activeEditorRef.current,\n activeCaretPositionRef.current,\n ),\n activeCaretPositionRef.current,\n captureCaretSelection(activeEditorRef.current),\n activeCaretPositionRef.current,\n captureCaretSelection(activeEditorRef.current),\n );\n historyStateRef.current = nextHistory;\n return nextHistory;\n });\n }\n } else {\n pendingHistoryActionRef.current = null;\n pendingUndoSnapshotRef.current = null;\n pendingUndoCaretPositionRef.current = null;\n pendingUndoCaretSelectionRef.current = null;\n }\n\n baseDispatch(action);\n }, [scheduleHistoryBatchFlush]);\n\n const restoreDocument = useCallback((\n snapshot: Lex4Document,\n caretPosition: CaretPosition | null,\n caretSelection: CaretSelection | null,\n ) => {\n suppressHistoryTemporarily();\n pendingCaretPositionRef.current = caretPosition;\n pendingCaretSelectionRef.current = caretSelection;\n activeEditorRef.current = null;\n activeCaretPositionRef.current = caretPosition;\n forceUpdate(n => n + 1);\n documentRef.current = cloneDocumentSnapshot(snapshot);\n baseDispatch({ type: 'SET_DOCUMENT', document: cloneDocumentSnapshot(snapshot) });\n }, [suppressHistoryTemporarily]);\n\n const undo = useCallback(() => {\n flushHistoryBatch();\n const result = undoHistory(historyStateRef.current);\n if (!result) {\n return;\n }\n\n historyStateRef.current = result.history;\n setHistoryState(result.history);\n restoreDocument(result.document, result.caretPosition, result.caretSelection);\n }, [flushHistoryBatch, restoreDocument]);\n\n const redo = useCallback(() => {\n flushHistoryBatch();\n const result = redoHistory(historyStateRef.current);\n if (!result) {\n return;\n }\n\n historyStateRef.current = result.history;\n setHistoryState(result.history);\n restoreDocument(result.document, result.caretPosition, result.caretSelection);\n }, [flushHistoryBatch, restoreDocument]);\n\n const clearHistory = useCallback(() => {\n flushHistoryBatch();\n const nextHistory = clearHistoryState(documentRef.current, activeCaretPositionRef.current);\n historyStateRef.current = nextHistory;\n setHistoryState(nextHistory);\n }, [flushHistoryBatch]);\n\n const handleJumpToHistoryEntry = useCallback((entryIndex: number) => {\n flushHistoryBatch();\n const result = jumpToHistoryEntry(historyStateRef.current, entryIndex);\n if (!result) {\n return;\n }\n\n historyStateRef.current = result.history;\n setHistoryState(result.history);\n restoreDocument(result.document, result.caretPosition, result.caretSelection);\n }, [flushHistoryBatch, restoreDocument]);\n\n useEffect(() => {\n documentRef.current = document;\n onDocumentChange?.(document);\n }, [document, onDocumentChange]);\n\n useEffect(() => {\n historyStateRef.current = historyState;\n }, [historyState]);\n\n useEffect(() => {\n const firstPageId = document.pages[0]?.id ?? null;\n const activePageStillExists = activePageId !== null\n && document.pages.some(page => page.id === activePageId);\n\n if (!activePageStillExists) {\n activePageIdRef.current = firstPageId;\n setActivePageIdRaw(firstPageId);\n activeEditorRef.current = null;\n activeCaretPositionRef.current = null;\n forceUpdate(n => n + 1);\n }\n }, [activePageId, document.pages]);\n\n useEffect(\n () => () => {\n if (historyFlushTimerRef.current) {\n clearTimeout(historyFlushTimerRef.current);\n }\n if (historyReleaseTimerRef.current) {\n clearTimeout(historyReleaseTimerRef.current);\n }\n },\n [],\n );\n\n return (\n <DocumentContext.Provider value={{\n document,\n dispatch,\n activePageId,\n setActivePageId,\n activeEditor: activeEditorRef.current,\n activeCaretPosition: activeCaretPositionRef.current,\n consumePendingCaretPosition,\n consumePendingFocusAtEnd,\n requestFocusAtEnd,\n focusAtEndVersion,\n setActiveEditor,\n globalSelectionActive,\n setGlobalSelectionActive,\n historyEntries: historyState.entries,\n historyCursor: historyState.cursor,\n canUndo: historyState.cursor > 0,\n canRedo: historyState.cursor < historyState.entries.length,\n queueHistoryAction,\n runHistoryAction,\n jumpToHistoryEntry: handleJumpToHistoryEntry,\n clearHistory,\n historySidebarOpen,\n setHistorySidebarOpen,\n undo,\n redo,\n editorRegistry,\n }}>\n <ToolbarStyleStoreProvider>\n {children}\n </ToolbarStyleStoreProvider>\n </DocumentContext.Provider>\n );\n};\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.js';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.js.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.js.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.js';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.js';\nimport { useLucideContext } from './context.js';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.js';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.js';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m15 16 2.536-7.328a1.02 1.02 1 0 1 1.928 0L22 16\", key: \"xik6mr\" }],\n [\"path\", { d: \"M15.697 14h5.606\", key: \"1stdlc\" }],\n [\"path\", { d: \"m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16\", key: \"d5nyq2\" }],\n [\"path\", { d: \"M3.304 13h6.392\", key: \"1q3zxz\" }]\n];\nconst ALargeSmall = createLucideIcon(\"a-large-small\", __iconNode);\n\nexport { __iconNode, ALargeSmall as default };\n//# sourceMappingURL=a-large-small.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\", key: \"mg9rjx\" }\n ]\n];\nconst Bold = createLucideIcon(\"bold\", __iconNode);\n\nexport { __iconNode, Bold as default };\n//# sourceMappingURL=bold.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n { d: \"M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1\", key: \"ezmyqa\" }\n ],\n [\n \"path\",\n {\n d: \"M16 21h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1\",\n key: \"e1hn23\"\n }\n ]\n];\nconst Braces = createLucideIcon(\"braces\", __iconNode);\n\nexport { __iconNode, Braces as default };\n//# sourceMappingURL=braces.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]];\nconst Check = createLucideIcon(\"check\", __iconNode);\n\nexport { __iconNode, Check as default };\n//# sourceMappingURL=check.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]];\nconst ChevronDown = createLucideIcon(\"chevron-down\", __iconNode);\n\nexport { __iconNode, ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"15\", x2: \"15\", y1: \"12\", y2: \"18\", key: \"1p7wdc\" }],\n [\"line\", { x1: \"12\", x2: \"18\", y1: \"15\", y2: \"15\", key: \"1nscbv\" }],\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n];\nconst CopyPlus = createLucideIcon(\"copy-plus\", __iconNode);\n\nexport { __iconNode, CopyPlus as default };\n//# sourceMappingURL=copy-plus.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21\",\n key: \"g5wo59\"\n }\n ],\n [\"path\", { d: \"m5.082 11.09 8.828 8.828\", key: \"1wx5vj\" }]\n];\nconst Eraser = createLucideIcon(\"eraser\", __iconNode);\n\nexport { __iconNode, Eraser as default };\n//# sourceMappingURL=eraser.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M10 9H8\", key: \"b1mrlr\" }],\n [\"path\", { d: \"M16 13H8\", key: \"t4e002\" }],\n [\"path\", { d: \"M16 17H8\", key: \"z1uh3a\" }]\n];\nconst FileText = createLucideIcon(\"file-text\", __iconNode);\n\nexport { __iconNode, FileText as default };\n//# sourceMappingURL=file-text.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }],\n [\"path\", { d: \"M12 7v5l4 2\", key: \"1fdv2h\" }]\n];\nconst History = createLucideIcon(\"history\", __iconNode);\n\nexport { __iconNode, History as default };\n//# sourceMappingURL=history.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n];\nconst Italic = createLucideIcon(\"italic\", __iconNode);\n\nexport { __iconNode, Italic as default };\n//# sourceMappingURL=italic.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H11\", key: \"us1j55\" }],\n [\"path\", { d: \"M21 12H11\", key: \"wd7e0v\" }],\n [\"path\", { d: \"M21 19H11\", key: \"saa85w\" }],\n [\"path\", { d: \"m7 8-4 4 4 4\", key: \"o5hrat\" }]\n];\nconst ListIndentDecrease = createLucideIcon(\"list-indent-decrease\", __iconNode);\n\nexport { __iconNode, ListIndentDecrease as default };\n//# sourceMappingURL=list-indent-decrease.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H11\", key: \"us1j55\" }],\n [\"path\", { d: \"M21 12H11\", key: \"wd7e0v\" }],\n [\"path\", { d: \"M21 19H11\", key: \"saa85w\" }],\n [\"path\", { d: \"m3 8 4 4-4 4\", key: \"1a3j6y\" }]\n];\nconst ListIndentIncrease = createLucideIcon(\"list-indent-increase\", __iconNode);\n\nexport { __iconNode, ListIndentIncrease as default };\n//# sourceMappingURL=list-indent-increase.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M11 5h10\", key: \"1cz7ny\" }],\n [\"path\", { d: \"M11 12h10\", key: \"1438ji\" }],\n [\"path\", { d: \"M11 19h10\", key: \"11t30w\" }],\n [\"path\", { d: \"M4 4h1v5\", key: \"10yrso\" }],\n [\"path\", { d: \"M4 9h2\", key: \"r1h2o0\" }],\n [\"path\", { d: \"M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02\", key: \"xtkcd5\" }]\n];\nconst ListOrdered = createLucideIcon(\"list-ordered\", __iconNode);\n\nexport { __iconNode, ListOrdered as default };\n//# sourceMappingURL=list-ordered.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 5h.01\", key: \"18ugdj\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M3 19h.01\", key: \"noohij\" }],\n [\"path\", { d: \"M8 5h13\", key: \"1pao27\" }],\n [\"path\", { d: \"M8 12h13\", key: \"1za7za\" }],\n [\"path\", { d: \"M8 19h13\", key: \"m83p4d\" }]\n];\nconst List = createLucideIcon(\"list\", __iconNode);\n\nexport { __iconNode, List as default };\n//# sourceMappingURL=list.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m15 14 5-5-5-5\", key: \"12vg1m\" }],\n [\"path\", { d: \"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13\", key: \"6uklza\" }]\n];\nconst Redo2 = createLucideIcon(\"redo-2\", __iconNode);\n\nexport { __iconNode, Redo2 as default };\n//# sourceMappingURL=redo-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\", key: \"v9h5vc\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }],\n [\"path\", { d: \"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\", key: \"3uifl3\" }],\n [\"path\", { d: \"M8 16H3v5\", key: \"1cv678\" }]\n];\nconst RefreshCw = createLucideIcon(\"refresh-cw\", __iconNode);\n\nexport { __iconNode, RefreshCw as default };\n//# sourceMappingURL=refresh-cw.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M14 17H5\", key: \"gfn3mx\" }],\n [\"path\", { d: \"M19 7h-9\", key: \"6i9tg\" }],\n [\"circle\", { cx: \"17\", cy: \"17\", r: \"3\", key: \"18b49y\" }],\n [\"circle\", { cx: \"7\", cy: \"7\", r: \"3\", key: \"dfmy0x\" }]\n];\nconst Settings2 = createLucideIcon(\"settings-2\", __iconNode);\n\nexport { __iconNode, Settings2 as default };\n//# sourceMappingURL=settings-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 4H9a3 3 0 0 0-2.83 4\", key: \"43sutm\" }],\n [\"path\", { d: \"M14 12a4 4 0 0 1 0 8H6\", key: \"nlfj13\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"12\", y2: \"12\", key: \"1e0a9i\" }]\n];\nconst Strikethrough = createLucideIcon(\"strikethrough\", __iconNode);\n\nexport { __iconNode, Strikethrough as default };\n//# sourceMappingURL=strikethrough.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }],\n [\"path\", { d: \"M19 19H5\", key: \"vjpgq2\" }]\n];\nconst TextAlignCenter = createLucideIcon(\"text-align-center\", __iconNode);\n\nexport { __iconNode, TextAlignCenter as default };\n//# sourceMappingURL=text-align-center.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M21 19H7\", key: \"4cu937\" }]\n];\nconst TextAlignEnd = createLucideIcon(\"text-align-end\", __iconNode);\n\nexport { __iconNode, TextAlignEnd as default };\n//# sourceMappingURL=text-align-end.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 5h18\", key: \"1u36vt\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }],\n [\"path\", { d: \"M3 19h18\", key: \"awlh7x\" }]\n];\nconst TextAlignJustify = createLucideIcon(\"text-align-justify\", __iconNode);\n\nexport { __iconNode, TextAlignJustify as default };\n//# sourceMappingURL=text-align-justify.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M17 19H3\", key: \"z6ezky\" }]\n];\nconst TextAlignStart = createLucideIcon(\"text-align-start\", __iconNode);\n\nexport { __iconNode, TextAlignStart as default };\n//# sourceMappingURL=text-align-start.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 4v16\", key: \"1654pz\" }],\n [\"path\", { d: \"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\", key: \"e0r10z\" }],\n [\"path\", { d: \"M9 20h6\", key: \"s66wpe\" }]\n];\nconst Type = createLucideIcon(\"type\", __iconNode);\n\nexport { __iconNode, Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M6 4v6a6 6 0 0 0 12 0V4\", key: \"9kb039\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"20\", y2: \"20\", key: \"nun2al\" }]\n];\nconst Underline = createLucideIcon(\"underline\", __iconNode);\n\nexport { __iconNode, Underline as default };\n//# sourceMappingURL=underline.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M9 14 4 9l5-5\", key: \"102s5s\" }],\n [\"path\", { d: \"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11\", key: \"f3b9sd\" }]\n];\nconst Undo2 = createLucideIcon(\"undo-2\", __iconNode);\n\nexport { __iconNode, Undo2 as default };\n//# sourceMappingURL=undo-2.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.js.map\n","import React from 'react';\nimport { X } from 'lucide-react';\nimport { useTranslations } from '../i18n';\n\ninterface EditorSidebarProps {\n title: string;\n subtitle?: string;\n open: boolean;\n onClose?: () => void;\n headerActions?: React.ReactNode;\n testId?: string;\n children: React.ReactNode;\n}\n\nexport const EditorSidebar: React.FC<EditorSidebarProps> = ({\n title,\n subtitle,\n open,\n onClose,\n headerActions,\n testId = 'editor-sidebar',\n children,\n}) => {\n const t = useTranslations();\n\n if (!open) {\n return null;\n }\n\n return (\n <aside\n className=\"lex4-sidebar\"\n data-testid={testId}\n >\n <div className=\"lex4-sidebar-header\">\n <div>\n <h2 className=\"lex4-sidebar-title\">{title}</h2>\n {subtitle && (\n <p className=\"lex4-sidebar-subtitle\">{subtitle}</p>\n )}\n </div>\n <div className=\"lex4-sidebar-actions\">\n {headerActions}\n {onClose && (\n <button\n type=\"button\"\n className=\"lex4-sidebar-action-btn\"\n data-testid=\"close-editor-sidebar\"\n onClick={onClose}\n aria-label={t.sidebar.close}\n >\n <X size={14} />\n </button>\n )}\n </div>\n </div>\n <div className=\"lex4-sidebar-body\">\n {children}\n </div>\n </aside>\n );\n};\n","import React from 'react';\nimport { Trash2 } from 'lucide-react';\nimport { useDocument } from '../context/document-context';\nimport { EditorSidebar } from './EditorSidebar';\nimport { useTranslations } from '../i18n';\n\nfunction formatTimestamp(timestamp: string): string {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nexport const HistorySidebar: React.FC = () => {\n const {\n clearHistory,\n historyEntries,\n historyCursor,\n historySidebarOpen,\n jumpToHistoryEntry,\n setHistorySidebarOpen,\n } = useDocument();\n const t = useTranslations();\n\n const visibleEntries = historyEntries.slice().reverse();\n\n const headerActions = (\n <button\n type=\"button\"\n title={t.history.clearHistory}\n aria-label={t.history.clearHistory}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => clearHistory('manual')}\n className=\"lex4-sidebar-action-btn\"\n data-testid=\"clear-history\"\n >\n <Trash2 size={13} />\n </button>\n );\n\n return (\n <EditorSidebar\n title={t.history.title}\n subtitle={t.history.subtitle}\n open={historySidebarOpen}\n onClose={() => setHistorySidebarOpen(false)}\n headerActions={headerActions}\n testId=\"history-sidebar\"\n >\n {visibleEntries.length === 0 ? (\n <div\n className=\"lex4-history-empty\"\n data-testid=\"history-empty\"\n >\n {t.history.empty}\n </div>\n ) : (\n <ol className=\"lex4-history-list\" data-testid=\"history-entry-list\">\n {visibleEntries.map((entry, reversedIndex) => {\n const actualIndex = historyEntries.length - reversedIndex - 1;\n const isCurrent = actualIndex === historyCursor - 1;\n\n return (\n <li key={entry.id}>\n <button\n type=\"button\"\n className={`lex4-history-entry ${\n isCurrent ? 'active' : ''\n }`}\n data-testid={`history-entry-${actualIndex}`}\n data-history-current={isCurrent ? 'true' : 'false'}\n onClick={() => jumpToHistoryEntry(actualIndex)}\n >\n <div className=\"lex4-history-entry-row\">\n <div className=\"lex4-history-entry-dot\" />\n <div className=\"lex4-history-entry-content\">\n <div className=\"lex4-history-entry-label\">\n {entry.label}\n </div>\n <div className=\"lex4-history-entry-meta\">\n <span className=\"lex4-history-entry-source\">\n {t.regions[entry.source as keyof typeof t.regions] ?? entry.source}\n </span>\n <span className=\"lex4-history-entry-meta-dot\">·</span>\n <span className=\"lex4-history-entry-time\">\n {formatTimestamp(entry.timestamp)}\n </span>\n </div>\n </div>\n </div>\n </button>\n </li>\n );\n })}\n </ol>\n )}\n </EditorSidebar>\n );\n};\n","import React, { createContext, useContext, useMemo } from 'react';\nimport type { Lex4ToolbarConfig, Lex4ToolbarControlConfig } from '../types/editor-props';\n\nexport interface ResolvedLex4ToolbarControlConfig {\n visible: boolean;\n showLabel: boolean;\n}\n\nexport interface ResolvedLex4ToolbarConfig {\n history: ResolvedLex4ToolbarControlConfig;\n variables: ResolvedLex4ToolbarControlConfig;\n headerFooter: ResolvedLex4ToolbarControlConfig;\n}\n\nconst DEFAULT_TOOLBAR_CONTROL_CONFIG: ResolvedLex4ToolbarControlConfig = {\n visible: true,\n showLabel: true,\n};\n\nconst DEFAULT_TOOLBAR_CONFIG: ResolvedLex4ToolbarConfig = {\n history: DEFAULT_TOOLBAR_CONTROL_CONFIG,\n variables: DEFAULT_TOOLBAR_CONTROL_CONFIG,\n headerFooter: DEFAULT_TOOLBAR_CONTROL_CONFIG,\n};\n\nconst ToolbarConfigContext = createContext<ResolvedLex4ToolbarConfig>(DEFAULT_TOOLBAR_CONFIG);\n\nfunction resolveControlConfig(\n config?: Lex4ToolbarControlConfig,\n): ResolvedLex4ToolbarControlConfig {\n return {\n visible: config?.visible ?? true,\n showLabel: config?.showLabel ?? true,\n };\n}\n\nexport function normalizeToolbarConfig(\n config?: Lex4ToolbarConfig,\n): ResolvedLex4ToolbarConfig {\n return {\n history: resolveControlConfig(config?.history),\n variables: resolveControlConfig(config?.variables),\n headerFooter: resolveControlConfig(config?.headerFooter),\n };\n}\n\nexport const ToolbarConfigProvider: React.FC<{\n toolbar?: Lex4ToolbarConfig;\n children: React.ReactNode;\n}> = ({ toolbar, children }) => {\n const resolvedConfig = useMemo(() => normalizeToolbarConfig(toolbar), [toolbar]);\n return (\n <ToolbarConfigContext.Provider value={resolvedConfig}>\n {children}\n </ToolbarConfigContext.Provider>\n );\n};\n\nexport function useToolbarConfig(): ResolvedLex4ToolbarConfig {\n return useContext(ToolbarConfigContext);\n}\n","import type { EditorThemeClasses, Klass, LexicalNode } from 'lexical';\nimport type { Lex4Document } from '../types/document';\n\n/**\n * Context passed to extension handleMethods factories.\n * Provides read access to editor state so extensions can build\n * their imperative API methods.\n */\nexport interface ExtensionContext {\n getDocument: () => Lex4Document;\n getActiveEditor: () => import('lexical').LexicalEditor | null;\n getExtensionState: <T = unknown>(key: string) => T | undefined;\n setExtensionState: <T = unknown>(key: string, value: T) => void;\n}\n\n/**\n * Lex4Extension — Plugin-based extension contract.\n *\n * Extensions add capabilities to the editor without requiring\n * hard-wired imports. Each extension can contribute:\n * - Lexical nodes (custom block/inline node types)\n * - Body plugins (rendered inside every page's LexicalComposer)\n * - Toolbar items (rendered in the toolbar extension slot)\n * - Side panels (rendered to the right of the document area)\n * - Provider wrappers (React context providers wrapping the editor)\n * - Imperative handle methods (merged into the ref API)\n */\nexport interface Lex4Extension {\n /** Unique extension name used for identification. */\n name: string;\n\n /** Additional Lexical node classes to register in every editor instance. */\n nodes?: Klass<LexicalNode>[];\n\n /** Plugin components rendered inside each page body's LexicalComposer. */\n bodyPlugins?: React.ComponentType[];\n\n /** Components rendered in the toolbar's extension slot. */\n toolbarItems?: React.ComponentType[];\n\n /** Components rendered in the toolbar's right-aligned end area (next to history toggle). */\n toolbarEndItems?: React.ComponentType[];\n\n /** Component rendered as a right side panel. */\n sidePanel?: React.ComponentType;\n\n /**\n * Provider component that wraps the editor tree.\n * Useful for injecting React contexts.\n */\n provider?: React.ComponentType<{ children: React.ReactNode }>;\n\n /**\n * Lexical editor theme overrides contributed by this extension.\n * Merged into the base theme.\n */\n themeOverrides?: Partial<EditorThemeClasses>;\n\n /**\n * CSS custom property overrides applied on the `.lex4-editor` root.\n * Use to retheme the editor — e.g. `{ '--color-primary': 'hsl(350 80% 50%)' }`.\n */\n cssVariables?: Record<string, string>;\n\n /**\n * Extra CSS class name(s) added to the `.lex4-editor` root element.\n * Useful for scoping extension-specific styles.\n */\n rootClassName?: string;\n\n /**\n * Factory that returns imperative handle methods.\n * These are merged into the Lex4EditorHandle exposed via ref.\n */\n handleMethods?: (ctx: ExtensionContext) => Record<string, (...args: never[]) => unknown>;\n}\n\n/**\n * Resolved extension data after processing all extensions.\n * Used internally by the editor to wire everything together.\n */\nexport interface ResolvedExtensions {\n nodes: Klass<LexicalNode>[];\n bodyPlugins: React.ComponentType[];\n toolbarItems: React.ComponentType[];\n toolbarEndItems: React.ComponentType[];\n sidePanels: React.ComponentType[];\n providers: React.ComponentType<{ children: React.ReactNode }>[];\n themeOverrides: Partial<EditorThemeClasses>;\n cssVariables: Record<string, string>;\n rootClassNames: string[];\n handleFactories: Array<(ctx: ExtensionContext) => Record<string, (...args: never[]) => unknown>>;\n}\n\n/**\n * Processes an array of extensions into a single resolved structure.\n */\nexport function resolveExtensions(extensions: Lex4Extension[]): ResolvedExtensions {\n const resolved: ResolvedExtensions = {\n nodes: [],\n bodyPlugins: [],\n toolbarItems: [],\n toolbarEndItems: [],\n sidePanels: [],\n providers: [],\n themeOverrides: {},\n cssVariables: {},\n rootClassNames: [],\n handleFactories: [],\n };\n\n for (const ext of extensions) {\n if (ext.nodes) resolved.nodes.push(...ext.nodes);\n if (ext.bodyPlugins) resolved.bodyPlugins.push(...ext.bodyPlugins);\n if (ext.toolbarItems) resolved.toolbarItems.push(...ext.toolbarItems);\n if (ext.toolbarEndItems) resolved.toolbarEndItems.push(...ext.toolbarEndItems);\n if (ext.sidePanel) resolved.sidePanels.push(ext.sidePanel);\n if (ext.provider) resolved.providers.push(ext.provider);\n if (ext.themeOverrides) {\n resolved.themeOverrides = { ...resolved.themeOverrides, ...ext.themeOverrides };\n }\n if (ext.cssVariables) {\n Object.assign(resolved.cssVariables, ext.cssVariables);\n }\n if (ext.rootClassName) resolved.rootClassNames.push(ext.rootClassName);\n if (ext.handleMethods) resolved.handleFactories.push(ext.handleMethods);\n }\n\n return resolved;\n}\n","import React, { createContext, useContext, useMemo, useRef } from 'react';\nimport type { ResolvedExtensions, ExtensionContext } from './types';\nimport { resolveExtensions } from './types';\nimport type { Lex4Extension } from './types';\n\nconst EMPTY_RESOLVED: ResolvedExtensions = {\n nodes: [],\n bodyPlugins: [],\n toolbarItems: [],\n toolbarEndItems: [],\n sidePanels: [],\n providers: [],\n themeOverrides: {},\n cssVariables: {},\n rootClassNames: [],\n handleFactories: [],\n};\n\nconst ExtensionResolvedContext = createContext<ResolvedExtensions>(EMPTY_RESOLVED);\n\nfunction extensionArraysEqual(a?: Lex4Extension[], b?: Lex4Extension[]): boolean {\n if (a === b) return true;\n if (!a || !b) return !a && !b;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/**\n * Provides resolved extension data to all child components.\n * Extensions are resolved when the extension instances change.\n * This keeps providers and side panels in sync when an extension\n * keeps the same name but receives fresh configuration.\n */\nexport const ExtensionProvider: React.FC<{\n extensions?: Lex4Extension[];\n children: React.ReactNode;\n}> = ({ extensions, children }) => {\n const prevExtensionsRef = useRef<Lex4Extension[] | undefined>(undefined);\n const resolvedRef = useRef<ResolvedExtensions>(EMPTY_RESOLVED);\n\n if (!extensionArraysEqual(extensions, prevExtensionsRef.current)) {\n resolvedRef.current =\n extensions && extensions.length > 0 ? resolveExtensions(extensions) : EMPTY_RESOLVED;\n prevExtensionsRef.current = extensions;\n }\n const resolved = resolvedRef.current;\n\n // Wrap children with extension providers (inside-out order)\n let wrapped = <>{children}</>;\n for (let i = resolved.providers.length - 1; i >= 0; i--) {\n const Provider = resolved.providers[i];\n wrapped = <Provider>{wrapped}</Provider>;\n }\n\n return (\n <ExtensionResolvedContext.Provider value={resolved}>\n {wrapped}\n </ExtensionResolvedContext.Provider>\n );\n};\n\n/**\n * Returns the resolved extension data.\n */\nexport function useExtensions(): ResolvedExtensions {\n return useContext(ExtensionResolvedContext);\n}\n\n// --- Extension state store ---\n\nconst ExtensionStateContext = createContext<React.MutableRefObject<Record<string, unknown>> | null>(null);\n\nexport const ExtensionStateProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const stateRef = useRef<Record<string, unknown>>({});\n return (\n <ExtensionStateContext.Provider value={stateRef}>\n {children}\n </ExtensionStateContext.Provider>\n );\n};\n\n/**\n * Hook to get/set extension shared state from any component within the editor tree.\n */\nexport function useExtensionState() {\n const stateRef = useContext(ExtensionStateContext);\n return {\n get: <T = unknown>(key: string): T | undefined => stateRef?.current[key] as T | undefined,\n set: <T = unknown>(key: string, value: T) => {\n if (stateRef) stateRef.current[key] = value;\n },\n };\n}\n\n/**\n * Builds an ExtensionContext for handle method factories.\n */\nexport function useExtensionContext(\n getDocument: ExtensionContext['getDocument'],\n getActiveEditor: ExtensionContext['getActiveEditor'],\n): ExtensionContext {\n const stateRef = useContext(ExtensionStateContext);\n\n return useMemo(() => ({\n getDocument,\n getActiveEditor,\n getExtensionState: <T = unknown>(key: string) => stateRef?.current[key] as T | undefined,\n setExtensionState: <T = unknown>(key: string, value: T) => {\n if (stateRef) stateRef.current[key] = value;\n },\n }), [getDocument, getActiveEditor, stateRef]);\n}\n","import React, { useCallback, useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nconst SUPPORTED_FONTS = [\n 'Calibri',\n 'Inter',\n 'Times New Roman',\n 'Arial',\n 'Georgia',\n 'Courier New',\n] as const;\n\nexport type FontFamily = (typeof SUPPORTED_FONTS)[number];\n\nexport { SUPPORTED_FONTS };\n\n/**\n * Applies a font family to the current text selection by setting\n * inline CSS style on each selected text node.\n */\nexport function applyFontFamily(editor: LexicalEditor, fontFamily: FontFamily): void {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n node.setStyle(`font-family: ${fontFamily}`);\n }\n }\n });\n}\n\ninterface FontPluginProps {\n onFontChange?: (font: string) => void;\n}\n\n/**\n * FontPlugin — tracks the current selection's font and exposes a callback\n * for the toolbar to display the active font.\n */\nexport const FontPlugin: React.FC<FontPluginProps> = ({ onFontChange }) => {\n const [editor] = useLexicalComposerContext();\n\n const reportFont = useCallback(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const node = selection.getNodes()[0];\n if ($isTextNode(node)) {\n const style = node.getStyle();\n const match = style.match(/font-family:\\s*([^;]+)/);\n onFontChange?.(match ? match[1].trim() : 'Inter');\n }\n });\n }, [editor, onFontChange]);\n\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n reportFont();\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, reportFont]);\n\n return null;\n};\n","import {\n FORMAT_TEXT_COMMAND,\n type LexicalEditor,\n type TextFormatType,\n} from 'lexical';\nimport { FORMAT_ELEMENT_COMMAND, type ElementFormatType } from 'lexical';\n\n/**\n * Dispatches a text formatting command to the given Lexical editor.\n */\nexport function toggleFormat(editor: LexicalEditor, format: TextFormatType): void {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);\n}\n\nexport function toggleBold(editor: LexicalEditor): void {\n toggleFormat(editor, 'bold');\n}\n\nexport function toggleItalic(editor: LexicalEditor): void {\n toggleFormat(editor, 'italic');\n}\n\nexport function toggleUnderline(editor: LexicalEditor): void {\n toggleFormat(editor, 'underline');\n}\n\nexport function toggleStrikethrough(editor: LexicalEditor): void {\n toggleFormat(editor, 'strikethrough');\n}\n\n/**\n * Dispatches an element alignment command.\n */\nexport function setAlignment(editor: LexicalEditor, alignment: ElementFormatType): void {\n editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, alignment);\n}\n","import {\n INSERT_ORDERED_LIST_COMMAND,\n INSERT_UNORDERED_LIST_COMMAND,\n REMOVE_LIST_COMMAND,\n} from '@lexical/list';\nimport {\n INDENT_CONTENT_COMMAND,\n OUTDENT_CONTENT_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nexport type ListType = 'number' | 'bullet';\n\n/**\n * Inserts a list of the given type into the editor.\n */\nexport function insertList(editor: LexicalEditor, type: ListType): void {\n if (type === 'number') {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n } else {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n }\n}\n\n/**\n * Removes the current list formatting.\n */\nexport function removeList(editor: LexicalEditor): void {\n editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n}\n\n/**\n * Indents the current selection.\n *\n * Paragraphs are rendered as first-line indents by the paragraph indent plugin,\n * while list items keep Lexical's native nesting behavior.\n */\nexport function indentContent(editor: LexicalEditor): void {\n editor.dispatchCommand(INDENT_CONTENT_COMMAND, undefined);\n}\n\n/**\n * Outdents the current selection.\n *\n * Paragraphs are rendered as first-line indents by the paragraph indent plugin,\n * while list items keep Lexical's native un-nesting behavior.\n */\nexport function outdentContent(editor: LexicalEditor): void {\n editor.dispatchCommand(OUTDENT_CONTENT_COMMAND, undefined);\n}\n","import type { BlockType } from '../lexical/commands/block-types';\n\nconst INLINE_BLOCK_STYLE_PROPERTY = '--lex4-block-type';\n\nconst INLINE_BLOCK_STYLE_PRESETS: Record<BlockType, Record<string, string>> = {\n paragraph: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'paragraph',\n 'font-size': '12pt',\n 'font-weight': '400',\n },\n h1: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'h1',\n 'font-size': '22.5pt',\n 'font-weight': '700',\n },\n h2: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'h2',\n 'font-size': '18pt',\n 'font-weight': '700',\n },\n h3: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'h3',\n 'font-size': '15pt',\n 'font-weight': '600',\n },\n h4: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'h4',\n 'font-size': '13.5pt',\n 'font-weight': '600',\n },\n h5: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'h5',\n 'font-size': '12pt',\n 'font-weight': '500',\n },\n h6: {\n [INLINE_BLOCK_STYLE_PROPERTY]: 'h6',\n 'font-size': '11.25pt',\n 'font-weight': '500',\n },\n};\n\nfunction escapeStyleProperty(property: string): string {\n const escapedProperty = property.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return escapedProperty;\n}\n\nfunction stripStyleDeclaration(existingStyle: string, property: string): string {\n const escapedProperty = escapeStyleProperty(property);\n return existingStyle.replace(\n new RegExp(`${escapedProperty}:\\\\s*[^;]+;?\\\\s*`, 'g'),\n '',\n ).trim();\n}\n\nfunction isSupportedInlineBlockType(value: string | undefined): value is BlockType {\n return value === 'paragraph'\n || value === 'h1'\n || value === 'h2'\n || value === 'h3'\n || value === 'h4'\n || value === 'h5'\n || value === 'h6';\n}\n\nexport function extractStyleValue(style: string, property: string): string | undefined {\n const escapedProperty = escapeStyleProperty(property);\n const match = style.match(new RegExp(`${escapedProperty}:\\\\s*([^;]+)`));\n return match ? match[1].trim().replace(/['\"]/g, '') : undefined;\n}\n\nexport function removeStyleDeclaration(existingStyle: string, property: string): string {\n return stripStyleDeclaration(existingStyle, property);\n}\n\nexport function mergeStyleDeclaration(\n existingStyle: string,\n property: string,\n value: string,\n): string {\n const stripped = stripStyleDeclaration(existingStyle, property);\n const declaration = `${property}: ${value}`;\n return stripped ? `${stripped}; ${declaration}` : declaration;\n}\n\nexport function mergeStyleDeclarations(\n existingStyle: string,\n declarations: Record<string, string>,\n): string {\n return Object.entries(declarations).reduce(\n (style, [property, value]) => mergeStyleDeclaration(style, property, value),\n existingStyle,\n );\n}\n\nexport function extractFontFamilyFromStyle(style: string): string | undefined {\n return extractStyleValue(style, 'font-family');\n}\n\nexport function extractFontSizePtFromStyle(style: string): number | undefined {\n const value = extractStyleValue(style, 'font-size');\n if (!value) {\n return undefined;\n }\n\n const match = value.match(/^(\\d+(?:\\.\\d+)?)\\s*pt$/);\n return match ? parseFloat(match[1]) : undefined;\n}\n\nexport function mergeFontFamilyStyle(existingStyle: string, fontFamily: string): string {\n return mergeStyleDeclaration(existingStyle, 'font-family', fontFamily);\n}\n\nexport function mergeFontSizeStyle(existingStyle: string, size: number): string {\n return mergeStyleDeclaration(existingStyle, 'font-size', `${size}pt`);\n}\n\nexport function extractInlineBlockTypeFromStyle(style: string): BlockType | undefined {\n const value = extractStyleValue(style, INLINE_BLOCK_STYLE_PROPERTY);\n return isSupportedInlineBlockType(value) ? value : undefined;\n}\n\nexport function createInlineBlockTypeStylePatch(blockType: BlockType): Record<string, string> {\n return INLINE_BLOCK_STYLE_PRESETS[blockType];\n}\n\nexport function mergeInlineBlockTypeStyle(existingStyle: string, blockType: BlockType): string {\n const baseStyle = [\n INLINE_BLOCK_STYLE_PROPERTY,\n 'font-size',\n 'font-weight',\n ].reduce((style, property) => removeStyleDeclaration(style, property), existingStyle);\n\n return mergeStyleDeclarations(baseStyle, createInlineBlockTypeStylePatch(blockType));\n}\n","import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\nimport type { VariableDefinition, VariableContextValue } from './types';\n\nconst EMPTY_CONTEXT: VariableContextValue = {\n definitions: [],\n refreshDefinitions: () => { /* no-op when variables extension not loaded */ },\n getDefinition: () => undefined,\n};\n\nconst VariableContext = createContext<VariableContextValue>(EMPTY_CONTEXT);\n\ninterface VariableProviderProps {\n initialDefinitions?: VariableDefinition[];\n children: React.ReactNode;\n}\n\n/**\n * VariableProvider — Manages the variable catalog.\n *\n * Host apps provide variable definitions via props.\n * The picker reads from this context. Definitions can be refreshed\n * at runtime without re-mounting the editor.\n */\nexport const VariableProvider: React.FC<VariableProviderProps> = ({\n initialDefinitions = [],\n children,\n}) => {\n const [definitions, setDefinitions] = useState<VariableDefinition[]>(initialDefinitions);\n\n const refresh = useCallback((newDefinitions: VariableDefinition[]) => {\n setDefinitions(newDefinitions);\n }, []);\n\n const getDefinition = useCallback(\n (key: string): VariableDefinition | undefined => {\n return definitions.find(d => d.key === key);\n },\n [definitions],\n );\n\n const value = useMemo<VariableContextValue>(\n () => ({ definitions, refreshDefinitions: refresh, getDefinition }),\n [definitions, refresh, getDefinition],\n );\n\n return (\n <VariableContext.Provider value={value}>\n {children}\n </VariableContext.Provider>\n );\n};\n\n/**\n * Hook to access the variable catalog from within the editor tree.\n * Returns empty defaults when called outside a VariableProvider.\n */\nexport function useVariables(): VariableContextValue {\n return useContext(VariableContext);\n}\n","import {\n $applyNodeReplacement,\n $createNodeSelection,\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n $setSelection,\n DecoratorNode,\n type DOMConversionMap,\n type DOMExportOutput,\n type LexicalNode,\n type NodeKey,\n type SerializedLexicalNode,\n type Spread,\n} from 'lexical';\nimport {\n COMMAND_PRIORITY_LOW,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_DOWN_COMMAND,\n} from 'lexical';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';\nimport { useCallback, useEffect, useMemo, type MouseEvent } from 'react';\nimport { useVariables } from './variable-context';\nimport {\n extractFontFamilyFromStyle,\n extractStyleValue,\n extractFontSizePtFromStyle,\n} from '../utils/text-style';\n\nexport type SerializedVariableNode = Spread<\n {\n variableKey: string;\n format?: number;\n style?: string;\n },\n SerializedLexicalNode\n>;\n\n/**\n * VariableNode — a custom Lexical DecoratorNode that represents\n * a document variable/placeholder (e.g. \"customer.name\").\n *\n * Variables are atomic, non-editable inline tokens that:\n * - Display as styled chips in the editor\n * - Serialize to a structured node in JSON (not plain text)\n * - Participate in copy/paste, undo/redo, and overflow\n * - Return {{key}} as text content for clipboard\n */\nexport class VariableNode extends DecoratorNode<JSX.Element> {\n __variableKey: string;\n __format: number;\n __style: string;\n\n static getType(): string {\n return 'variable-node';\n }\n\n static clone(node: VariableNode): VariableNode {\n return new VariableNode(node.__variableKey, node.__format, node.__style, node.__key);\n }\n\n constructor(variableKey: string, format = 0, style = '', key?: NodeKey) {\n super(key);\n this.__variableKey = variableKey;\n this.__format = format;\n this.__style = style;\n }\n\n getVariableKey(): string {\n return this.getLatest().__variableKey;\n }\n\n getFormat(): number {\n return this.getLatest().__format;\n }\n\n setFormat(format: number): this {\n const writable = this.getWritable();\n writable.__format = format;\n return writable;\n }\n\n getStyle(): string {\n return this.getLatest().__style;\n }\n\n setStyle(style: string): this {\n const writable = this.getWritable();\n writable.__style = style;\n return writable;\n }\n\n // -- Serialization --\n\n static importJSON(serializedNode: SerializedVariableNode): VariableNode {\n return $createVariableNode(\n serializedNode.variableKey,\n serializedNode.format ?? 0,\n serializedNode.style ?? '',\n );\n }\n\n exportJSON(): SerializedVariableNode {\n return {\n type: 'variable-node',\n version: 1,\n variableKey: this.__variableKey,\n format: this.__format,\n style: this.__style,\n };\n }\n\n // -- DOM --\n\n createDOM(): HTMLElement {\n const span = document.createElement('span');\n span.className = 'lex4-variable';\n span.setAttribute('data-variable-key', this.__variableKey);\n span.setAttribute('data-node-key', this.__key);\n span.setAttribute('data-testid', `variable-${this.__variableKey}`);\n span.contentEditable = 'false';\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const span = document.createElement('span');\n span.setAttribute('data-variable-key', this.__variableKey);\n span.textContent = `{{${this.__variableKey}}}`;\n return { element: span };\n }\n\n static importDOM(): DOMConversionMap | null {\n return null;\n }\n\n // -- Behavior --\n\n isInline(): boolean {\n return true;\n }\n\n isKeyboardSelectable(): boolean {\n return true;\n }\n\n getTextContent(): string {\n return `{{${this.__variableKey}}}`;\n }\n\n // -- Rendering --\n\n decorate(): JSX.Element {\n return (\n <VariableChip\n nodeKey={this.__key}\n variableKey={this.__variableKey}\n format={this.__format}\n styleValue={this.__style}\n />\n );\n }\n}\n\nfunction VariableChip({\n nodeKey,\n variableKey,\n format,\n styleValue,\n}: {\n nodeKey: NodeKey;\n variableKey: string;\n format: number;\n styleValue: string;\n}): JSX.Element {\n const { getDefinition } = useVariables();\n const [editor] = useLexicalComposerContext();\n const [isSelected] = useLexicalNodeSelection(nodeKey);\n const def = getDefinition(variableKey);\n const label = def?.label ?? variableKey;\n const group = def?.group;\n const style = useMemo(() => {\n const fontFamily = extractFontFamilyFromStyle(styleValue);\n const fontSize = extractFontSizePtFromStyle(styleValue);\n const fontWeight = extractStyleValue(styleValue, 'font-weight');\n return {\n ...(fontFamily ? { fontFamily } : {}),\n ...(fontSize ? { fontSize: `${fontSize}pt` } : {}),\n ...(fontWeight ? { fontWeight } : {}),\n };\n }, [styleValue]);\n const className = [\n 'lex4-variable-chip',\n isSelected && 'lex4-variable-chip-selected',\n format & 1 ? 'lex4-text-bold' : '',\n format & 2 ? 'lex4-text-italic' : '',\n format & 8 ? 'lex4-text-underline' : '',\n format & 4 ? 'lex4-text-strikethrough' : '',\n ].filter(Boolean).join(' ');\n\n const clearDomSelection = useCallback(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n window.getSelection()?.removeAllRanges();\n }, []);\n\n const selectNode = useCallback((extendSelection: boolean) => {\n editor.focus();\n editor.update(() => {\n const nextSelection = $createNodeSelection();\n if (extendSelection) {\n const currentSelection = $getSelection();\n if ($isNodeSelection(currentSelection)) {\n for (const node of currentSelection.getNodes()) {\n if ($isVariableNode(node)) {\n nextSelection.add(node.getKey());\n }\n }\n }\n }\n nextSelection.add(nodeKey);\n $setSelection(nextSelection);\n });\n clearDomSelection();\n }, [clearDomSelection, editor, nodeKey]);\n\n const handleMouseDown = useCallback((event: MouseEvent<HTMLSpanElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!isSelected || event.shiftKey) {\n selectNode(event.shiftKey);\n }\n }, [isSelected, selectNode]);\n\n const handleClick = useCallback((event: MouseEvent<HTMLSpanElement>) => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n const handleMouseUp = useCallback((event: MouseEvent<HTMLSpanElement>) => {\n event.preventDefault();\n event.stopPropagation();\n clearDomSelection();\n }, [clearDomSelection]);\n\n useEffect(() => {\n const removeSelectedNodes = () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n const node = $getNodeByKey(nodeKey);\n if ($isVariableNode(node)) {\n node.remove();\n }\n return;\n }\n\n for (const node of selection.getNodes()) {\n if ($isVariableNode(node)) {\n node.remove();\n }\n }\n });\n };\n\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n () => {\n if (!isSelected) {\n return false;\n }\n removeSelectedNodes();\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n () => {\n if (!isSelected) {\n return false;\n }\n removeSelectedNodes();\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const moveCaretFromSelectedNode = (direction: 'backward' | 'forward') => {\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (!$isVariableNode(node)) {\n return;\n }\n\n if (direction === 'backward') {\n node.selectPrevious();\n } else {\n node.selectNext();\n }\n });\n };\n\n const unregisterArrowNavigation = editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (!isSelected || event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {\n return false;\n }\n\n if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault();\n moveCaretFromSelectedNode('backward');\n return true;\n }\n\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault();\n moveCaretFromSelectedNode('forward');\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n return () => {\n unregisterBackspace();\n unregisterDelete();\n unregisterArrowNavigation();\n };\n }, [editor, isSelected, nodeKey]);\n\n return (\n <span\n className={className}\n data-testid={`variable-chip-${variableKey}`}\n data-variable-group={group}\n title={variableKey}\n style={style}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onClick={handleClick}\n >\n {label}\n </span>\n );\n}\n\nexport function $createVariableNode(\n variableKey: string,\n format = 0,\n style = '',\n): VariableNode {\n return $applyNodeReplacement(new VariableNode(variableKey, format, style));\n}\n\nexport function $isVariableNode(\n node: LexicalNode | null | undefined,\n): node is VariableNode {\n return node instanceof VariableNode;\n}\n","import {\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n type LexicalEditor,\n type TextFormatType,\n} from 'lexical';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n mergeFontFamilyStyle,\n mergeFontSizeStyle,\n} from '../utils/text-style';\nimport { $isVariableNode, type VariableNode } from './variable-node';\n\nconst FORMAT_MASKS: Partial<Record<TextFormatType, number>> = {\n bold: 1,\n italic: 2,\n strikethrough: 4,\n underline: 8,\n};\n\nfunction dedupeVariableNodes(nodes: VariableNode[]): VariableNode[] {\n return Array.from(new Map(nodes.map(node => [node.getKey(), node])).values());\n}\n\nfunction getSelectedVariableNodesFromSelection(\n selection: ReturnType<typeof $getSelection>,\n): VariableNode[] {\n if (\n !selection\n || typeof selection !== 'object'\n || !('getNodes' in selection)\n || typeof selection.getNodes !== 'function'\n ) {\n return [];\n }\n\n return dedupeVariableNodes(selection.getNodes().filter($isVariableNode));\n}\n\nexport function getVisuallySelectedVariableNodes(editor: LexicalEditor): VariableNode[] {\n const rootElement = editor.getRootElement();\n if (!rootElement) {\n return [];\n }\n\n const nodes: VariableNode[] = [];\n rootElement\n .querySelectorAll<HTMLElement>('.lex4-variable-chip-selected')\n .forEach((chip) => {\n const variableElement = chip.closest<HTMLElement>('[data-node-key]');\n const nodeKey = variableElement?.dataset.nodeKey;\n if (!nodeKey) {\n return;\n }\n\n const node = $getNodeByKey(nodeKey);\n if ($isVariableNode(node)) {\n nodes.push(node);\n }\n });\n\n return dedupeVariableNodes(nodes);\n}\n\nfunction withSelectedVariableNodes(\n editor: LexicalEditor,\n updater: (nodes: VariableNode[]) => void,\n): boolean {\n let updated = false;\n\n editor.update(() => {\n const nodes = [\n ...getSelectedVariableNodesFromSelection($getSelection()),\n ...getVisuallySelectedVariableNodes(editor),\n ];\n const uniqueNodes = dedupeVariableNodes(nodes);\n if (uniqueNodes.length === 0) {\n return;\n }\n\n updater(uniqueNodes);\n updated = true;\n });\n\n return updated;\n}\n\nexport function getSelectedVariableNodes(editor: LexicalEditor): VariableNode[] {\n let nodes: VariableNode[] = [];\n\n editor.getEditorState().read(() => {\n nodes = dedupeVariableNodes([\n ...getSelectedVariableNodesFromSelection($getSelection()),\n ...getVisuallySelectedVariableNodes(editor),\n ]);\n if (nodes.length === 0) {\n return;\n }\n });\n\n return nodes;\n}\n\nexport function toggleSelectedVariableFormat(\n editor: LexicalEditor,\n format: TextFormatType,\n): boolean {\n const mask = FORMAT_MASKS[format];\n if (!mask) {\n return false;\n }\n\n return withSelectedVariableNodes(editor, (nodes) => {\n const shouldEnable = nodes.some((node) => (node.getFormat() & mask) === 0);\n\n for (const node of nodes) {\n const nextFormat = shouldEnable\n ? node.getFormat() | mask\n : node.getFormat() & ~mask;\n node.setFormat(nextFormat);\n }\n });\n}\n\nexport function applyFontFamilyToSelectedVariables(\n editor: LexicalEditor,\n fontFamily: string,\n): boolean {\n return withSelectedVariableNodes(editor, (nodes) => {\n for (const node of nodes) {\n node.setStyle(mergeFontFamilyStyle(node.getStyle(), fontFamily));\n }\n });\n}\n\nexport function applyFontSizeToSelectedVariables(\n editor: LexicalEditor,\n size: number,\n): boolean {\n return withSelectedVariableNodes(editor, (nodes) => {\n for (const node of nodes) {\n node.setStyle(mergeFontSizeStyle(node.getStyle(), size));\n }\n });\n}\n\nexport function readSelectedVariableFormatting(editor: LexicalEditor): {\n fontFamily?: string;\n fontSize?: number;\n} {\n let formatting: {\n fontFamily?: string;\n fontSize?: number;\n } = {};\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) {\n return;\n }\n\n const firstNode = selection.getNodes().filter($isVariableNode)[0];\n if (!firstNode) {\n return;\n }\n\n const style = firstNode.getStyle();\n formatting = {\n fontFamily: extractFontFamilyFromStyle(style),\n fontSize: extractFontSizePtFromStyle(style),\n };\n });\n\n return formatting;\n}\n","import { $patchStyleText, $setBlocksType } from '@lexical/selection';\nimport {\n $createRangeSelectionFromDom,\n $createNodeSelection,\n $createParagraphNode,\n $isElementNode,\n $getSelection,\n $isNodeSelection,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n type ElementNode,\n type LexicalEditor,\n type RangeSelection,\n} from 'lexical';\nimport {\n $createHeadingNode,\n $isHeadingNode,\n} from '@lexical/rich-text';\nimport type { BlockType } from './block-types';\nimport {\n createInlineBlockTypeStylePatch,\n extractInlineBlockTypeFromStyle,\n mergeInlineBlockTypeStyle,\n} from '../../utils/text-style';\nimport { $isVariableNode, type VariableNode } from '../../variables/variable-node';\nimport { getVisuallySelectedVariableNodes } from '../../variables/variable-formatting';\n\nfunction getElementBlockType(element: ElementNode): BlockType {\n if ($isHeadingNode(element)) {\n return element.getTag();\n }\n return 'paragraph';\n}\n\nfunction getVariableTopLevelElement(variable: VariableNode): ElementNode | null {\n const topLevelElement = variable.getTopLevelElementOrThrow();\n return $isElementNode(topLevelElement) ? topLevelElement : null;\n}\n\nfunction replaceTopLevelBlockType(element: ElementNode, blockType: BlockType): void {\n const currentType = getElementBlockType(element);\n if (currentType === blockType) {\n return;\n }\n\n const nextElement = blockType === 'paragraph'\n ? $createParagraphNode()\n : $createHeadingNode(blockType);\n nextElement.setFormat(element.getFormatType());\n nextElement.setIndent(element.getIndent());\n\n const children = element.getChildren();\n for (const child of children) {\n nextElement.append(child);\n }\n\n element.replace(nextElement);\n}\n\nfunction isPartialSingleBlockSelection(selection: RangeSelection): boolean {\n if (selection.isCollapsed()) {\n return false;\n }\n\n const anchorTopLevel = selection.anchor.getNode().getTopLevelElementOrThrow();\n const focusTopLevel = selection.focus.getNode().getTopLevelElementOrThrow();\n if (!anchorTopLevel.is(focusTopLevel)) {\n return false;\n }\n\n const selectedText = selection.getTextContent().trim();\n const blockText = anchorTopLevel.getTextContent().trim();\n return selectedText.length > 0 && selectedText.length < blockText.length;\n}\n\nfunction applySemanticBlockType(selection: RangeSelection, blockType: BlockType): void {\n if (blockType === 'paragraph') {\n $setBlocksType(selection, () => $createParagraphNode());\n return;\n }\n\n $setBlocksType(selection, () => $createHeadingNode(blockType));\n}\n\nfunction selectedVariablesOccupyEntireBlock(\n variables: VariableNode[],\n topLevelElement: ElementNode,\n): boolean {\n const selectedKeys = new Set(variables.map(variable => variable.getKey()));\n const meaningfulChildren = topLevelElement.getChildren().filter(\n child => !($isTextNode(child) && child.getTextContent().trim() === ''),\n );\n\n if (meaningfulChildren.length === 0) {\n return false;\n }\n\n return meaningfulChildren.every(\n child => $isVariableNode(child) && selectedKeys.has(child.getKey()),\n );\n}\n\nfunction getStandaloneVariableChildren(topLevelElement: ElementNode): VariableNode[] | null {\n const meaningfulChildren = topLevelElement.getChildren().filter(\n child => !($isTextNode(child) && child.getTextContent().trim() === ''),\n );\n\n if (meaningfulChildren.length === 0 || !meaningfulChildren.every($isVariableNode)) {\n return null;\n }\n\n return meaningfulChildren;\n}\n\nfunction getSelectedVariableNodesFromRangeSelection(\n editor: LexicalEditor,\n selection: RangeSelection,\n): VariableNode[] {\n const seen = new Set<string>();\n const variables: VariableNode[] = [];\n\n for (const node of [\n selection.anchor.getNode(),\n selection.focus.getNode(),\n ...selection.getNodes(),\n ...getVisuallySelectedVariableNodes(editor),\n ]) {\n if (!$isVariableNode(node) || seen.has(node.getKey())) {\n continue;\n }\n\n seen.add(node.getKey());\n variables.push(node);\n }\n\n return variables;\n}\n\nexport function setBlockType(editor: LexicalEditor, blockType: BlockType): void {\n editor.update(() => {\n const visuallySelectedVariables = getVisuallySelectedVariableNodes(editor);\n const currentSelection = $getSelection();\n const selection = $isNodeSelection(currentSelection)\n ? currentSelection\n : $createRangeSelectionFromDom(window.getSelection(), editor) ?? currentSelection;\n\n if ($isRangeSelection(selection)) {\n $setSelection(selection);\n }\n\n if ($isNodeSelection(selection)) {\n const variables = Array.from(new Map(\n [\n ...selection.getNodes().filter($isVariableNode),\n ...visuallySelectedVariables,\n ].map(variable => [variable.getKey(), variable]),\n ).values());\n if (variables.length === 0) {\n return;\n }\n\n const firstTopLevelElement = getVariableTopLevelElement(variables[0]);\n if (!firstTopLevelElement) {\n return;\n }\n const sameTopLevelElement = variables.every(\n variable => getVariableTopLevelElement(variable)?.is(firstTopLevelElement) ?? false,\n );\n\n if (sameTopLevelElement && selectedVariablesOccupyEntireBlock(variables, firstTopLevelElement)) {\n for (const variable of variables) {\n variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));\n }\n replaceTopLevelBlockType(firstTopLevelElement, blockType);\n const nextSelection = $createNodeSelection();\n for (const variable of variables) {\n nextSelection.add(variable.getKey());\n }\n $setSelection(nextSelection);\n return;\n }\n\n for (const variable of variables) {\n variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));\n }\n return;\n }\n\n if (!$isRangeSelection(selection)) {\n if (visuallySelectedVariables.length === 0) {\n return;\n }\n\n for (const variable of visuallySelectedVariables) {\n variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));\n }\n return;\n }\n\n const anchorTopLevel = selection.anchor.getNode().getTopLevelElementOrThrow();\n const standaloneVariables = $isElementNode(anchorTopLevel)\n ? getStandaloneVariableChildren(anchorTopLevel)\n : null;\n const selectedVariables = getSelectedVariableNodesFromRangeSelection(editor, selection);\n\n if (isPartialSingleBlockSelection(selection)) {\n $patchStyleText(selection, createInlineBlockTypeStylePatch(blockType));\n for (const variable of selectedVariables) {\n variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));\n }\n return;\n }\n\n for (const variable of new Map(\n [...(standaloneVariables ?? []), ...selectedVariables].map(variable => [variable.getKey(), variable]),\n ).values()) {\n variable.setStyle(mergeInlineBlockTypeStyle(variable.getStyle(), blockType));\n }\n\n applySemanticBlockType(selection, blockType);\n });\n}\n\nexport function getActiveBlockType(editor: LexicalEditor): BlockType {\n let blockType: BlockType = 'paragraph';\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if ($isNodeSelection(selection)) {\n const firstVariableNode = selection.getNodes().filter($isVariableNode)[0];\n if (!firstVariableNode) {\n return;\n }\n\n const topLevelElement = getVariableTopLevelElement(firstVariableNode);\n blockType = extractInlineBlockTypeFromStyle(firstVariableNode.getStyle())\n ?? (topLevelElement ? getElementBlockType(topLevelElement) : 'paragraph');\n return;\n }\n\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n const anchorNode = selection.anchor.getNode();\n const styleTarget = ($isTextNode(anchorNode) || $isVariableNode(anchorNode))\n ? anchorNode\n : selection.getNodes().find(node => $isTextNode(node) || $isVariableNode(node));\n const style = selection.style\n || (($isTextNode(styleTarget) || $isVariableNode(styleTarget)) ? styleTarget.getStyle() : '');\n blockType = extractInlineBlockTypeFromStyle(style)\n ?? getElementBlockType(anchorNode.getTopLevelElementOrThrow());\n });\n\n return blockType;\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { Check, ChevronDown } from 'lucide-react';\nimport type { Lex4Translations } from '../i18n';\nimport { useTranslations } from '../i18n';\nimport type { BlockType } from '../lexical/commands/block-types';\n\nconst BLOCK_TYPE_OPTIONS: Array<{ value: BlockType; shortLabel: string }> = [\n { value: 'paragraph', shortLabel: 'P' },\n { value: 'h1', shortLabel: 'H1' },\n { value: 'h2', shortLabel: 'H2' },\n { value: 'h3', shortLabel: 'H3' },\n { value: 'h4', shortLabel: 'H4' },\n { value: 'h5', shortLabel: 'H5' },\n { value: 'h6', shortLabel: 'H6' },\n];\n\nexport function getBlockTypeLabel(t: Lex4Translations, blockType: BlockType): string {\n switch (blockType) {\n case 'h1':\n return t.toolbar.heading1;\n case 'h2':\n return t.toolbar.heading2;\n case 'h3':\n return t.toolbar.heading3;\n case 'h4':\n return t.toolbar.heading4;\n case 'h5':\n return t.toolbar.heading5;\n case 'h6':\n return t.toolbar.heading6;\n default:\n return t.toolbar.paragraph;\n }\n}\n\nfunction getBlockTypeShortLabel(blockType: BlockType): string {\n return BLOCK_TYPE_OPTIONS.find((option) => option.value === blockType)?.shortLabel ?? 'P';\n}\n\ninterface BlockTypePickerProps {\n value: BlockType;\n onChange: (blockType: BlockType) => void;\n}\n\nexport const BlockTypePicker: React.FC<BlockTypePickerProps> = ({ value, onChange }) => {\n const t = useTranslations();\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleEscape);\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleEscape);\n };\n }, [open]);\n\n return (\n <div\n ref={containerRef}\n className=\"lex4-block-type-picker\"\n data-testid=\"block-type-picker\"\n >\n <button\n type=\"button\"\n className={`lex4-block-type-trigger${open ? ' open' : ''}`}\n data-testid=\"block-type-selector\"\n aria-label={t.toolbar.blockType}\n aria-expanded={open}\n aria-haspopup=\"menu\"\n title={getBlockTypeLabel(t, value)}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => setOpen((current) => !current)}\n >\n <span\n className={`lex4-block-type-trigger-code${value === 'paragraph' ? '' : ' heading'}`}\n >\n {getBlockTypeShortLabel(value)}\n </span>\n <ChevronDown size={14} className={`lex4-block-type-trigger-chevron${open ? ' open' : ''}`} />\n </button>\n\n {open && (\n <div\n className=\"lex4-block-type-menu\"\n role=\"menu\"\n data-testid=\"block-type-menu\"\n >\n {BLOCK_TYPE_OPTIONS.map((option) => {\n const label = getBlockTypeLabel(t, option.value);\n const active = option.value === value;\n\n return (\n <button\n key={option.value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n className={`lex4-block-type-item${active ? ' active' : ''}`}\n data-testid={`block-type-option-${option.value}`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n onChange(option.value);\n setOpen(false);\n }}\n >\n <span\n className={`lex4-block-type-item-code${option.value === 'paragraph' ? '' : ' heading'}${active ? ' active' : ''}`}\n >\n {option.shortLabel}\n </span>\n <span className=\"lex4-block-type-item-label\">\n {label}\n </span>\n <span className=\"lex4-block-type-item-check\" aria-hidden=\"true\">\n {active ? <Check size={14} /> : null}\n </span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { FileText } from 'lucide-react';\nimport { useTranslations } from '../i18n';\n\ninterface HeaderFooterToggleProps {\n enabled: boolean;\n onToggle: (enabled: boolean) => void;\n showLabel?: boolean;\n}\n\nexport const HeaderFooterToggle: React.FC<HeaderFooterToggleProps> = ({\n enabled,\n onToggle,\n showLabel = true,\n}) => {\n const t = useTranslations();\n\n return (\n <label\n className=\"lex4-hf-toggle\"\n data-testid=\"header-footer-toggle\"\n >\n <FileText size={14} className=\"lex4-hf-toggle-icon\" />\n {showLabel && (\n <span className=\"lex4-hf-toggle-label\">\n {t.headerFooter.label}\n </span>\n )}\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={t.headerFooter.label}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => onToggle(!enabled)}\n className=\"lex4-hf-switch\"\n style={{ backgroundColor: enabled ? 'var(--color-primary)' : 'var(--color-muted)' }}\n data-testid=\"header-footer-switch\"\n title={t.headerFooter.label}\n >\n <span className=\"lex4-hf-switch-knob\" />\n </button>\n </label>\n );\n};\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { CopyPlus, Eraser, Settings2, Trash2 } from 'lucide-react';\nimport { useTranslations } from '../i18n';\nimport type { PageCounterMode } from '../types/document';\n\ninterface HeaderFooterActionsProps {\n activePageId: string | null;\n pageCounterMode: PageCounterMode;\n onPageCounterModeChange: (mode: PageCounterMode) => void;\n onCopyHeaderToAll: () => void;\n onCopyFooterToAll: () => void;\n onClearHeader: () => void;\n onClearFooter: () => void;\n onClearAllHeaders: () => void;\n onClearAllFooters: () => void;\n}\n\nconst PAGE_COUNTER_OPTIONS: PageCounterMode[] = ['none', 'header', 'footer', 'both'];\n\nexport const HeaderFooterActions: React.FC<HeaderFooterActionsProps> = ({\n activePageId,\n pageCounterMode,\n onPageCounterModeChange,\n onCopyHeaderToAll,\n onCopyFooterToAll,\n onClearHeader,\n onClearFooter,\n onClearAllHeaders,\n onClearAllFooters,\n}) => {\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const hasActivePage = activePageId !== null;\n const t = useTranslations();\n\n const close = useCallback(() => setOpen(false), []);\n\n useEffect(() => {\n if (!open) return;\n const handleClickOutside = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n close();\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, [open, close]);\n\n const handleAction = (action: () => void) => {\n action();\n close();\n };\n\n return (\n <div ref={containerRef} style={{ position: 'relative' }} data-testid=\"header-footer-actions\">\n <button\n type=\"button\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => setOpen(!open)}\n className=\"lex4-settings-trigger lex4-settings-trigger-icon\"\n data-testid=\"header-footer-menu-trigger\"\n aria-expanded={open}\n aria-haspopup=\"true\"\n aria-label={t.headerFooter.settingsLabel}\n title={t.headerFooter.settingsLabel}\n >\n <Settings2 size={14} />\n </button>\n\n {open && (\n <div\n className=\"lex4-settings-menu\"\n role=\"menu\"\n data-testid=\"header-footer-menu\"\n >\n <SectionLabel>{t.headerFooter.pageCounter}</SectionLabel>\n <div className=\"lex4-settings-counter-grid\" data-testid=\"page-counter-mode\">\n {PAGE_COUNTER_OPTIONS.map((value) => (\n <button\n key={value}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={pageCounterMode === value}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => onPageCounterModeChange(value)}\n className=\"lex4-settings-counter-btn\"\n data-testid={`page-counter-${value}`}\n >\n {t.headerFooter.pageCounterModes[value]}\n </button>\n ))}\n </div>\n\n <MenuDivider />\n\n <SectionLabel>{t.headerFooter.headerSection}</SectionLabel>\n <MenuItem\n icon={<CopyPlus size={14} />}\n label={t.headerFooter.copyToAllPages}\n onClick={() => handleAction(onCopyHeaderToAll)}\n disabled={!hasActivePage}\n testId=\"copy-header-all\"\n />\n <MenuItem\n icon={<Eraser size={14} />}\n label={t.headerFooter.clearThisPage}\n onClick={() => handleAction(onClearHeader)}\n disabled={!hasActivePage}\n testId=\"clear-header\"\n />\n <MenuItem\n icon={<Trash2 size={14} />}\n label={t.headerFooter.clearAll}\n onClick={() => handleAction(onClearAllHeaders)}\n testId=\"clear-all-headers\"\n />\n\n <MenuDivider />\n\n <SectionLabel>{t.headerFooter.footerSection}</SectionLabel>\n <MenuItem\n icon={<CopyPlus size={14} />}\n label={t.headerFooter.copyToAllPages}\n onClick={() => handleAction(onCopyFooterToAll)}\n disabled={!hasActivePage}\n testId=\"copy-footer-all\"\n />\n <MenuItem\n icon={<Eraser size={14} />}\n label={t.headerFooter.clearThisPage}\n onClick={() => handleAction(onClearFooter)}\n disabled={!hasActivePage}\n testId=\"clear-footer\"\n />\n <MenuItem\n icon={<Trash2 size={14} />}\n label={t.headerFooter.clearAll}\n onClick={() => handleAction(onClearAllFooters)}\n testId=\"clear-all-footers\"\n />\n </div>\n )}\n </div>\n );\n};\n\nconst SectionLabel: React.FC<{ children: React.ReactNode }> = ({ children }) => (\n <div className=\"lex4-settings-label\">\n {children}\n </div>\n);\n\ninterface MenuItemProps {\n icon: React.ReactNode;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n testId: string;\n}\n\nconst MenuItem: React.FC<MenuItemProps> = ({ icon, label, onClick, disabled, testId }) => (\n <button\n type=\"button\"\n role=\"menuitem\"\n onMouseDown={(e) => e.preventDefault()}\n onClick={onClick}\n disabled={disabled}\n className=\"lex4-settings-item\"\n data-testid={testId}\n >\n {icon}\n {label}\n </button>\n);\n\nconst MenuDivider: React.FC = () => (\n <div className=\"lex4-settings-divider\" />\n);\n","import React, { useCallback } from 'react';\nimport { useDocument } from '../context/document-context';\nimport { useToolbarConfig } from '../context/toolbar-config';\nimport { useTranslations, interpolate } from '../i18n';\nimport type { PageCounterMode } from '../types/document';\nimport { HeaderFooterToggle } from './HeaderFooterToggle';\nimport { HeaderFooterActions } from './HeaderFooterActions';\n\nexport const CanvasControls: React.FC = () => {\n const { document, dispatch, activePageId, runHistoryAction } = useDocument();\n const toolbarConfig = useToolbarConfig();\n const t = useTranslations();\n\n const runCanvasAction = useCallback((label: string, callback: () => void) => {\n runHistoryAction(\n {\n label,\n source: 'toolbar',\n region: 'document',\n },\n callback,\n );\n }, [runHistoryAction]);\n\n const handleToggle = useCallback((enabled: boolean) => {\n runCanvasAction(\n enabled ? t.history.actions.enabledHeadersFooters : t.history.actions.disabledHeadersFooters,\n () => {\n dispatch({ type: 'SET_HEADER_FOOTER_ENABLED', enabled });\n },\n );\n }, [dispatch, runCanvasAction, t.history.actions.disabledHeadersFooters, t.history.actions.enabledHeadersFooters]);\n\n const handleCopyHeaderToAll = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.copiedHeaderToAll, () => {\n dispatch({ type: 'COPY_HEADER_TO_ALL', sourcePageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.copiedHeaderToAll]);\n\n const handleCopyFooterToAll = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.copiedFooterToAll, () => {\n dispatch({ type: 'COPY_FOOTER_TO_ALL', sourcePageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.copiedFooterToAll]);\n\n const handleClearHeader = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.clearedHeader, () => {\n dispatch({ type: 'CLEAR_HEADER', pageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.clearedHeader]);\n\n const handleClearFooter = useCallback(() => {\n if (!activePageId) {\n return;\n }\n\n runCanvasAction(t.history.actions.clearedFooter, () => {\n dispatch({ type: 'CLEAR_FOOTER', pageId: activePageId });\n });\n }, [activePageId, dispatch, runCanvasAction, t.history.actions.clearedFooter]);\n\n const handleClearAllHeaders = useCallback(() => {\n runCanvasAction(t.history.actions.clearedAllHeaders, () => {\n dispatch({ type: 'CLEAR_ALL_HEADERS' });\n });\n }, [dispatch, runCanvasAction, t.history.actions.clearedAllHeaders]);\n\n const handleClearAllFooters = useCallback(() => {\n runCanvasAction(t.history.actions.clearedAllFooters, () => {\n dispatch({ type: 'CLEAR_ALL_FOOTERS' });\n });\n }, [dispatch, runCanvasAction, t.history.actions.clearedAllFooters]);\n\n const handlePageCounterModeChange = useCallback((mode: PageCounterMode) => {\n runCanvasAction(interpolate(t.history.actions.pageCounterSet, { value: mode }), () => {\n dispatch({ type: 'SET_PAGE_COUNTER_MODE', mode });\n });\n }, [dispatch, runCanvasAction, t.history.actions.pageCounterSet]);\n\n if (!toolbarConfig.headerFooter.visible) {\n return null;\n }\n\n return (\n <div className=\"lex4-toolbar-group lex4-toolbar-group-gap\" data-testid=\"header-footer-controls\">\n <HeaderFooterToggle\n enabled={document.headerFooterEnabled}\n onToggle={handleToggle}\n showLabel={toolbarConfig.headerFooter.showLabel}\n />\n\n {document.headerFooterEnabled && (\n <HeaderFooterActions\n activePageId={activePageId}\n pageCounterMode={document.pageCounterMode}\n onPageCounterModeChange={handlePageCounterModeChange}\n onCopyHeaderToAll={handleCopyHeaderToAll}\n onCopyFooterToAll={handleCopyFooterToAll}\n onClearHeader={handleClearHeader}\n onClearFooter={handleClearFooter}\n onClearAllHeaders={handleClearAllHeaders}\n onClearAllFooters={handleClearAllFooters}\n />\n )}\n </div>\n );\n};\n","import {\n $createRangeSelectionFromDom,\n $getSelection,\n $isElementNode,\n $isNodeSelection,\n $isRangeSelection,\n $isTextNode,\n type ElementFormatType,\n type LexicalEditor,\n type EditorState,\n type LexicalNode,\n} from 'lexical';\nimport { $isHeadingNode } from '@lexical/rich-text';\nimport type { ToolbarStyleSnapshot } from './toolbar-style-store';\nimport { DEFAULT_TOOLBAR_STYLE_SNAPSHOT } from './toolbar-style-store';\nimport type { BlockType } from '../lexical/commands/block-types';\nimport { SUPPORTED_FONTS, type FontFamily } from '../lexical/plugins/font-plugin';\nimport { DEFAULT_FONT_SIZE } from '../lexical/plugins/font-size-plugin';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n extractInlineBlockTypeFromStyle,\n} from '../utils/text-style';\nimport { $isVariableNode } from '../variables/variable-node';\n\nconst FORMAT_MASKS = {\n bold: 1,\n italic: 2,\n strikethrough: 4,\n underline: 8,\n} as const;\n\nfunction normalizeFontFamily(fontFamily?: string): FontFamily {\n if (fontFamily && SUPPORTED_FONTS.includes(fontFamily as FontFamily)) {\n return fontFamily as FontFamily;\n }\n return 'Inter';\n}\n\nfunction normalizeAlignment(alignment: string): ElementFormatType {\n if (alignment === 'center' || alignment === 'right' || alignment === 'justify') {\n return alignment;\n }\n return 'left';\n}\n\nfunction getElementBlockType(node: LexicalNode): BlockType {\n const topLevelElement = node.getTopLevelElementOrThrow();\n if ($isHeadingNode(topLevelElement)) {\n return topLevelElement.getTag();\n }\n return 'paragraph';\n}\n\nfunction getElementAlignment(node: LexicalNode): ElementFormatType {\n const topLevelElement = node.getTopLevelElementOrThrow();\n if ($isElementNode(topLevelElement)) {\n return normalizeAlignment(topLevelElement.getFormatType());\n }\n return 'left';\n}\n\nfunction getInlineStyleTarget(nodes: LexicalNode[], anchorNode: LexicalNode): LexicalNode | null {\n if ($isTextNode(anchorNode) || $isVariableNode(anchorNode)) {\n return anchorNode;\n }\n return nodes.find(node => $isTextNode(node) || $isVariableNode(node)) ?? null;\n}\n\nfunction getInlineStyleFromNode(node: LexicalNode | null): string {\n if ($isTextNode(node) || $isVariableNode(node)) {\n return node.getStyle();\n }\n return '';\n}\n\nfunction hasInlineFormat(node: LexicalNode | null, format: keyof typeof FORMAT_MASKS): boolean {\n if ($isVariableNode(node)) {\n return (node.getFormat() & FORMAT_MASKS[format]) !== 0;\n }\n\n if (\n $isTextNode(node)\n && 'hasFormat' in node\n && typeof node.hasFormat === 'function'\n ) {\n return node.hasFormat(format);\n }\n\n if (\n $isTextNode(node)\n && 'getFormat' in node\n && typeof node.getFormat === 'function'\n ) {\n return (node.getFormat() & FORMAT_MASKS[format]) !== 0;\n }\n\n return false;\n}\n\nexport function readToolbarStyleSnapshot(\n editor: LexicalEditor,\n editorState: EditorState = editor.getEditorState(),\n): ToolbarStyleSnapshot {\n let snapshot = DEFAULT_TOOLBAR_STYLE_SNAPSHOT;\n\n editorState.read(() => {\n const currentSelection = $getSelection();\n const selection = $isNodeSelection(currentSelection)\n ? currentSelection\n : $createRangeSelectionFromDom(window.getSelection(), editor) ?? currentSelection;\n\n if ($isNodeSelection(selection)) {\n const variableNodes = selection.getNodes().filter($isVariableNode);\n if (variableNodes.length === 0) {\n return;\n }\n\n const firstVariableNode = variableNodes[0];\n const style = firstVariableNode.getStyle();\n snapshot = {\n blockType: extractInlineBlockTypeFromStyle(style)\n ?? getElementBlockType(firstVariableNode),\n fontFamily: normalizeFontFamily(extractFontFamilyFromStyle(style)),\n fontSize: extractFontSizePtFromStyle(style) ?? DEFAULT_FONT_SIZE,\n alignment: getElementAlignment(firstVariableNode),\n isBold: variableNodes.every(node => (node.getFormat() & FORMAT_MASKS.bold) !== 0),\n isItalic: variableNodes.every(node => (node.getFormat() & FORMAT_MASKS.italic) !== 0),\n isUnderline: variableNodes.every(node => (node.getFormat() & FORMAT_MASKS.underline) !== 0),\n isStrikethrough: variableNodes.every(node => (node.getFormat() & FORMAT_MASKS.strikethrough) !== 0),\n hasSelectedVariable: true,\n };\n return;\n }\n\n if (!$isRangeSelection(selection)) {\n return;\n }\n\n const anchorNode = selection.anchor.getNode();\n const inlineStyleTarget = getInlineStyleTarget(selection.getNodes(), anchorNode);\n const style = selection.style || getInlineStyleFromNode(inlineStyleTarget);\n const isCollapsed = selection.isCollapsed();\n snapshot = {\n blockType: extractInlineBlockTypeFromStyle(style) ?? getElementBlockType(anchorNode),\n fontFamily: normalizeFontFamily(extractFontFamilyFromStyle(style)),\n fontSize: extractFontSizePtFromStyle(style) ?? DEFAULT_FONT_SIZE,\n alignment: getElementAlignment(anchorNode),\n isBold: selection.hasFormat('bold') || (isCollapsed && hasInlineFormat(inlineStyleTarget, 'bold')),\n isItalic: selection.hasFormat('italic') || (isCollapsed && hasInlineFormat(inlineStyleTarget, 'italic')),\n isUnderline: selection.hasFormat('underline') || (isCollapsed && hasInlineFormat(inlineStyleTarget, 'underline')),\n isStrikethrough:\n selection.hasFormat('strikethrough') || (isCollapsed && hasInlineFormat(inlineStyleTarget, 'strikethrough')),\n hasSelectedVariable: false,\n };\n });\n\n return snapshot;\n}\n","import React, { useCallback, useEffect } from 'react';\nimport {\n $selectAll,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n type LexicalEditor,\n} from 'lexical';\nimport {\n Undo2,\n Redo2,\n Bold,\n Italic,\n Underline,\n Strikethrough,\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n ListOrdered,\n List,\n IndentIncrease,\n IndentDecrease,\n History,\n Type,\n ALargeSmall,\n} from 'lucide-react';\nimport { useDocument } from '../context/document-context';\nimport { useToolbarConfig } from '../context/toolbar-config';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { SUPPORTED_FONTS } from '../lexical/plugins/font-plugin';\nimport { applyFontFamily, type FontFamily } from '../lexical/plugins/font-plugin';\nimport {\n applyFontSize,\n SUPPORTED_FONT_SIZES,\n type FontSize,\n} from '../lexical/plugins/font-size-plugin';\nimport {\n toggleBold,\n toggleItalic,\n toggleUnderline,\n toggleStrikethrough,\n setAlignment,\n} from '../lexical/commands/format-commands';\nimport { insertList, indentContent, outdentContent } from '../lexical/commands/list-commands';\nimport {\n setBlockType,\n} from '../lexical/commands/block-commands';\nimport type { BlockType } from '../lexical/commands/block-types';\nimport {\n applyFontFamilyToSelectedVariables,\n applyFontSizeToSelectedVariables,\n toggleSelectedVariableFormat,\n} from '../variables/variable-formatting';\nimport { debug } from '../utils/debug';\nimport { BlockTypePicker, getBlockTypeLabel } from './BlockTypePicker';\nimport { CanvasControls } from './CanvasControls';\nimport { readToolbarStyleSnapshot } from '../context/toolbar-style-snapshot';\nimport { useToolbarStyleStore, useToolbarStyleStoreApi } from '../context/toolbar-style-store';\n\nexport const Toolbar: React.FC = () => {\n const {\n activeEditor,\n canRedo,\n canUndo,\n editorRegistry,\n globalSelectionActive,\n historySidebarOpen,\n redo,\n runHistoryAction,\n setHistorySidebarOpen,\n undo,\n } = useDocument();\n const { toolbarItems, toolbarEndItems } = useExtensions();\n const toolbarConfig = useToolbarConfig();\n const t = useTranslations();\n const toolbarStyleStore = useToolbarStyleStoreApi();\n const activeBlockType = useToolbarStyleStore(state => state.blockType);\n const activeFontFamily = useToolbarStyleStore(state => state.fontFamily);\n const activeFontSize = useToolbarStyleStore(state => state.fontSize);\n const activeAlignment = useToolbarStyleStore(state => state.alignment);\n const isBoldActive = useToolbarStyleStore(state => state.isBold);\n const isItalicActive = useToolbarStyleStore(state => state.isItalic);\n const isUnderlineActive = useToolbarStyleStore(state => state.isUnderline);\n const isStrikethroughActive = useToolbarStyleStore(state => state.isStrikethrough);\n\n const withBodySelection = useCallback(\n (editor: LexicalEditor, action: (targetEditor: LexicalEditor) => void) => {\n editor.update(() => {\n $selectAll();\n });\n action(editor);\n },\n [],\n );\n\n const applyToBodyEditors = useCallback(\n (action: (targetEditor: LexicalEditor) => void) => {\n const targetEditors = globalSelectionActive\n ? editorRegistry.all()\n : activeEditor\n ? [activeEditor]\n : [];\n\n targetEditors.forEach(editor => {\n if (globalSelectionActive) {\n withBodySelection(editor, action);\n } else {\n action(editor);\n }\n });\n },\n [activeEditor, editorRegistry, globalSelectionActive, withBodySelection],\n );\n\n const runToolbarAction = useCallback(\n (label: string, callback: () => void) => {\n runHistoryAction(\n {\n label,\n source: 'toolbar',\n region: 'document',\n },\n callback,\n );\n },\n [runHistoryAction],\n );\n\n useEffect(() => {\n if (!activeEditor) {\n toolbarStyleStore.getState().reset();\n return;\n }\n\n const updateSelectionState = (editorState = activeEditor.getEditorState()) => {\n toolbarStyleStore.getState().setSnapshot(readToolbarStyleSnapshot(activeEditor, editorState));\n };\n\n updateSelectionState();\n const unregisterSelectionChange = activeEditor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n updateSelectionState();\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n const unregisterUpdateListener = activeEditor.registerUpdateListener(({ editorState }) => {\n updateSelectionState(editorState);\n });\n\n return () => {\n unregisterSelectionChange();\n unregisterUpdateListener();\n };\n }, [activeEditor, toolbarStyleStore]);\n\n const handleBold = useCallback(() => {\n debug('toolbar', `bold (globalSelection=${globalSelectionActive}, editors=${editorRegistry.all().length}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.boldApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'bold')) {\n return;\n }\n applyToBodyEditors(toggleBold);\n });\n }, [activeEditor, applyToBodyEditors, editorRegistry, globalSelectionActive, runToolbarAction, t.history.actions.boldApplied]);\n\n const handleItalic = useCallback(() => {\n debug('toolbar', `italic (globalSelection=${globalSelectionActive}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.italicApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'italic')) {\n return;\n }\n applyToBodyEditors(toggleItalic);\n });\n }, [activeEditor, applyToBodyEditors, globalSelectionActive, runToolbarAction, t.history.actions.italicApplied]);\n\n const handleUnderline = useCallback(() => {\n debug('toolbar', `underline (globalSelection=${globalSelectionActive}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.underlineApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'underline')) {\n return;\n }\n applyToBodyEditors(toggleUnderline);\n });\n }, [activeEditor, applyToBodyEditors, globalSelectionActive, runToolbarAction, t.history.actions.underlineApplied]);\n\n const handleStrikethrough = useCallback(() => {\n debug('toolbar', `strikethrough (globalSelection=${globalSelectionActive}, hasEditor=${!!activeEditor})`);\n runToolbarAction(t.history.actions.strikethroughApplied, () => {\n if (activeEditor && toggleSelectedVariableFormat(activeEditor, 'strikethrough')) {\n return;\n }\n applyToBodyEditors(toggleStrikethrough);\n });\n }, [activeEditor, applyToBodyEditors, globalSelectionActive, runToolbarAction, t.history.actions.strikethroughApplied]);\n\n const handleAlignLeft = useCallback(() => {\n runToolbarAction(t.history.actions.alignedLeft, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'left'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.alignedLeft]);\n\n const handleAlignCenter = useCallback(() => {\n runToolbarAction(t.history.actions.alignedCenter, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'center'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.alignedCenter]);\n\n const handleAlignRight = useCallback(() => {\n runToolbarAction(t.history.actions.alignedRight, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'right'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.alignedRight]);\n\n const handleAlignJustify = useCallback(() => {\n runToolbarAction(t.history.actions.justifiedText, () => {\n applyToBodyEditors(editor => setAlignment(editor, 'justify'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.justifiedText]);\n\n const handleListNumber = useCallback(() => {\n runToolbarAction(t.history.actions.insertedNumberedList, () => {\n applyToBodyEditors(editor => insertList(editor, 'number'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.insertedNumberedList]);\n\n const handleListBullet = useCallback(() => {\n runToolbarAction(t.history.actions.insertedBulletList, () => {\n applyToBodyEditors(editor => insertList(editor, 'bullet'));\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.insertedBulletList]);\n\n const handleIndent = useCallback(() => {\n runToolbarAction(t.history.actions.indentedContent, () => {\n applyToBodyEditors(indentContent);\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.indentedContent]);\n\n const handleOutdent = useCallback(() => {\n runToolbarAction(t.history.actions.outdentedContent, () => {\n applyToBodyEditors(outdentContent);\n });\n }, [applyToBodyEditors, runToolbarAction, t.history.actions.outdentedContent]);\n\n const handleFontChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const fontFamily = e.target.value as FontFamily;\n runToolbarAction(interpolate(t.history.actions.fontChanged, { value: fontFamily }), () => {\n if (activeEditor && applyFontFamilyToSelectedVariables(activeEditor, fontFamily)) {\n return;\n }\n applyToBodyEditors(editor => applyFontFamily(editor, fontFamily));\n });\n },\n [activeEditor, applyToBodyEditors, runToolbarAction, t.history.actions.fontChanged],\n );\n\n const handleFontSizeChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const size = parseInt(e.target.value, 10) as FontSize;\n runToolbarAction(interpolate(t.history.actions.fontSizeChanged, { value: String(size) }), () => {\n if (activeEditor && applyFontSizeToSelectedVariables(activeEditor, size)) {\n return;\n }\n applyToBodyEditors(editor => applyFontSize(editor, size));\n });\n },\n [activeEditor, applyToBodyEditors, runToolbarAction, t.history.actions.fontSizeChanged],\n );\n\n const handleBlockTypeChange = useCallback(\n (blockType: BlockType) => {\n runToolbarAction(\n interpolate(t.history.actions.blockTypeChanged, { value: getBlockTypeLabel(t, blockType) }),\n () => {\n applyToBodyEditors(editor => setBlockType(editor, blockType));\n },\n );\n },\n [\n applyToBodyEditors,\n runToolbarAction,\n t.history.actions.blockTypeChanged,\n t,\n ],\n );\n\n const handleToggleHistory = useCallback(() => {\n setHistorySidebarOpen(!historySidebarOpen);\n }, [historySidebarOpen, setHistorySidebarOpen]);\n\n return (\n <div\n className=\"lex4-toolbar\"\n data-testid=\"toolbar\"\n >\n <div className=\"lex4-toolbar-row\">\n <div className=\"lex4-toolbar-group\" data-testid=\"history-controls\">\n <ToolbarIconButton\n title={t.toolbar.undo}\n testId=\"btn-undo\"\n disabled={!canUndo}\n onClick={undo}\n >\n <Undo2 size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton\n title={t.toolbar.redo}\n testId=\"btn-redo\"\n disabled={!canRedo}\n onClick={redo}\n >\n <Redo2 size={15} />\n </ToolbarIconButton>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\">\n <BlockTypePicker\n value={activeBlockType}\n onChange={handleBlockTypeChange}\n />\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group-gap\">\n <Type size={14} className=\"lex4-toolbar-icon\" />\n <select\n className=\"lex4-toolbar-select\"\n data-testid=\"font-selector\"\n value={activeFontFamily}\n onChange={handleFontChange}\n >\n {SUPPORTED_FONTS.map(font => (\n <option key={font} value={font} style={{ fontFamily: font }}>\n {font}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"lex4-toolbar-group-gap\">\n <ALargeSmall size={14} className=\"lex4-toolbar-icon\" />\n <select\n className=\"lex4-toolbar-select lex4-toolbar-select-narrow\"\n data-testid=\"font-size-selector\"\n value={String(activeFontSize)}\n onChange={handleFontSizeChange}\n >\n {SUPPORTED_FONT_SIZES.map(size => (\n <option key={size} value={size}>\n {size}\n </option>\n ))}\n </select>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\" data-testid=\"format-group\">\n <ToolbarIconButton title={t.toolbar.bold} testId=\"btn-bold\" active={isBoldActive} onClick={handleBold}>\n <Bold size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.italic} testId=\"btn-italic\" active={isItalicActive} onClick={handleItalic}>\n <Italic size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.underline} testId=\"btn-underline\" active={isUnderlineActive} onClick={handleUnderline}>\n <Underline size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.strikethrough} testId=\"btn-strike\" active={isStrikethroughActive} onClick={handleStrikethrough}>\n <Strikethrough size={15} />\n </ToolbarIconButton>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\" data-testid=\"align-group\">\n <ToolbarIconButton title={t.toolbar.alignLeft} testId=\"btn-align-left\" active={activeAlignment === 'left'} onClick={handleAlignLeft}>\n <AlignLeft size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.alignCenter} testId=\"btn-align-center\" active={activeAlignment === 'center'} onClick={handleAlignCenter}>\n <AlignCenter size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.alignRight} testId=\"btn-align-right\" active={activeAlignment === 'right'} onClick={handleAlignRight}>\n <AlignRight size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.justify} testId=\"btn-align-justify\" active={activeAlignment === 'justify'} onClick={handleAlignJustify}>\n <AlignJustify size={15} />\n </ToolbarIconButton>\n </div>\n\n <Divider />\n\n <div className=\"lex4-toolbar-group\" data-testid=\"list-group\">\n <ToolbarIconButton title={t.toolbar.numberedList} testId=\"btn-list-number\" onClick={handleListNumber}>\n <ListOrdered size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.bulletList} testId=\"btn-list-bullet\" onClick={handleListBullet}>\n <List size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.indent} testId=\"btn-indent\" onClick={handleIndent}>\n <IndentIncrease size={15} />\n </ToolbarIconButton>\n <ToolbarIconButton title={t.toolbar.outdent} testId=\"btn-outdent\" onClick={handleOutdent}>\n <IndentDecrease size={15} />\n </ToolbarIconButton>\n </div>\n\n {toolbarItems.length > 0 && (\n <>\n <Divider />\n {toolbarItems.map((ToolbarItem, idx) => (\n <ToolbarItem key={idx} />\n ))}\n </>\n )}\n\n <Divider />\n\n <CanvasControls />\n\n <div className=\"lex4-toolbar-end\">\n {toolbarEndItems.map((EndItem, idx) => (\n <EndItem key={idx} />\n ))}\n {toolbarConfig.history.visible && (\n <button\n type=\"button\"\n className={`lex4-toolbar-toggle-btn${historySidebarOpen ? ' active' : ''}`}\n onMouseDown={(e) => e.preventDefault()}\n onClick={handleToggleHistory}\n data-testid=\"toggle-history-sidebar\"\n title={historySidebarOpen ? t.toolbar.closeHistory : t.toolbar.openHistory}\n aria-label={historySidebarOpen ? t.toolbar.closeHistory : t.toolbar.openHistory}\n >\n <History size={14} />\n {toolbarConfig.history.showLabel && t.toolbar.history}\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n\ninterface ToolbarIconButtonProps {\n title: string;\n testId: string;\n disabled?: boolean;\n active?: boolean;\n onClick?: () => void;\n children: React.ReactNode;\n}\n\nconst ToolbarIconButton: React.FC<ToolbarIconButtonProps> = ({\n title,\n testId,\n disabled = false,\n active = false,\n onClick,\n children,\n}) => (\n <button\n type=\"button\"\n title={title}\n aria-label={title}\n aria-pressed={active}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={onClick}\n className={`lex4-toolbar-btn${active ? ' active' : ''}`}\n data-testid={testId}\n >\n {children}\n </button>\n);\n\nconst Divider: React.FC = () => (\n <div className=\"lex4-toolbar-separator\" />\n);\n","import {\n A4_HEIGHT_PX,\n PAGE_MARGIN_TOP_PX,\n PAGE_MARGIN_BOTTOM_PX,\n} from './dimensions';\n\nexport function computeBodyHeight(\n headerHeight: number,\n footerHeight: number,\n): number {\n const verticalMargins = PAGE_MARGIN_TOP_PX + PAGE_MARGIN_BOTTOM_PX;\n return A4_HEIGHT_PX - headerHeight - footerHeight - verticalMargins;\n}\n\n/**\n * Computes the content area height based on whether\n * headers/footers are enabled.\n */\nexport function computeContentAreaHeight(\n headerFooterEnabled: boolean,\n headerHeight: number,\n footerHeight: number,\n): number {\n if (!headerFooterEnabled) {\n return computeBodyHeight(0, 0);\n }\n return computeBodyHeight(headerHeight, footerHeight);\n}\n","import type { SerializedEditorState, SerializedLexicalNode } from 'lexical';\n\n/**\n * Utilities for splitting and merging Lexical editor states.\n *\n * A SerializedEditorState has shape:\n * { root: { children: [...], type: \"root\", ... } }\n *\n * Content flow between pages is achieved by manipulating\n * the root.children array — extracting, splitting, merging\n * top-level block nodes.\n */\n\n/** Extract all top-level nodes from a serialized editor state */\nexport function getTopLevelNodes(state: SerializedEditorState | null): SerializedLexicalNode[] {\n if (!state) return [];\n return (state.root as any).children ?? [];\n}\n\n/** Count top-level nodes in a serialized editor state */\nexport function countTopLevelNodes(state: SerializedEditorState | null): number {\n return getTopLevelNodes(state).length;\n}\n\n/**\n * Create a SerializedEditorState from a list of top-level nodes.\n * Uses a standard root wrapper.\n */\nexport function createEditorStateFromNodes(\n nodes: SerializedLexicalNode[],\n): SerializedEditorState {\n return {\n root: {\n children: nodes,\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState;\n}\n\n/**\n * Split a serialized editor state at a given node index.\n *\n * Returns [before, after] where:\n * - before contains nodes 0..splitIndex-1\n * - after contains nodes splitIndex..end\n */\nexport function splitEditorState(\n state: SerializedEditorState | null,\n splitIndex: number,\n): [SerializedEditorState | null, SerializedEditorState | null] {\n const nodes = getTopLevelNodes(state);\n\n if (splitIndex <= 0) {\n return [null, state];\n }\n if (splitIndex >= nodes.length) {\n return [state, null];\n }\n\n const before = nodes.slice(0, splitIndex);\n const after = nodes.slice(splitIndex);\n\n return [\n before.length > 0 ? createEditorStateFromNodes(before) : null,\n after.length > 0 ? createEditorStateFromNodes(after) : null,\n ];\n}\n\n/**\n * Merge two serialized editor states by concatenating their top-level nodes.\n * Returns a new state with all nodes from both states.\n */\nexport function mergeEditorStates(\n stateA: SerializedEditorState | null,\n stateB: SerializedEditorState | null,\n): SerializedEditorState | null {\n const nodesA = getTopLevelNodes(stateA);\n const nodesB = getTopLevelNodes(stateB);\n\n const all = [...nodesA, ...nodesB];\n if (all.length === 0) return null;\n\n return createEditorStateFromNodes(all);\n}\n\n/**\n * Append nodes to the end of a serialized editor state.\n */\nexport function appendNodes(\n state: SerializedEditorState | null,\n nodes: SerializedLexicalNode[],\n): SerializedEditorState {\n const existing = getTopLevelNodes(state);\n return createEditorStateFromNodes([...existing, ...nodes]);\n}\n\n/**\n * Split a serialized block node's children at a given child offset.\n *\n * Returns two copies of the block: the first has children [0, offset),\n * the second has children [offset, end). Both keep the same node type,\n * format, direction, indent, and version.\n *\n * Returns null pair if the offset is out of range.\n */\nexport function splitBlockNode(\n block: SerializedLexicalNode,\n childOffset: number,\n): [SerializedLexicalNode | null, SerializedLexicalNode | null] {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const children: SerializedLexicalNode[] = (block as any).children ?? [];\n\n if (childOffset <= 0) return [null, structuredClone(block)];\n if (childOffset >= children.length) return [structuredClone(block), null];\n\n const before = children.slice(0, childOffset);\n const after = children.slice(childOffset);\n\n const makeCopy = (kids: SerializedLexicalNode[]): SerializedLexicalNode => {\n const copy = structuredClone(block);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (copy as any).children = kids;\n return copy;\n };\n\n return [makeCopy(before), makeCopy(after)];\n}\n\n/**\n * Remove the last N nodes from a serialized editor state.\n * Returns [trimmedState, removedNodes].\n */\nexport function removeLastNodes(\n state: SerializedEditorState | null,\n count: number,\n): [SerializedEditorState | null, SerializedLexicalNode[]] {\n const nodes = getTopLevelNodes(state);\n if (count >= nodes.length) {\n return [null, [...nodes]];\n }\n\n const kept = nodes.slice(0, nodes.length - count);\n const removed = nodes.slice(nodes.length - count);\n\n return [\n kept.length > 0 ? createEditorStateFromNodes(kept) : null,\n removed,\n ];\n}\n\n/**\n * Remove the first N nodes from a serialized editor state.\n * Returns [removedNodes, remainingState].\n */\nexport function removeFirstNodes(\n state: SerializedEditorState | null,\n count: number,\n): [SerializedLexicalNode[], SerializedEditorState | null] {\n const nodes = getTopLevelNodes(state);\n if (count >= nodes.length) {\n return [[...nodes], null];\n }\n\n const removed = nodes.slice(0, count);\n const remaining = nodes.slice(count);\n\n return [\n removed,\n remaining.length > 0 ? createEditorStateFromNodes(remaining) : null,\n ];\n}\n","import { useCallback, useRef } from 'react';\nimport type { SerializedEditorState } from 'lexical';\nimport type { DocumentAction } from '../context/document-context';\nimport { computeBodyHeight } from '../constants/page-layout';\nimport {\n getTopLevelNodes,\n splitEditorState,\n splitBlockNode,\n mergeEditorStates,\n createEditorStateFromNodes,\n} from '../utils/editor-state-utils';\nimport type { Lex4Document, PageState } from '../types/document';\nimport { createEmptyPage, createPageFromTemplate } from '../types/document';\n\n/**\n * usePagination — Orchestrates content flow between pages.\n *\n * When a page body overflows, this hook:\n * 1. Measures which nodes fit within the body height\n * 2. Splits the editor state at the overflow point\n * 3. Moves overflow content to the next page (creating it if needed)\n * 4. Cascades forward through all subsequent pages\n *\n * When a page body underflows (content deleted), it:\n * 1. Checks if the next page has content that fits\n * 2. Pulls content back from the next page\n * 3. Removes empty trailing pages\n */\nexport function usePagination(\n document: Lex4Document,\n dispatch: React.Dispatch<DocumentAction>,\n) {\n const reflowingRef = useRef(false);\n const pendingReflowRef = useRef(false);\n\n /**\n * Estimate how many top-level nodes fit within a given pixel height.\n *\n * Since we don't have DOM measurements at this point (the nodes may not\n * be rendered yet), we use a heuristic: assume each top-level paragraph\n * is approximately 24px (one line of text). This is imperfect but\n * provides a reasonable starting split point. The ResizeObserver in\n * PageBody will trigger another reflow if the estimate was wrong.\n */\n const estimateNodesFitting = useCallback(\n (\n state: SerializedEditorState | null,\n bodyHeight: number,\n ): number => {\n const nodes = getTopLevelNodes(state);\n if (nodes.length === 0) return 0;\n\n const estimatedLineHeight = 24;\n let usedHeight = 0;\n let fitCount = 0;\n\n for (const _node of nodes) {\n usedHeight += estimatedLineHeight;\n if (usedHeight > bodyHeight) break;\n fitCount++;\n }\n\n // At least one node must stay on the current page\n return Math.max(1, fitCount);\n },\n [],\n );\n\n /**\n * Handle overflow on a specific page.\n * Splits content and pushes overflow to the next page.\n */\n const handlePageOverflow = useCallback(\n (pageIndex: number) => {\n if (reflowingRef.current) {\n pendingReflowRef.current = true;\n return;\n }\n\n reflowingRef.current = true;\n\n try {\n const pages = document.pages;\n const page = pages[pageIndex];\n if (!page) return;\n\n const headerH = document.headerFooterEnabled ? page.headerHeight : 0;\n const footerH = document.headerFooterEnabled ? page.footerHeight : 0;\n const bodyHeight = computeBodyHeight(headerH, footerH);\n\n const nodes = getTopLevelNodes(page.bodyState);\n if (nodes.length <= 1) {\n // Single block overflow — attempt heuristic mid-block split on\n // the serialized node. The real DOM-based split in OverflowPlugin\n // will correct this on render if the estimate is off.\n if (nodes.length === 1) {\n const singleNode = nodes[0];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const children = (singleNode as any).children;\n if (children && children.length > 1) {\n const estimatedLineHeight = 24;\n const maxChildren = Math.max(1, Math.floor(bodyHeight / estimatedLineHeight));\n if (maxChildren < children.length) {\n const [keepBlock, overflowBlock] = splitBlockNode(singleNode, maxChildren);\n if (keepBlock && overflowBlock) {\n const keepState = createEditorStateFromNodes([keepBlock]);\n const overflowState = createEditorStateFromNodes([overflowBlock]);\n\n const nextPage = pages[pageIndex + 1];\n if (nextPage) {\n const mergedBody = mergeEditorStates(overflowState, nextPage.bodyState);\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: pages.map((p, i) => {\n if (i === pageIndex) return { ...p, bodyState: keepState };\n if (i === pageIndex + 1) return { ...p, bodyState: mergedBody };\n return p;\n }),\n },\n });\n } else {\n const newPage: PageState = {\n ...createPageFromTemplate({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n }),\n bodyState: overflowState,\n };\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: [\n ...pages.map((p, i) =>\n i === pageIndex ? { ...p, bodyState: keepState } : p,\n ),\n newPage,\n ],\n },\n });\n }\n }\n }\n }\n }\n return;\n }\n\n const fitCount = estimateNodesFitting(page.bodyState, bodyHeight);\n if (fitCount >= nodes.length) return; // Everything fits\n\n const [keepState, overflowState] = splitEditorState(page.bodyState, fitCount);\n\n if (!overflowState) return; // Nothing to overflow\n\n // Get or create the next page\n const nextPage = pages[pageIndex + 1];\n if (nextPage) {\n // Merge overflow into the beginning of the next page\n const mergedBody = mergeEditorStates(overflowState, nextPage.bodyState);\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: pages.map((p, i) => {\n if (i === pageIndex) return { ...p, bodyState: keepState };\n if (i === pageIndex + 1) return { ...p, bodyState: mergedBody };\n return p;\n }),\n },\n });\n } else {\n // Create a new page with overflow content\n const newPage: PageState = {\n ...createPageFromTemplate({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n }),\n bodyState: overflowState,\n };\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: [\n ...pages.map((p, i) =>\n i === pageIndex ? { ...p, bodyState: keepState } : p,\n ),\n newPage,\n ],\n },\n });\n }\n } finally {\n reflowingRef.current = false;\n\n if (pendingReflowRef.current) {\n pendingReflowRef.current = false;\n // Schedule another reflow on next tick\n setTimeout(() => handlePageOverflow(pageIndex), 0);\n }\n }\n },\n [document, dispatch, estimateNodesFitting],\n );\n\n /**\n * Handle underflow — try to pull content from the next page.\n */\n const handlePageUnderflow = useCallback(\n (pageIndex: number) => {\n if (reflowingRef.current) return;\n\n const pages = document.pages;\n const page = pages[pageIndex];\n const nextPage = pages[pageIndex + 1];\n\n if (!page || !nextPage) return;\n\n const nextNodes = getTopLevelNodes(nextPage.bodyState);\n if (nextNodes.length === 0) {\n // Next page is empty — remove it (unless it's the only page)\n if (pages.length > 1) {\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: pages.filter((_, i) => i !== pageIndex + 1),\n },\n });\n }\n return;\n }\n\n // Try to pull the first node from the next page\n const headerH = document.headerFooterEnabled ? page.headerHeight : 0;\n const footerH = document.headerFooterEnabled ? page.footerHeight : 0;\n const bodyHeight = computeBodyHeight(headerH, footerH);\n\n const currentNodes = getTopLevelNodes(page.bodyState);\n const estimatedCurrentHeight = currentNodes.length * 24;\n const remainingSpace = bodyHeight - estimatedCurrentHeight;\n\n if (remainingSpace > 24) {\n // Pull the first node from next page\n const [pulled, remaining] = [nextNodes.slice(0, 1), nextNodes.slice(1)];\n\n const updatedCurrent = mergeEditorStates(\n page.bodyState,\n createEditorStateFromNodes(pulled),\n );\n const updatedNext =\n remaining.length > 0 ? createEditorStateFromNodes(remaining) : null;\n\n const newPages = pages.map((p, i) => {\n if (i === pageIndex) return { ...p, bodyState: updatedCurrent };\n if (i === pageIndex + 1) return { ...p, bodyState: updatedNext };\n return p;\n });\n\n // Remove empty trailing pages\n while (newPages.length > 1) {\n const last = newPages[newPages.length - 1];\n if (getTopLevelNodes(last.bodyState).length === 0) {\n newPages.pop();\n } else {\n break;\n }\n }\n\n dispatch({\n type: 'SET_DOCUMENT',\n document: { ...document, pages: newPages },\n });\n }\n },\n [document, dispatch],\n );\n\n /**\n * Full document reflow — recalculate all pages from scratch.\n * Used after toggle changes or major content operations.\n */\n const reflowAll = useCallback(() => {\n if (reflowingRef.current) return;\n reflowingRef.current = true;\n\n try {\n const pages = document.pages;\n\n // Collect all body content across all pages\n const allNodes = pages.flatMap(p => getTopLevelNodes(p.bodyState));\n if (allNodes.length === 0) {\n // Ensure at least one page\n if (pages.length !== 1) {\n dispatch({\n type: 'SET_DOCUMENT',\n document: {\n ...document,\n pages: [pages[0] ?? createEmptyPage()],\n },\n });\n }\n return;\n }\n\n // Distribute nodes across pages\n const newPages: PageState[] = [];\n let remainingNodes = [...allNodes];\n let pageIdx = 0;\n\n while (remainingNodes.length > 0) {\n const existingPage = pages[pageIdx];\n const headerH = document.headerFooterEnabled\n ? (existingPage?.headerHeight ?? 0)\n : 0;\n const footerH = document.headerFooterEnabled\n ? (existingPage?.footerHeight ?? 0)\n : 0;\n const bodyHeight = computeBodyHeight(headerH, footerH);\n const estimatedLineHeight = 24;\n const maxNodes = Math.max(1, Math.floor(bodyHeight / estimatedLineHeight));\n\n const pageNodes = remainingNodes.slice(0, maxNodes);\n remainingNodes = remainingNodes.slice(maxNodes);\n\n const basePage = existingPage ?? createPageFromTemplate({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n });\n newPages.push({\n ...basePage,\n bodyState: createEditorStateFromNodes(pageNodes),\n });\n\n pageIdx++;\n }\n\n dispatch({\n type: 'SET_DOCUMENT',\n document: { ...document, pages: newPages },\n });\n } finally {\n reflowingRef.current = false;\n }\n }, [document, dispatch]);\n\n return {\n handlePageOverflow,\n handlePageUnderflow,\n reflowAll,\n };\n}\n","import type { EditorThemeClasses } from 'lexical';\n\n/**\n * Lexical theme configuration — maps Lexical CSS class names\n * to stable Lex4 class strings for consistent styling.\n */\nexport const lexicalTheme: EditorThemeClasses = {\n root: 'lex4-root',\n paragraph: 'lex4-paragraph',\n heading: {\n h1: 'lex4-heading lex4-heading-h1',\n h2: 'lex4-heading lex4-heading-h2',\n h3: 'lex4-heading lex4-heading-h3',\n h4: 'lex4-heading lex4-heading-h4',\n h5: 'lex4-heading lex4-heading-h5',\n h6: 'lex4-heading lex4-heading-h6',\n },\n text: {\n bold: 'lex4-text-bold',\n italic: 'lex4-text-italic',\n underline: 'lex4-text-underline',\n strikethrough: 'lex4-text-strikethrough',\n underlineStrikethrough: 'lex4-text-underline lex4-text-strikethrough',\n },\n list: {\n nested: {\n listitem: 'lex4-listitem-nested',\n },\n ol: 'lex4-list lex4-list-ordered',\n ul: 'lex4-list lex4-list-unordered',\n listitem: 'lex4-listitem',\n listitemChecked: 'lex4-listitem-checked',\n listitemUnchecked: 'lex4-listitem-unchecked',\n },\n quote: 'lex4-quote',\n};\n","import type { InitialConfigType } from '@lexical/react/LexicalComposer';\nimport type { EditorThemeClasses, Klass, LexicalNode } from 'lexical';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\nimport { ListNode, ListItemNode } from '@lexical/list';\n\nimport { lexicalTheme } from './theme';\n\nexport type EditorMode = 'body' | 'header' | 'footer';\n\nconst DEFAULT_NODES: Klass<LexicalNode>[] = [HeadingNode, QuoteNode, ListNode, ListItemNode];\n\n/**\n * Creates a Lexical editor configuration for the given mode.\n *\n * Each mode gets its own namespace to avoid conflicts when\n * multiple Lexical editors coexist on the same page.\n *\n * @param extraNodes - Additional node classes contributed by extensions\n * @param themeOverrides - Theme class overrides from extensions\n */\nexport function createEditorConfig(\n mode: EditorMode,\n pageId?: string,\n extraNodes: Klass<LexicalNode>[] = [],\n themeOverrides: Partial<EditorThemeClasses> = {},\n): InitialConfigType {\n const namespace = pageId ? `lex4-${mode}-${pageId}` : `lex4-${mode}`;\n\n return {\n namespace,\n theme: { ...lexicalTheme, ...themeOverrides },\n nodes: [...DEFAULT_NODES, ...extraNodes],\n onError: (error: Error) => {\n console.error(`[Lex4 ${mode} editor error]`, error);\n },\n };\n}\n","import React, { useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_LOW, KEY_TAB_COMMAND } from 'lexical';\nimport { indentContent, outdentContent } from '../commands/list-commands';\n\n/**\n * TabIndentPlugin — handles Tab and Shift+Tab for indentation shortcuts.\n *\n * List items use Lexical's native nesting behavior. Regular paragraphs use the\n * editor's first-line indent behavior.\n */\nexport const TabIndentPlugin: React.FC = () => {\n const [editor] = useLexicalComposerContext();\n\n const handleTab = useCallback(\n (event: KeyboardEvent) => {\n event.preventDefault();\n if (event.shiftKey) {\n outdentContent(editor);\n } else {\n indentContent(editor);\n }\n return true;\n },\n [editor],\n );\n\n React.useEffect(() => {\n return editor.registerCommand(KEY_TAB_COMMAND, handleTab, COMMAND_PRIORITY_LOW);\n }, [editor, handleTab]);\n\n return null;\n};\n","import React, { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { $getRoot, $isElementNode, $isParagraphNode, type ElementNode } from 'lexical';\n\nconst FIRST_LINE_INDENT_PX = 40;\n\nfunction visitElements(node: ElementNode, callback: (element: ElementNode) => void): void {\n callback(node);\n\n for (const child of node.getChildren()) {\n if ($isElementNode(child)) {\n visitElements(child, callback);\n }\n }\n}\n\n/**\n * Applies first-line paragraph indentation in the DOM while leaving\n * Lexical's serialized paragraph indent levels intact.\n */\nexport const ParagraphIndentPlugin: React.FC = () => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const syncParagraphIndents = () => editor.getEditorState().read(() => {\n visitElements($getRoot(), node => {\n if (!$isParagraphNode(node)) {\n return;\n }\n\n const element = editor.getElementByKey(node.getKey());\n if (!(element instanceof HTMLElement)) {\n return;\n }\n\n const indent = node.getIndent();\n element.style.paddingInlineStart = '0px';\n element.style.textIndent = indent > 0 ? `${indent * FIRST_LINE_INDENT_PX}px` : '';\n });\n });\n\n syncParagraphIndents();\n\n return editor.registerUpdateListener(() => {\n syncParagraphIndents();\n });\n }, [editor]);\n\n return null;\n};\n","import React from 'react';\n\n/**\n * PastePlugin — placeholder for paste normalization.\n *\n * Overflow detection after paste is handled by the OverflowPlugin\n * which monitors content size changes via ResizeObserver.\n */\nexport const PastePlugin: React.FC = () => {\n return null;\n};\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $createRangeSelectionFromDom,\n $getRoot,\n $setSelection,\n COMMAND_PRIORITY_LOW,\n FOCUS_COMMAND,\n} from 'lexical';\nimport type { LexicalEditor } from 'lexical';\nimport { useDocument } from '../../context/document-context';\nimport type { CaretPosition } from '../../types/history';\nimport { debug } from '../../utils/debug';\n\ninterface ActiveEditorPluginProps {\n pageId: string;\n region: CaretPosition['region'];\n onFocus?: (editor: LexicalEditor) => void;\n}\n\nfunction resolveTextOffset(root: HTMLElement, targetOffset: number): { node: Node; offset: number } {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n let remaining = targetOffset;\n let currentNode = walker.nextNode();\n let lastTextNode: Node | null = null;\n\n while (currentNode) {\n const textLength = currentNode.textContent?.length ?? 0;\n if (remaining <= textLength) {\n return { node: currentNode, offset: remaining };\n }\n\n remaining -= textLength;\n lastTextNode = currentNode;\n currentNode = walker.nextNode();\n }\n\n if (lastTextNode) {\n return {\n node: lastTextNode,\n offset: lastTextNode.textContent?.length ?? 0,\n };\n }\n\n return {\n node: root,\n offset: root.childNodes.length,\n };\n}\n\n/**\n * ActiveEditorPlugin — Registers the editor in the document context on focus.\n *\n * This enables the toolbar to dispatch commands (bold, italic, etc.)\n * to whichever editor the user is currently editing.\n */\nexport const ActiveEditorPlugin: React.FC<ActiveEditorPluginProps> = ({\n pageId,\n region,\n onFocus,\n}) => {\n const [editor] = useLexicalComposerContext();\n const {\n consumePendingCaretPosition,\n consumePendingFocusAtEnd,\n focusAtEndVersion,\n setActiveEditor,\n setActivePageId,\n } = useDocument();\n\n useEffect(() => {\n const caretPosition: CaretPosition = { pageId, region };\n const selectionToRestore = consumePendingCaretPosition(caretPosition);\n if (selectionToRestore === undefined) {\n return;\n }\n\n requestAnimationFrame(() => {\n setActivePageId(pageId);\n setActiveEditor(editor, caretPosition);\n editor.focus();\n if (!selectionToRestore) {\n return;\n }\n\n requestAnimationFrame(() => {\n const rootElement = editor.getRootElement();\n const domSelection = window.getSelection();\n if (!rootElement || !domSelection) {\n return;\n }\n\n const anchorPoint = resolveTextOffset(rootElement, selectionToRestore.anchorTextOffset);\n const focusPoint = resolveTextOffset(rootElement, selectionToRestore.focusTextOffset);\n const range = document.createRange();\n range.setStart(anchorPoint.node, anchorPoint.offset);\n range.setEnd(focusPoint.node, focusPoint.offset);\n\n domSelection.removeAllRanges();\n domSelection.addRange(range);\n\n editor.update(() => {\n const nextSelection = $createRangeSelectionFromDom(window.getSelection(), editor);\n if (nextSelection) {\n $setSelection(nextSelection);\n }\n });\n });\n });\n }, [consumePendingCaretPosition, editor, pageId, region, setActiveEditor, setActivePageId]);\n\n useEffect(() => {\n const caretPosition: CaretPosition = { pageId, region };\n if (!consumePendingFocusAtEnd(caretPosition)) {\n return;\n }\n\n requestAnimationFrame(() => {\n setActivePageId(pageId);\n setActiveEditor(editor, caretPosition);\n editor.focus(() => {\n editor.update(() => {\n $getRoot().selectEnd();\n });\n });\n });\n }, [\n consumePendingFocusAtEnd,\n editor,\n focusAtEndVersion,\n pageId,\n region,\n setActiveEditor,\n setActivePageId,\n ]);\n\n useEffect(() => {\n const caretPosition: CaretPosition = { pageId, region };\n const markEditorActive = () => {\n setActivePageId(pageId);\n setActiveEditor(editor, caretPosition);\n onFocus?.(editor);\n };\n\n return editor.registerRootListener((rootElement, prevRootElement) => {\n prevRootElement?.removeEventListener('focusin', markEditorActive);\n prevRootElement?.removeEventListener('mousedown', markEditorActive);\n prevRootElement?.removeEventListener('pointerdown', markEditorActive);\n rootElement?.addEventListener('focusin', markEditorActive);\n rootElement?.addEventListener('mousedown', markEditorActive);\n rootElement?.addEventListener('pointerdown', markEditorActive);\n });\n }, [editor, onFocus, pageId, region, setActiveEditor, setActivePageId]);\n\n useEffect(() => {\n return editor.registerCommand(\n FOCUS_COMMAND,\n () => {\n debug('focus', `editor focused (ns=${editor.getKey()})`);\n setActivePageId(pageId);\n setActiveEditor(editor, { pageId, region });\n onFocus?.(editor);\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, onFocus, pageId, region, setActiveEditor, setActivePageId]);\n\n return null;\n};\n","import {\n $getRoot,\n $isElementNode,\n $isTextNode,\n $getNearestNodeFromDOMNode,\n $splitNode,\n type LexicalNode,\n type SerializedLexicalNode,\n type ElementNode,\n} from 'lexical';\nimport { $isListNode } from '@lexical/list';\nimport { debug, debugWarn } from '../../utils/debug';\n\n/**\n * Result of finding a split point inside a block element.\n */\ninterface DomSplitPoint {\n /** The DOM Text node containing the split offset */\n textNode: Text;\n /** Character offset within the text node */\n offset: number;\n}\n\n/**\n * Finds the character position inside a block element where content\n * crosses the available height boundary.\n *\n * Uses a binary search with Range.getBoundingClientRect() for efficiency.\n * Returns the offset backed up to the nearest word boundary.\n *\n * @returns The DOM text node and offset, or null if no valid split found\n */\nexport function findMidBlockSplitPoint(\n blockElement: HTMLElement,\n availableHeight: number,\n): DomSplitPoint | null {\n const blockRect = blockElement.getBoundingClientRect();\n const maxBottom = blockRect.top + availableHeight;\n\n // Collect all text nodes in the block\n const textNodes: Text[] = [];\n const walker = document.createTreeWalker(blockElement, NodeFilter.SHOW_TEXT);\n let walkNode: Text | null;\n while ((walkNode = walker.nextNode() as Text | null)) {\n if (walkNode.length > 0) {\n textNodes.push(walkNode);\n }\n }\n\n if (textNodes.length === 0) return null;\n\n // Find the text node that contains the split boundary\n const range = document.createRange();\n\n for (const textNode of textNodes) {\n // Quick check: does this text node cross the boundary?\n range.selectNodeContents(textNode);\n const nodeRect = range.getBoundingClientRect();\n\n if (nodeRect.bottom <= maxBottom) {\n continue; // Entire text node fits\n }\n\n if (nodeRect.top >= maxBottom) {\n // This text node starts after the boundary — split at offset 0\n return backupToWordBoundary(textNode, 0);\n }\n\n // This text node crosses the boundary — binary search for exact offset\n let low = 0;\n let high = textNode.length;\n\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n range.setStart(textNode, 0);\n range.setEnd(textNode, mid + 1);\n const testRect = range.getBoundingClientRect();\n\n if (testRect.bottom > maxBottom) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // 'low' is the first character that doesn't fit\n return backupToWordBoundary(textNode, low);\n }\n\n return null;\n}\n\n/**\n * Backs up a split offset to the nearest word boundary (whitespace).\n * Ensures at least one character remains on each side.\n */\nfunction backupToWordBoundary(\n textNode: Text,\n offset: number,\n): DomSplitPoint | null {\n const text = textNode.textContent || '';\n if (offset <= 0 || offset >= text.length) {\n // Can't back up — split at the raw offset if valid\n if (offset > 0 && offset < text.length) {\n return { textNode, offset };\n }\n // offset is at an edge — try the raw value\n if (offset > 0) return { textNode, offset };\n return null;\n }\n\n // Scan backwards for whitespace\n let adjusted = offset;\n while (adjusted > 0 && !/\\s/.test(text[adjusted - 1])) {\n adjusted--;\n }\n\n // If backing up to 0 would leave nothing on this page, use original offset\n if (adjusted <= 0) {\n adjusted = offset;\n }\n\n return { textNode, offset: adjusted };\n}\n\n/**\n * Recursively serializes a Lexical node and all its children.\n */\nfunction serializeNodeTree(node: LexicalNode): SerializedLexicalNode {\n const json = node.exportJSON();\n if ($isElementNode(node)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (json as any).children = node.getChildren().map(serializeNodeTree);\n }\n return json;\n}\n\n/**\n * Finds the split point for a ListNode by checking which ListItem\n * crosses the height boundary.\n *\n * @returns The child index to split at, or -1 if no valid split\n */\nfunction findListSplitIndex(\n listElement: HTMLElement,\n availableHeight: number,\n): number {\n const listRect = listElement.getBoundingClientRect();\n const maxBottom = listRect.top + availableHeight;\n const children = Array.from(listElement.children) as HTMLElement[];\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const childRect = child.getBoundingClientRect();\n if (childRect.bottom > maxBottom && i > 0) {\n return i;\n }\n }\n\n return -1;\n}\n\n/**\n * Performs a mid-block split on the first overflowing block in the editor.\n *\n * Handles two cases:\n * 1. Paragraph/Heading: splits at a text offset using Range measurement\n * 2. List: splits at a ListItem boundary\n *\n * Must be called inside an editor.update() context.\n *\n * @returns Serialized overflow nodes, or null if split wasn't possible\n */\nexport function performMidBlockSplit(\n rootElement: HTMLElement,\n availableHeight: number,\n overflowBlockIndex: number,\n): SerializedLexicalNode[] | null {\n const root = $getRoot();\n const allChildren = root.getChildren();\n const blockNode = allChildren[overflowBlockIndex];\n\n if (!blockNode || !$isElementNode(blockNode)) {\n debugWarn('overflow', 'target node is not an ElementNode');\n return null;\n }\n\n const blockElements = Array.from(rootElement.children) as HTMLElement[];\n const blockElement = blockElements[overflowBlockIndex];\n if (!blockElement) {\n debugWarn('overflow', 'no DOM element for block index');\n return null;\n }\n\n // Compute available height for this specific block\n const blockTop = blockElement.offsetTop;\n const heightForBlock = availableHeight - blockTop;\n\n if (heightForBlock <= 0) {\n debugWarn('overflow', 'no space for block');\n return null;\n }\n\n // Try list splitting first\n if ($isListNode(blockNode)) {\n return splitListNode(blockNode as ElementNode, blockElement, heightForBlock);\n }\n\n // Paragraph/Heading splitting via text measurement\n return splitParagraphNode(blockNode as ElementNode, blockElement, heightForBlock);\n}\n\n/**\n * Splits a ListNode at a ListItem boundary.\n */\nfunction splitListNode(\n listNode: ElementNode,\n listElement: HTMLElement,\n availableHeight: number,\n): SerializedLexicalNode[] | null {\n const splitIndex = findListSplitIndex(listElement, availableHeight);\n if (splitIndex <= 0) {\n debug('overflow', 'cannot split list — first item exceeds height');\n return null;\n }\n\n const [, overflowList] = $splitNode(listNode, splitIndex);\n\n // Serialize the overflow list and all subsequent siblings\n const overflowNodes: SerializedLexicalNode[] = [];\n const toRemove: LexicalNode[] = [];\n\n overflowNodes.push(serializeNodeTree(overflowList));\n toRemove.push(overflowList);\n\n // Collect remaining siblings after the overflow list\n let nextSibling = overflowList.getNextSibling();\n while (nextSibling) {\n overflowNodes.push(serializeNodeTree(nextSibling));\n toRemove.push(nextSibling);\n nextSibling = nextSibling.getNextSibling();\n }\n\n for (const node of toRemove) {\n node.remove();\n }\n\n debug('overflow', `split list at item ${splitIndex}, extracted ${overflowNodes.length} overflow nodes`);\n return overflowNodes;\n}\n\n/**\n * Splits a paragraph or heading node at a text boundary.\n */\nfunction splitParagraphNode(\n blockNode: ElementNode,\n blockElement: HTMLElement,\n availableHeight: number,\n): SerializedLexicalNode[] | null {\n const splitPoint = findMidBlockSplitPoint(blockElement, availableHeight);\n if (!splitPoint) {\n debug('overflow', 'no valid split point found in paragraph');\n return null;\n }\n\n // Map DOM text node to Lexical TextNode\n const lexicalNode = $getNearestNodeFromDOMNode(splitPoint.textNode);\n if (!lexicalNode || !$isTextNode(lexicalNode)) {\n debugWarn('overflow', 'could not map DOM text node to Lexical TextNode');\n return null;\n }\n\n // Split the text node\n const [, afterText] = lexicalNode.splitText(splitPoint.offset);\n if (!afterText) {\n debugWarn('overflow', 'splitText returned no second half');\n return null;\n }\n\n // Find afterText's index in the parent\n const parent = afterText.getParent();\n if (!parent || !$isElementNode(parent)) {\n debugWarn('overflow', 'split text has no element parent');\n return null;\n }\n\n // Walk up from the text to find the direct child of blockNode\n let directChild: LexicalNode = afterText;\n let directChildParent = parent;\n\n while (directChildParent && directChildParent.getKey() !== blockNode.getKey()) {\n directChild = directChildParent;\n const next = directChildParent.getParent();\n if (!next || !$isElementNode(next)) {\n debugWarn('overflow', 'could not find block node in parent chain');\n return null;\n }\n directChildParent = next;\n }\n\n // Now directChild is the child of blockNode that contains (or is) afterText\n const splitChildIndex = blockNode.getChildren().indexOf(directChild);\n\n if (splitChildIndex <= 0) {\n debug('overflow', 'split index is 0 or not found — nothing to keep on this page');\n return null;\n }\n\n // If the direct child is not afterText itself, we need to split intermediate nodes\n if (directChild !== afterText) {\n // Split each level from the text's parent up to (but not including) blockNode\n let current: ElementNode = parent;\n let childToSplitAt: LexicalNode = afterText;\n\n while (current.getKey() !== blockNode.getKey()) {\n const childIdx = current.getChildren().indexOf(childToSplitAt);\n if (childIdx > 0) {\n $splitNode(current, childIdx);\n }\n childToSplitAt = current;\n const next = current.getParent();\n if (!next || !$isElementNode(next)) break;\n current = next;\n }\n }\n\n // Re-find the split index after potential intermediate splits\n // Find the child of blockNode that contains afterText\n let finalSplitChild: LexicalNode = afterText;\n let p = afterText.getParent();\n while (p && p.getKey() !== blockNode.getKey()) {\n finalSplitChild = p;\n p = p.getParent() as ElementNode | null;\n }\n const finalSplitIndex = blockNode.getChildren().indexOf(finalSplitChild);\n\n if (finalSplitIndex <= 0) {\n debug('overflow', 'final split index is 0 or not found — nothing to keep on this page');\n return null;\n }\n\n const [, overflowBlock] = $splitNode(blockNode, finalSplitIndex);\n\n // Serialize the overflow block and any subsequent nodes\n const overflowNodes: SerializedLexicalNode[] = [];\n const toRemove: LexicalNode[] = [];\n\n overflowNodes.push(serializeNodeTree(overflowBlock));\n toRemove.push(overflowBlock);\n\n // Collect remaining siblings after the split\n let nextSibling = overflowBlock.getNextSibling();\n while (nextSibling) {\n overflowNodes.push(serializeNodeTree(nextSibling));\n toRemove.push(nextSibling);\n nextSibling = nextSibling.getNextSibling();\n }\n\n for (const node of toRemove) {\n node.remove();\n }\n\n debug(\n 'overflow',\n `split paragraph at offset ${splitPoint.offset}, extracted ${overflowNodes.length} overflow nodes`,\n );\n return overflowNodes;\n}\n","import { useEffect, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getRoot,\n $isElementNode,\n type LexicalNode,\n type SerializedEditorState,\n type SerializedLexicalNode,\n} from 'lexical';\nimport { debug, debugWarn } from '../../utils/debug';\nimport { performMidBlockSplit } from '../utils/mid-block-split';\n\n/**\n * Recursively serializes a Lexical node and all its children.\n * ElementNode.exportJSON() returns children: [] by default —\n * the recursive walk must be done manually.\n */\nfunction serializeNodeTree(node: LexicalNode): SerializedLexicalNode {\n const json = node.exportJSON();\n if ($isElementNode(node)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (json as any).children = node.getChildren().map(serializeNodeTree);\n }\n return json;\n}\n\ninterface OverflowPluginProps {\n /** Called with the serialized overflow content that must go to the next page */\n onOverflow: (\n overflowContent: SerializedEditorState,\n cause: 'paste' | 'content',\n ) => void;\n}\n\n/** Debounce delay for typing-triggered overflow checks (ms) */\nconst OVERFLOW_DEBOUNCE_MS = 300;\n\n/**\n * OverflowPlugin — Detects content overflow inside a Lexical editor\n * and automatically extracts overflow nodes.\n *\n * Uses registerRootListener to reliably get the root element (handles\n * the case where the root is not yet available on first render).\n *\n * Measures child element positions via getBoundingClientRect() relative\n * to the container, which works regardless of CSS overflow settings.\n *\n * Debounces overflow checks during normal typing (300ms) to avoid\n * extracting only the empty trailing paragraph. Paste and external\n * state changes (e.g. setEditorState) trigger immediate checks.\n */\nexport const OverflowPlugin: React.FC<OverflowPluginProps> = ({\n onOverflow,\n}) => {\n const [editor] = useLexicalComposerContext();\n const processingRef = useRef(false);\n const onOverflowRef = useRef(onOverflow);\n onOverflowRef.current = onOverflow;\n\n useEffect(() => {\n let observer: ResizeObserver | null = null;\n let unregisterUpdateListener: (() => void) | null = null;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const checkOverflow = (\n rootElement: HTMLElement,\n container: HTMLElement,\n cause: 'paste' | 'content',\n ) => {\n if (processingRef.current) return;\n\n const availableHeight = container.clientHeight;\n if (availableHeight <= 0) return;\n\n // Use scrollHeight for reliable overflow detection — unaffected by\n // scroll position (getBoundingClientRect is affected when the browser\n // scrolls overflow:hidden containers to follow the cursor after paste).\n const contentHeight = rootElement.scrollHeight;\n\n // No overflow if all content fits (+2px tolerance for sub-pixel rounding)\n if (contentHeight <= availableHeight + 2) return;\n\n const children = Array.from(rootElement.children) as HTMLElement[];\n if (children.length === 0) return;\n\n if (children.length <= 1) {\n debug('overflow', `single block overflows (content=${contentHeight}px > available=${availableHeight}px) — attempting mid-block split`);\n\n processingRef.current = true;\n\n editor.update(\n () => {\n const overflowNodes = performMidBlockSplit(rootElement, availableHeight, 0);\n if (!overflowNodes || overflowNodes.length === 0) {\n debug('overflow', 'mid-block split not possible for single block');\n processingRef.current = false;\n return;\n }\n\n const overflowState: SerializedEditorState = {\n root: {\n children: overflowNodes,\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState;\n\n debug('overflow', `mid-block split extracted ${overflowNodes.length} overflow nodes from single block`);\n\n setTimeout(() => {\n onOverflowRef.current(overflowState, cause);\n processingRef.current = false;\n }, 0);\n },\n { tag: 'overflow-split' },\n );\n return;\n }\n\n processingRef.current = true;\n\n debug('overflow', `OVERFLOW detected: content=${contentHeight}px available=${availableHeight}px children=${children.length}`);\n\n // Find the first child whose bottom exceeds the available height.\n // Uses offsetTop (relative to offsetParent, unaffected by scroll)\n // instead of getBoundingClientRect (which shifts with scroll).\n let splitIndex = children.length;\n let firstBlockOverflows = false;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const childBottom = child.offsetTop + child.offsetHeight;\n\n if (childBottom > availableHeight) {\n if (i === 0) {\n // First block itself overflows — attempt mid-block split on it,\n // then fall through to extract remaining blocks after it\n firstBlockOverflows = true;\n splitIndex = 1; // everything after block 0 overflows\n } else {\n splitIndex = i;\n }\n debug('overflow', `split at index ${i === 0 ? '0 (mid-block)' : i} (childBottom=${childBottom}px > ${availableHeight}px)`);\n break;\n }\n }\n\n if (splitIndex >= children.length) {\n debugWarn('overflow', 'no valid split point found — all children fit individually');\n processingRef.current = false;\n return;\n }\n\n editor.update(\n () => {\n const root = $getRoot();\n const allChildren = root.getChildren();\n\n if (splitIndex >= allChildren.length) {\n debugWarn('overflow', `splitIndex=${splitIndex} >= Lexical children=${allChildren.length} — mismatch`);\n processingRef.current = false;\n return;\n }\n\n let overflowNodes: SerializedLexicalNode[] = [];\n\n // If the first block itself overflows, try mid-block split on it\n if (firstBlockOverflows) {\n const midBlockOverflow = performMidBlockSplit(rootElement, availableHeight, 0);\n if (midBlockOverflow && midBlockOverflow.length > 0) {\n overflowNodes.push(...midBlockOverflow);\n debug('overflow', `mid-block split on first block extracted ${midBlockOverflow.length} nodes`);\n } else {\n debug('overflow', 'mid-block split failed on first block — keeping it whole');\n }\n\n // Serialize and remove remaining blocks after the first\n const freshChildren = root.getChildren();\n const toRemove = freshChildren.slice(1);\n for (const node of toRemove) {\n overflowNodes.push(serializeNodeTree(node));\n }\n for (const node of toRemove) {\n node.remove();\n }\n } else {\n const toRemove = allChildren.slice(splitIndex);\n for (const node of toRemove) {\n overflowNodes.push(serializeNodeTree(node));\n }\n for (const node of toRemove) {\n node.remove();\n }\n }\n\n if (overflowNodes.length === 0) {\n processingRef.current = false;\n return;\n }\n\n debug('overflow', `extracted ${overflowNodes.length} overflow nodes total`);\n\n const overflowState: SerializedEditorState = {\n root: {\n children: overflowNodes,\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState;\n\n setTimeout(() => {\n onOverflowRef.current(overflowState, cause);\n processingRef.current = false;\n }, 0);\n },\n { tag: 'overflow-split' },\n );\n };\n\n const setupObservers = (rootElement: HTMLElement) => {\n // Clean up any previous observers\n if (observer) observer.disconnect();\n if (unregisterUpdateListener) unregisterUpdateListener();\n if (debounceTimer) clearTimeout(debounceTimer);\n\n const container = rootElement.closest('.lex4-page-body') as HTMLElement | null;\n if (!container) {\n debugWarn('overflow', 'no .lex4-page-body container found');\n return;\n }\n\n debug('overflow', `observers attached (ns=${editor.getKey()})`);\n\n const immediateCheck = () => {\n requestAnimationFrame(() => checkOverflow(rootElement, container, 'content'));\n };\n\n const pasteCheck = () => {\n requestAnimationFrame(() => checkOverflow(rootElement, container, 'paste'));\n };\n\n const debouncedCheck = () => {\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(immediateCheck, OVERFLOW_DEBOUNCE_MS);\n };\n\n // ResizeObserver fires on actual layout changes — debounce to\n // avoid constant checks during typing\n observer = new ResizeObserver(debouncedCheck);\n observer.observe(rootElement);\n observer.observe(container);\n\n unregisterUpdateListener = editor.registerUpdateListener(({ tags }) => {\n if (tags.has('overflow-split')) return;\n\n // Paste and external state changes trigger immediate overflow check.\n // Normal typing is debounced to avoid extracting only the cursor paragraph.\n if (tags.has('paste')) {\n debug('overflow', `paste check (tags=${Array.from(tags).join(',')})`);\n pasteCheck();\n } else if (tags.has('collaboration') || tags.has('historic')) {\n debug('overflow', `immediate check (tags=${Array.from(tags).join(',')})`);\n immediateCheck();\n } else {\n debouncedCheck();\n }\n });\n\n // Initial check after setup (immediate — handles mount with initial content)\n immediateCheck();\n };\n\n // registerRootListener fires immediately with current root (if any)\n // and again whenever the root element changes — handles the case\n // where getRootElement() returns null on first render\n const unregisterRootListener = editor.registerRootListener(\n (rootElement: HTMLElement | null) => {\n if (rootElement) {\n debug('overflow', `rootListener: root available (ns=${editor.getKey()})`);\n setupObservers(rootElement);\n } else {\n debug('overflow', `rootListener: root detached (ns=${editor.getKey()})`);\n if (observer) observer.disconnect();\n if (unregisterUpdateListener) unregisterUpdateListener();\n if (debounceTimer) clearTimeout(debounceTimer);\n observer = null;\n unregisterUpdateListener = null;\n debounceTimer = null;\n }\n },\n );\n\n return () => {\n unregisterRootListener();\n if (observer) observer.disconnect();\n if (unregisterUpdateListener) unregisterUpdateListener();\n if (debounceTimer) clearTimeout(debounceTimer);\n };\n }, [editor]);\n\n return null;\n};\n","import { useEffect, useMemo } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n COMMAND_PRIORITY_LOW,\n CONTROLLED_TEXT_INSERTION_COMMAND,\n FORMAT_ELEMENT_COMMAND,\n FORMAT_TEXT_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_DOWN_COMMAND,\n KEY_ENTER_COMMAND,\n PASTE_COMMAND,\n} from 'lexical';\n\nimport { useDocument } from '../../context/document-context';\nimport { useTranslations, interpolate } from '../../i18n';\nimport type { HistoryActionDescriptor, HistoryRegion } from '../../types/history';\n\ninterface HistoryCapturePluginProps {\n pageId: string;\n region: Exclude<HistoryRegion, 'document'>;\n}\n\nexport const HistoryCapturePlugin: React.FC<HistoryCapturePluginProps> = ({ pageId, region }) => {\n const [editor] = useLexicalComposerContext();\n const { document, queueHistoryAction } = useDocument();\n const t = useTranslations();\n\n const context = useMemo(() => {\n const pageNumber = document.pages.findIndex(page => page.id === pageId);\n return {\n pageNumber: pageNumber >= 0 ? pageNumber + 1 : null,\n source: region,\n };\n }, [document.pages, pageId, region]);\n\n const createPageLabel = useMemo(() => {\n return (r: HistoryCapturePluginProps['region'], pageNumber: number | null): string => {\n if (r === 'body') {\n return pageNumber ? interpolate(t.regions.page, { page: pageNumber }) : t.regions.body;\n }\n const regionLabel = r === 'header' ? t.regions.header : t.regions.footer;\n return pageNumber\n ? `${regionLabel} ${interpolate(t.regions.page, { page: pageNumber })}`\n : regionLabel;\n };\n }, [t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n CONTROLLED_TEXT_INSERTION_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.typedText));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (event.metaKey || event.ctrlKey || event.altKey) {\n return false;\n }\n\n if (event.key.length !== 1) {\n return false;\n }\n\n queueHistoryAction(buildDescriptor(t.historyLabels.typedText));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n const text = event.clipboardData?.getData('text/plain') ?? '';\n if (text.trim().length === 0) {\n return false;\n }\n queueHistoryAction(buildDescriptor(t.historyLabels.pastedContent));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.insertedLineBreak));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.deletedBackward));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n KEY_DELETE_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.deletedForward));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n FORMAT_TEXT_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.formattedText));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n useEffect(() => {\n const buildDescriptor = (label: string): HistoryActionDescriptor => ({\n label: `${label} - ${createPageLabel(region, context.pageNumber)}`,\n source: context.source,\n pageId,\n region,\n });\n\n return editor.registerCommand(\n FORMAT_ELEMENT_COMMAND,\n () => {\n queueHistoryAction(buildDescriptor(t.historyLabels.formattedParagraph));\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [context.pageNumber, context.source, createPageLabel, editor, pageId, queueHistoryAction, region, t]);\n\n return null;\n};\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n COMMAND_PRIORITY_HIGH,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_DOWN_COMMAND,\n} from 'lexical';\n\ninterface PageBoundaryPluginProps {\n onBackspaceAtStart: () => void;\n onDeleteAtEnd: () => void;\n onMoveToPreviousPage: () => void;\n onMoveToNextPage: () => void;\n}\n\ninterface CollapsedTextPosition {\n textOffset: number;\n totalTextLength: number;\n}\n\nfunction getCollapsedTextPosition(rootElement: HTMLElement | null): CollapsedTextPosition | null {\n const domSelection = window.getSelection();\n if (!rootElement || !domSelection || domSelection.rangeCount === 0 || !domSelection.isCollapsed) {\n return null;\n }\n\n const range = domSelection.getRangeAt(0);\n if (!rootElement.contains(range.startContainer)) {\n return null;\n }\n\n const offsetRange = document.createRange();\n offsetRange.setStart(rootElement, 0);\n offsetRange.setEnd(range.startContainer, range.startOffset);\n\n const contentRange = document.createRange();\n contentRange.selectNodeContents(rootElement);\n\n return {\n textOffset: offsetRange.toString().length,\n totalTextLength: contentRange.toString().length,\n };\n}\n\nexport const PageBoundaryPlugin: React.FC<PageBoundaryPluginProps> = ({\n onBackspaceAtStart,\n onDeleteAtEnd,\n onMoveToPreviousPage,\n onMoveToNextPage,\n}) => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n () => {\n const position = getCollapsedTextPosition(editor.getRootElement());\n if (!position || position.textOffset !== 0) {\n return false;\n }\n\n onBackspaceAtStart();\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n ), [editor, onBackspaceAtStart]);\n\n useEffect(() => editor.registerCommand(\n KEY_DELETE_COMMAND,\n () => {\n const position = getCollapsedTextPosition(editor.getRootElement());\n if (!position || position.textOffset !== position.totalTextLength) {\n return false;\n }\n\n onDeleteAtEnd();\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n ), [editor, onDeleteAtEnd]);\n\n useEffect(() => editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {\n return false;\n }\n\n const position = getCollapsedTextPosition(editor.getRootElement());\n if (!position) {\n return false;\n }\n\n if ((event.key === 'ArrowLeft' || event.key === 'ArrowUp') && position.textOffset === 0) {\n event.preventDefault();\n onMoveToPreviousPage();\n return true;\n }\n\n if (\n (event.key === 'ArrowRight' || event.key === 'ArrowDown')\n && position.textOffset === position.totalTextLength\n ) {\n event.preventDefault();\n onMoveToNextPage();\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_HIGH,\n ), [editor, onMoveToNextPage, onMoveToPreviousPage]);\n\n return null;\n};\n","import React, { useCallback, useEffect, useMemo } from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { ListPlugin } from '@lexical/react/LexicalListPlugin';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport type { EditorState, SerializedEditorState } from 'lexical';\n\nimport { createEditorConfig } from '../lexical/editor-setup';\nimport { TabIndentPlugin } from '../lexical/plugins/tab-indent-plugin';\nimport { ParagraphIndentPlugin } from '../lexical/plugins/paragraph-indent-plugin';\nimport { PastePlugin } from '../lexical/plugins/paste-plugin';\nimport { ActiveEditorPlugin } from '../lexical/plugins/active-editor-plugin';\nimport { OverflowPlugin } from '../lexical/plugins/overflow-plugin';\nimport { HistoryCapturePlugin } from '../lexical/plugins/history-capture-plugin';\nimport { PageBoundaryPlugin } from '../lexical/plugins/page-boundary-plugin';\nimport { useDocument } from '../context/document-context';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations } from '../i18n';\nimport { debug, shortId } from '../utils/debug';\n\ninterface PageBodyProps {\n pageId: string;\n initialBodyState?: SerializedEditorState | null;\n onBodyChange?: (state: SerializedEditorState) => void;\n onOverflow?: (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => void;\n onFocus?: () => void;\n onBackspaceAtStart?: () => void;\n onDeleteAtEnd?: () => void;\n onMoveToPreviousPage?: () => void;\n onMoveToNextPage?: () => void;\n readOnly?: boolean;\n}\n\n/**\n * EditorRegistryPlugin — Registers the editor in the document-level\n * editor registry so other pages can directly push content into it.\n */\nconst EditorRegistryPlugin: React.FC<{ pageId: string }> = ({ pageId }) => {\n const [editor] = useLexicalComposerContext();\n const { editorRegistry } = useDocument();\n\n useEffect(() => {\n editorRegistry.register(pageId, editor);\n debug('registry', `registered editor for page ${shortId(pageId)}`);\n return () => {\n editorRegistry.unregister(pageId, editor);\n debug('registry', `unregistered editor for page ${shortId(pageId)}`);\n };\n }, [editor, pageId, editorRegistry]);\n\n return null;\n};\n\n/**\n * PageBody — Lexical editor instance for one page's body content.\n *\n * Each page gets its own Lexical editor. The OverflowPlugin\n * handles splitting content when it exceeds the available height.\n *\n * Extension-contributed body plugins are rendered inside the LexicalComposer.\n */\nexport const PageBody: React.FC<PageBodyProps> = ({\n pageId,\n initialBodyState,\n onBodyChange,\n onOverflow,\n onFocus,\n onBackspaceAtStart,\n onDeleteAtEnd,\n onMoveToPreviousPage,\n onMoveToNextPage,\n readOnly = false,\n}) => {\n const { nodes, bodyPlugins, themeOverrides } = useExtensions();\n const t = useTranslations();\n\n const config = useMemo(\n () => {\n const baseConfig = {\n ...createEditorConfig('body', pageId, nodes, themeOverrides),\n editable: !readOnly,\n };\n\n if (initialBodyState) {\n debug('page', `PageBody ${shortId(pageId)}: initializing with ${initialBodyState.root?.children?.length ?? 0} children`);\n return {\n ...baseConfig,\n editorState: JSON.stringify(initialBodyState),\n };\n }\n\n debug('page', `PageBody ${shortId(pageId)}: initializing empty`);\n return baseConfig;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally only use initialBodyState at mount time\n [pageId, readOnly, nodes, themeOverrides],\n );\n\n const handleChange = useCallback(\n (editorState: EditorState) => {\n const serialized = editorState.toJSON();\n onBodyChange?.(serialized);\n },\n [onBodyChange],\n );\n\n const handleOverflow = useCallback(\n (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => {\n debug('page', `PageBody ${shortId(pageId)}: overflow callback fired with ${overflowContent.root?.children?.length ?? 0} children`);\n onOverflow?.(overflowContent, cause);\n },\n [onOverflow, pageId],\n );\n\n return (\n <div\n className=\"lex4-page-body\"\n data-testid={`page-body-${pageId}`}\n onFocus={onFocus}\n >\n <LexicalComposer initialConfig={config}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n className=\"lex4-page-body-editable\"\n />\n }\n placeholder={\n <div className=\"lex4-page-placeholder\">\n {t.body.placeholder}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <ListPlugin />\n <ParagraphIndentPlugin />\n <TabIndentPlugin />\n <PastePlugin />\n <EditorRegistryPlugin pageId={pageId} />\n <ActiveEditorPlugin pageId={pageId} region=\"body\" />\n {!readOnly && <HistoryCapturePlugin pageId={pageId} region=\"body\" />}\n {!readOnly && onBackspaceAtStart && onDeleteAtEnd && onMoveToPreviousPage && onMoveToNextPage && (\n <PageBoundaryPlugin\n onBackspaceAtStart={onBackspaceAtStart}\n onDeleteAtEnd={onDeleteAtEnd}\n onMoveToPreviousPage={onMoveToPreviousPage}\n onMoveToNextPage={onMoveToNextPage}\n />\n )}\n <OverflowPlugin onOverflow={handleOverflow} />\n {bodyPlugins.map((Plugin, idx) => (\n <Plugin key={idx} />\n ))}\n <OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n </LexicalComposer>\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_CRITICAL, KEY_ENTER_COMMAND, PASTE_COMMAND } from 'lexical';\nimport { debug } from '../../utils/debug';\n\n/**\n * HeightLimitPlugin — Prevents editing that would push content beyond\n * a maximum height. Instead of clipping overflow, this plugin reverts\n * any change that makes the editor's scrollHeight exceed maxHeight.\n *\n * Works by:\n * 1. Blocking Enter key when already at max height\n * 2. Saving editor state before each update, reverting if scrollHeight exceeds limit\n * 3. Truncating paste content that would overflow\n */\nexport function HeightLimitPlugin({ maxHeight, channel }: { maxHeight: number; channel: 'header' | 'footer' }) {\n const [editor] = useLexicalComposerContext();\n const lastGoodStateRef = useRef<string | null>(null);\n const isRevertingRef = useRef(false);\n\n useEffect(() => {\n // Save initial state as \"last good\"\n lastGoodStateRef.current = JSON.stringify(editor.getEditorState().toJSON());\n\n // Intercept Enter key when at max height\n const removeEnterCommand = editor.registerCommand(\n KEY_ENTER_COMMAND,\n () => {\n const root = editor.getRootElement();\n if (root && root.scrollHeight >= maxHeight) {\n debug(channel, `blocked Enter — scrollHeight ${root.scrollHeight}px >= max ${maxHeight}px`);\n return true; // Prevent the Enter\n }\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n // Intercept paste when at max height\n const removePasteCommand = editor.registerCommand(\n PASTE_COMMAND,\n () => {\n const root = editor.getRootElement();\n if (root && root.scrollHeight >= maxHeight) {\n debug(channel, `blocked paste — scrollHeight ${root.scrollHeight}px >= max ${maxHeight}px`);\n return true; // Prevent the paste\n }\n return false;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n // After each update, check if content exceeds max height and revert if so\n const removeUpdateListener = editor.registerUpdateListener(({ editorState, prevEditorState }) => {\n if (isRevertingRef.current) return;\n\n const root = editor.getRootElement();\n if (!root) return;\n\n // Use requestAnimationFrame to read DOM after paint\n requestAnimationFrame(() => {\n if (root.scrollHeight > maxHeight) {\n debug(channel, `reverting — scrollHeight ${root.scrollHeight}px > max ${maxHeight}px`);\n const restoreState =\n JSON.stringify(prevEditorState.toJSON()) || lastGoodStateRef.current;\n if (!restoreState) {\n return;\n }\n isRevertingRef.current = true;\n\n editor.setEditorState(editor.parseEditorState(restoreState));\n\n isRevertingRef.current = false;\n } else {\n // Content fits — save as last good state\n lastGoodStateRef.current = JSON.stringify(editorState.toJSON());\n }\n });\n });\n\n return () => {\n removeEnterCommand();\n removePasteCommand();\n removeUpdateListener();\n };\n }, [editor, maxHeight, channel]);\n\n return null;\n}\n","import React, { useCallback, useMemo, useRef } from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';\nimport type { EditorState, SerializedEditorState } from 'lexical';\n\nimport { createEditorConfig } from '../lexical/editor-setup';\nimport { MAX_HEADER_HEIGHT_PX } from '../constants/dimensions';\nimport { ActiveEditorPlugin } from '../lexical/plugins/active-editor-plugin';\nimport { HeightLimitPlugin } from '../lexical/plugins/height-limit-plugin';\nimport { HistoryCapturePlugin } from '../lexical/plugins/history-capture-plugin';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations } from '../i18n';\nimport { debug, shortId } from '../utils/debug';\n\ninterface PageHeaderProps {\n pageId: string;\n initialHeaderState?: SerializedEditorState | null;\n pageCounterLabel?: string;\n onHeaderChange?: (state: SerializedEditorState, height: number) => void;\n}\n\n/**\n * PageHeader — Mini Lexical editor for a page's header region.\n *\n * Constrained to MAX_HEADER_HEIGHT_PX. Uses overflow: clip to prevent\n * the browser from scrolling the container to follow the cursor.\n * Remounts via key={syncVersion} when content is copied/cleared externally.\n */\nexport const PageHeader: React.FC<PageHeaderProps> = ({\n pageId,\n initialHeaderState,\n pageCounterLabel,\n onHeaderChange,\n}) => {\n const hasPageCounter = !!pageCounterLabel;\n const { nodes, themeOverrides } = useExtensions();\n const t = useTranslations();\n const config = useMemo(\n () => {\n const baseConfig = createEditorConfig('header', pageId, nodes, themeOverrides);\n if (initialHeaderState) {\n return { ...baseConfig, editorState: JSON.stringify(initialHeaderState) };\n }\n return baseConfig;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- syncVersion forces remount via key, only used at init\n [pageId, nodes, themeOverrides],\n );\n\n const contentRef = useRef<HTMLDivElement>(null);\n\n const handleChange = useCallback(\n (editorState: EditorState) => {\n requestAnimationFrame(() => {\n const el = contentRef.current;\n if (el) {\n if (el.scrollHeight > MAX_HEADER_HEIGHT_PX) {\n debug(\n 'header',\n `page ${shortId(pageId)}: skipped external sync at ${el.scrollHeight}px > max ${MAX_HEADER_HEIGHT_PX}px`,\n );\n return;\n }\n const height = Math.min(el.scrollHeight, MAX_HEADER_HEIGHT_PX);\n debug('header', `page ${shortId(pageId)}: height=${height}px (scrollH=${el.scrollHeight})`);\n onHeaderChange?.(editorState.toJSON(), height);\n }\n });\n },\n [onHeaderChange, pageId],\n );\n\n return (\n <div\n className=\"lex4-page-header\"\n style={{ maxHeight: MAX_HEADER_HEIGHT_PX, overflow: 'clip' }}\n data-testid={`page-header-${pageId}`}\n >\n <LexicalComposer initialConfig={config}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n ref={contentRef}\n className={`lex4-page-hf-editable${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}\n />\n }\n placeholder={\n <div className={`lex4-page-hf-placeholder${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}>\n {t.header.placeholder}</div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <ActiveEditorPlugin pageId={pageId} region=\"header\" />\n <HistoryCapturePlugin pageId={pageId} region=\"header\" />\n <HeightLimitPlugin maxHeight={MAX_HEADER_HEIGHT_PX} channel=\"header\" />\n <OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n </LexicalComposer>\n {pageCounterLabel && (\n <div\n className=\"lex4-page-counter\"\n data-testid={`page-counter-header-${pageId}`}\n >\n {pageCounterLabel}\n </div>\n )}\n </div>\n );\n};","import React, { useCallback, useMemo, useRef } from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';\nimport type { EditorState, SerializedEditorState } from 'lexical';\n\nimport { createEditorConfig } from '../lexical/editor-setup';\nimport { MAX_FOOTER_HEIGHT_PX } from '../constants/dimensions';\nimport { ActiveEditorPlugin } from '../lexical/plugins/active-editor-plugin';\nimport { HeightLimitPlugin } from '../lexical/plugins/height-limit-plugin';\nimport { HistoryCapturePlugin } from '../lexical/plugins/history-capture-plugin';\nimport { useExtensions } from '../extensions/extension-context';\nimport { useTranslations } from '../i18n';\nimport { debug, shortId } from '../utils/debug';\n\ninterface PageFooterProps {\n pageId: string;\n initialFooterState?: SerializedEditorState | null;\n pageCounterLabel?: string;\n onFooterChange?: (state: SerializedEditorState, height: number) => void;\n}\n\n/**\n * PageFooter — Mini Lexical editor for a page's footer region.\n *\n * Constrained to MAX_FOOTER_HEIGHT_PX. Uses overflow: clip to prevent\n * the browser from scrolling the container to follow the cursor.\n * Remounts via key={syncVersion} when content is copied/cleared externally.\n */\nexport const PageFooter: React.FC<PageFooterProps> = ({\n pageId,\n initialFooterState,\n pageCounterLabel,\n onFooterChange,\n}) => {\n const hasPageCounter = !!pageCounterLabel;\n const { nodes, themeOverrides } = useExtensions();\n const t = useTranslations();\n const config = useMemo(\n () => {\n const baseConfig = createEditorConfig('footer', pageId, nodes, themeOverrides);\n if (initialFooterState) {\n return { ...baseConfig, editorState: JSON.stringify(initialFooterState) };\n }\n return baseConfig;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- syncVersion forces remount via key, only used at init\n [pageId, nodes, themeOverrides],\n );\n\n const contentRef = useRef<HTMLDivElement>(null);\n\n const handleChange = useCallback(\n (editorState: EditorState) => {\n requestAnimationFrame(() => {\n const el = contentRef.current;\n if (el) {\n if (el.scrollHeight > MAX_FOOTER_HEIGHT_PX) {\n debug(\n 'footer',\n `page ${shortId(pageId)}: skipped external sync at ${el.scrollHeight}px > max ${MAX_FOOTER_HEIGHT_PX}px`,\n );\n return;\n }\n const height = Math.min(el.scrollHeight, MAX_FOOTER_HEIGHT_PX);\n debug('footer', `page ${shortId(pageId)}: height=${height}px (scrollH=${el.scrollHeight})`);\n onFooterChange?.(editorState.toJSON(), height);\n }\n });\n },\n [onFooterChange, pageId],\n );\n\n return (\n <div\n className=\"lex4-page-footer\"\n style={{ maxHeight: MAX_FOOTER_HEIGHT_PX, overflow: 'clip' }}\n data-testid={`page-footer-${pageId}`}\n >\n <LexicalComposer initialConfig={config}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n ref={contentRef}\n className={`lex4-page-hf-editable${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}\n />\n }\n placeholder={\n <div className={`lex4-page-hf-placeholder${hasPageCounter ? ' lex4-page-hf-narrow' : ''}`}>\n {t.footer.placeholder}</div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <ActiveEditorPlugin pageId={pageId} region=\"footer\" />\n <HistoryCapturePlugin pageId={pageId} region=\"footer\" />\n <HeightLimitPlugin maxHeight={MAX_FOOTER_HEIGHT_PX} channel=\"footer\" />\n <OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n </LexicalComposer>\n {pageCounterLabel && (\n <div\n className=\"lex4-page-counter\"\n data-testid={`page-counter-footer-${pageId}`}\n >\n {pageCounterLabel}\n </div>\n )}\n </div>\n );\n};","import React, { useCallback } from 'react';\nimport { A4_WIDTH_PX, A4_HEIGHT_PX, PAGE_MARGIN_TOP_PX, PAGE_MARGIN_BOTTOM_PX, PAGE_MARGIN_LEFT_PX, PAGE_MARGIN_RIGHT_PX } from '../constants/dimensions';\nimport { useDocument } from '../context/document-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { PageBody } from './PageBody';\nimport { PageHeader } from './PageHeader';\nimport { PageFooter } from './PageFooter';\nimport type { SerializedEditorState } from 'lexical';\n\ninterface PageViewProps {\n pageId: string;\n pageIndex: number;\n onOverflow?: (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => void;\n onBackspaceAtStart?: (pageIndex: number, pageId: string) => void;\n onDeleteAtEnd?: (pageIndex: number, pageId: string) => void;\n onMoveToPreviousPage?: (pageIndex: number) => void;\n onMoveToNextPage?: (pageIndex: number) => void;\n}\n\n/**\n * PageView — A single A4 page with header, body, and footer regions.\n *\n * Dimensions are always exactly A4 (794 × 1123 px).\n * Header and footer are only rendered when the global toggle is on.\n * Uses CSS flexbox: header/footer are flex-shrink-0, body is flex-1.\n */\nexport const PageView: React.FC<PageViewProps> = React.memo(({\n pageId,\n pageIndex,\n onOverflow,\n onBackspaceAtStart,\n onDeleteAtEnd,\n onMoveToPreviousPage,\n onMoveToNextPage,\n}) => {\n const { document, dispatch, editorRegistry, setActiveEditor, setActivePageId } = useDocument();\n const t = useTranslations();\n const page = document.pages.find(p => p.id === pageId);\n const showHeaderFooter = document.headerFooterEnabled;\n const pageCounterMode = document.pageCounterMode;\n const pageCounterLabel = interpolate(t.pageCounter.format, {\n current: pageIndex + 1,\n total: document.pages.length,\n });\n\n if (!page) return null;\n\n const handleBodyChange = useCallback(\n (bodyState: SerializedEditorState) => {\n dispatch({ type: 'UPDATE_PAGE_BODY', pageId, bodyState });\n },\n [dispatch, pageId],\n );\n\n const handleHeaderChange = useCallback(\n (headerState: SerializedEditorState, height: number) => {\n dispatch({ type: 'UPDATE_PAGE_HEADER_CONTENT', pageId, headerState, height });\n },\n [dispatch, pageId],\n );\n\n const handleFooterChange = useCallback(\n (footerState: SerializedEditorState, height: number) => {\n dispatch({ type: 'UPDATE_PAGE_FOOTER_CONTENT', pageId, footerState, height });\n },\n [dispatch, pageId],\n );\n\n const handleFocus = useCallback(() => {\n setActivePageId(pageId);\n const editor = editorRegistry.get(pageId);\n if (editor) {\n setActiveEditor(editor, { pageId, region: 'body' });\n }\n }, [editorRegistry, pageId, setActiveEditor, setActivePageId]);\n\n const handleOverflow = useCallback(\n (overflowContent: SerializedEditorState, cause: 'paste' | 'content') => {\n onOverflow?.(overflowContent, cause);\n },\n [onOverflow],\n );\n\n return (\n <div\n className=\"lex4-page\"\n style={{\n width: A4_WIDTH_PX,\n height: A4_HEIGHT_PX,\n paddingTop: PAGE_MARGIN_TOP_PX,\n paddingBottom: PAGE_MARGIN_BOTTOM_PX,\n paddingLeft: PAGE_MARGIN_LEFT_PX,\n paddingRight: PAGE_MARGIN_RIGHT_PX,\n }}\n data-testid={`page-${pageIndex}`}\n data-page-id={pageId}\n >\n {showHeaderFooter && (\n <PageHeader\n key={`header-${page.headerSyncVersion}`}\n pageId={pageId}\n initialHeaderState={page.headerState}\n pageCounterLabel={pageCounterMode === 'header' || pageCounterMode === 'both' ? pageCounterLabel : undefined}\n onHeaderChange={handleHeaderChange}\n />\n )}\n\n <PageBody\n key={`body-${page.bodySyncVersion}`}\n pageId={pageId}\n initialBodyState={page.bodyState}\n onBodyChange={handleBodyChange}\n onOverflow={handleOverflow}\n onFocus={handleFocus}\n onBackspaceAtStart={() => onBackspaceAtStart?.(pageIndex, pageId)}\n onDeleteAtEnd={() => onDeleteAtEnd?.(pageIndex, pageId)}\n onMoveToPreviousPage={() => onMoveToPreviousPage?.(pageIndex)}\n onMoveToNextPage={() => onMoveToNextPage?.(pageIndex)}\n />\n\n {showHeaderFooter && (\n <PageFooter\n key={`footer-${page.footerSyncVersion}`}\n pageId={pageId}\n initialFooterState={page.footerState}\n pageCounterLabel={pageCounterMode === 'footer' || pageCounterMode === 'both' ? pageCounterLabel : undefined}\n onFooterChange={handleFooterChange}\n />\n )}\n </div>\n );\n});\n\nPageView.displayName = 'PageView';\n","import React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { $getRoot } from 'lexical';\nimport type { SerializedEditorState, LexicalEditor } from 'lexical';\n\nimport { useDocument } from '../context/document-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { computeBodyHeight } from '../constants/page-layout';\nimport { usePagination } from '../hooks/use-pagination';\nimport { PageView } from './PageView';\nimport { createPageFromTemplate } from '../types/document';\nimport { debug, shortId } from '../utils/debug';\n\n/**\n * DocumentView — Scrollable container rendering all pages vertically.\n *\n * Provides the page-layout visual with pages centered on a gray background\n * with gaps between pages. Handles overflow content from pages by\n * creating new pages or prepending to existing next pages.\n */\nexport const DocumentView: React.FC = () => {\n const {\n document,\n dispatch,\n editorRegistry,\n requestFocusAtEnd,\n runHistoryAction,\n setActiveEditor,\n setActivePageId,\n } = useDocument();\n const t = useTranslations();\n const { handlePageUnderflow, reflowAll } = usePagination(document, dispatch);\n const previousBodyHeightsRef = useRef<number[] | null>(null);\n const pasteOverflowSequenceRef = useRef(false);\n const pasteOverflowReleaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const defaultPageTemplate = useMemo(\n () => ({\n headerState: document.defaultHeaderState,\n footerState: document.defaultFooterState,\n headerHeight: document.defaultHeaderHeight,\n footerHeight: document.defaultFooterHeight,\n }),\n [\n document.defaultFooterHeight,\n document.defaultFooterState,\n document.defaultHeaderHeight,\n document.defaultHeaderState,\n ],\n );\n\n const bodyHeights = useMemo(\n () => document.pages.map(page => computeBodyHeight(\n document.headerFooterEnabled ? page.headerHeight : 0,\n document.headerFooterEnabled ? page.footerHeight : 0,\n )),\n [document.headerFooterEnabled, document.pages],\n );\n\n useEffect(() => {\n const previousBodyHeights = previousBodyHeightsRef.current;\n previousBodyHeightsRef.current = bodyHeights;\n\n if (!previousBodyHeights) {\n return;\n }\n\n const bodySpaceExpanded = bodyHeights.some((height, index) => {\n const previousHeight = previousBodyHeights[index];\n return previousHeight !== undefined && height > previousHeight;\n });\n\n if (bodySpaceExpanded) {\n debug('page', 'body space expanded — running full reflow');\n reflowAll();\n }\n }, [bodyHeights, reflowAll]);\n\n useEffect(\n () => () => {\n if (pasteOverflowReleaseTimerRef.current) {\n clearTimeout(pasteOverflowReleaseTimerRef.current);\n }\n },\n [],\n );\n\n const focusBodyEditor = useCallback(\n (pageId: string, boundary: 'start' | 'end') => {\n let attempts = 0;\n\n const focusWhenReady = () => {\n const editor = editorRegistry.get(pageId);\n if (!editor) {\n if (attempts < 4) {\n attempts += 1;\n requestAnimationFrame(focusWhenReady);\n }\n return;\n }\n\n const caretPosition = { pageId, region: 'body' as const };\n setActivePageId(pageId);\n setActiveEditor(editor as LexicalEditor, caretPosition);\n editor.focus(() => {\n editor.update(() => {\n if (boundary === 'start') {\n $getRoot().selectStart();\n } else {\n $getRoot().selectEnd();\n }\n });\n });\n };\n\n requestAnimationFrame(focusWhenReady);\n },\n [editorRegistry, setActiveEditor, setActivePageId],\n );\n\n const handlePageOverflow = useCallback(\n (\n pageIndex: number,\n overflowContent: SerializedEditorState,\n cause: 'paste' | 'content',\n ) => {\n const nextPageIndex = pageIndex + 1;\n const overflowChildCount = overflowContent.root?.children?.length ?? 0;\n debug('page', `handlePageOverflow: pageIndex=${pageIndex} overflowChildren=${overflowChildCount} totalPages=${document.pages.length}`);\n\n if (cause === 'paste') {\n pasteOverflowSequenceRef.current = true;\n }\n\n if (pasteOverflowSequenceRef.current) {\n if (pasteOverflowReleaseTimerRef.current) {\n clearTimeout(pasteOverflowReleaseTimerRef.current);\n }\n pasteOverflowReleaseTimerRef.current = setTimeout(() => {\n pasteOverflowSequenceRef.current = false;\n pasteOverflowReleaseTimerRef.current = null;\n }, 800);\n }\n\n if (nextPageIndex < document.pages.length) {\n // Prepend overflow content to the next page's editor directly\n const nextPage = document.pages[nextPageIndex];\n const nextEditor = editorRegistry.get(nextPage.id);\n\n if (nextEditor) {\n const currentState = nextEditor.getEditorState().toJSON();\n const existingChildren = currentState.root?.children ?? [];\n const overflowChildren = overflowContent.root?.children ?? [];\n\n debug('page', `prepending ${overflowChildren.length} nodes to existing page ${shortId(nextPage.id)} (had ${existingChildren.length} children)`);\n\n const mergedState: SerializedEditorState = {\n root: {\n ...currentState.root,\n children: [...overflowChildren, ...existingChildren],\n },\n } as SerializedEditorState;\n\n const newEditorState = nextEditor.parseEditorState(JSON.stringify(mergedState));\n nextEditor.setEditorState(newEditorState);\n if (pasteOverflowSequenceRef.current) {\n requestFocusAtEnd({ pageId: nextPage.id, region: 'body' });\n }\n } else {\n debug('page', `editor not found in registry for page ${shortId(nextPage.id)} — falling back to ADD_PAGE`);\n const newPage = createPageFromTemplate(defaultPageTemplate);\n newPage.bodyState = overflowContent;\n runHistoryAction(\n {\n label: 'Overflow created new page',\n source: 'overflow',\n region: 'document',\n },\n () => {\n dispatch({ type: 'ADD_PAGE', afterIndex: pageIndex, page: newPage });\n },\n );\n if (pasteOverflowSequenceRef.current) {\n requestFocusAtEnd({ pageId: newPage.id, region: 'body' });\n }\n }\n } else {\n // Create a new page with the overflow content as initial state\n const newPage = createPageFromTemplate(defaultPageTemplate);\n newPage.bodyState = overflowContent;\n debug('page', `creating new page ${shortId(newPage.id)} with ${overflowChildCount} overflow children`);\n runHistoryAction(\n {\n label: 'Overflow created new page',\n source: 'overflow',\n region: 'document',\n },\n () => {\n dispatch({ type: 'ADD_PAGE', page: newPage });\n },\n );\n if (pasteOverflowSequenceRef.current) {\n requestFocusAtEnd({ pageId: newPage.id, region: 'body' });\n }\n }\n },\n [defaultPageTemplate, document.pages, dispatch, editorRegistry, requestFocusAtEnd, runHistoryAction],\n );\n\n const handleBackspaceAtPageStart = useCallback(\n (pageIndex: number, pageId: string) => {\n if (pageIndex <= 0) {\n return;\n }\n\n const previousPage = document.pages[pageIndex - 1];\n if (!previousPage) {\n return;\n }\n\n runHistoryAction(\n {\n label: `${t.historyLabels.deletedBackward} - ${interpolate(t.regions.page, { page: pageIndex + 1 })}`,\n source: 'body',\n pageId,\n region: 'body',\n },\n () => {\n handlePageUnderflow(pageIndex - 1);\n },\n );\n\n focusBodyEditor(previousPage.id, 'end');\n },\n [document.pages, focusBodyEditor, handlePageUnderflow, runHistoryAction],\n );\n\n const handleDeleteAtPageEnd = useCallback(\n (pageIndex: number, pageId: string) => {\n const currentPage = document.pages[pageIndex];\n const nextPage = document.pages[pageIndex + 1];\n if (!currentPage || !nextPage) {\n return;\n }\n\n runHistoryAction(\n {\n label: `${t.historyLabels.deletedForward} - ${interpolate(t.regions.page, { page: pageIndex + 1 })}`,\n source: 'body',\n pageId,\n region: 'body',\n },\n () => {\n handlePageUnderflow(pageIndex);\n },\n );\n\n focusBodyEditor(currentPage.id, 'end');\n },\n [document.pages, focusBodyEditor, handlePageUnderflow, runHistoryAction],\n );\n\n const handleMoveToPreviousPage = useCallback(\n (pageIndex: number) => {\n if (pageIndex <= 0) {\n return;\n }\n\n const previousPage = document.pages[pageIndex - 1];\n if (!previousPage) {\n return;\n }\n\n focusBodyEditor(previousPage.id, 'end');\n },\n [document.pages, focusBodyEditor],\n );\n\n const handleMoveToNextPage = useCallback(\n (pageIndex: number) => {\n const nextPage = document.pages[pageIndex + 1];\n if (!nextPage) {\n return;\n }\n\n focusBodyEditor(nextPage.id, 'start');\n },\n [document.pages, focusBodyEditor],\n );\n\n return (\n <div\n className=\"lex4-document-view\"\n data-testid=\"document-view\"\n tabIndex={-1}\n >\n {document.pages.map((page, index) => (\n <PageView\n key={page.id}\n pageId={page.id}\n pageIndex={index}\n onOverflow={(content, cause) => handlePageOverflow(index, content, cause)}\n onBackspaceAtStart={handleBackspaceAtPageStart}\n onDeleteAtEnd={handleDeleteAtPageEnd}\n onMoveToPreviousPage={handleMoveToPreviousPage}\n onMoveToNextPage={handleMoveToNextPage}\n />\n ))}\n </div>\n );\n};\n","/**\n * Document AST types — the backend integration contract.\n *\n * These types define the clean, Lexical-independent AST\n * that consumers receive when calling getDocumentAst().\n * Backend teams can use these types directly without any\n * knowledge of Lexical or React internals.\n *\n * @version 1.0.0\n */\n\nexport const AST_VERSION = '1.0.0' as const;\n\n// ---------------------------------------------------------------------------\n// Top-level document\n// ---------------------------------------------------------------------------\n\nexport interface DocumentAst {\n version: typeof AST_VERSION;\n page: PageFormatAst;\n headerFooter: HeaderFooterConfigAst;\n pages: PageAst[];\n metadata: DocumentMetadataAst;\n}\n\nexport interface PageFormatAst {\n format: 'A4';\n widthMm: number;\n heightMm: number;\n margins: MarginsAst;\n}\n\nexport interface MarginsAst {\n topMm: number;\n rightMm: number;\n bottomMm: number;\n leftMm: number;\n}\n\nexport interface HeaderFooterConfigAst {\n enabled: boolean;\n pageCounterMode: 'none' | 'header' | 'footer' | 'both';\n defaultHeader: ContentAst | null;\n defaultFooter: ContentAst | null;\n}\n\nexport interface DocumentMetadataAst {\n variables: Record<string, VariableDefinitionAst>;\n}\n\n// ---------------------------------------------------------------------------\n// Page\n// ---------------------------------------------------------------------------\n\nexport interface PageAst {\n pageIndex: number;\n body: BlockNodeAst[];\n header: ContentAst | null;\n footer: ContentAst | null;\n}\n\n// ---------------------------------------------------------------------------\n// Content container\n// ---------------------------------------------------------------------------\n\nexport interface ContentAst {\n blocks: BlockNodeAst[];\n}\n\n// ---------------------------------------------------------------------------\n// Block nodes\n// ---------------------------------------------------------------------------\n\nexport type BlockNodeAst =\n | ParagraphAst\n | HeadingAst\n | ListAst\n | BlockQuoteAst;\n\nexport type Alignment = 'left' | 'center' | 'right' | 'justify';\n\nexport interface ParagraphAst {\n type: 'paragraph';\n alignment?: Alignment;\n indent?: number;\n children: InlineNodeAst[];\n}\n\nexport interface HeadingAst {\n type: 'heading';\n level: 1 | 2 | 3 | 4 | 5 | 6;\n alignment?: Alignment;\n children: InlineNodeAst[];\n}\n\nexport interface ListAst {\n type: 'list';\n listType: 'ordered' | 'unordered';\n items: ListItemAst[];\n}\n\nexport interface ListItemAst {\n type: 'list-item';\n children: InlineNodeAst[];\n nestedList?: ListAst;\n}\n\nexport interface BlockQuoteAst {\n type: 'blockquote';\n children: InlineNodeAst[];\n}\n\n// ---------------------------------------------------------------------------\n// Inline nodes\n// ---------------------------------------------------------------------------\n\nexport type InlineNodeAst =\n | TextRunAst\n | VariableAst\n | LineBreakAst;\n\nexport interface TextMarks {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n fontFamily?: string;\n fontSize?: number;\n}\n\nexport interface TextRunAst {\n type: 'text';\n text: string;\n marks?: TextMarks;\n}\n\nexport interface VariableAst {\n type: 'variable';\n key: string;\n marks?: TextMarks;\n}\n\nexport interface LineBreakAst {\n type: 'linebreak';\n}\n\n// ---------------------------------------------------------------------------\n// Variable definitions (shared with variables/types.ts)\n// ---------------------------------------------------------------------------\n\nexport interface VariableDefinitionAst {\n key: string;\n label: string;\n description?: string;\n valueType?: 'string' | 'number' | 'date' | 'boolean';\n group?: string;\n}\n\n// ---------------------------------------------------------------------------\n// REST payload\n// ---------------------------------------------------------------------------\n\nexport interface SaveDocumentRequest {\n document: DocumentAst;\n exportTarget?: 'pdf' | 'docx';\n documentId?: string;\n metadata?: Record<string, string>;\n}\n","/**\n * Inline mapper — Converts Lexical serialized inline nodes to AST inline nodes.\n *\n * Handles:\n * - TextNode → TextRunAst (decodes format bitmask + parses CSS style)\n * - VariableNode → VariableAst\n * - LineBreakNode → LineBreakAst\n */\n\nimport type { InlineNodeAst, TextMarks, TextRunAst, VariableAst, LineBreakAst } from './types';\nimport type { SerializedVariableNode } from '../variables/variable-node';\nimport {\n extractFontFamilyFromStyle,\n extractFontSizePtFromStyle,\n} from '../utils/text-style';\n\n// Lexical format bitmask constants\nconst IS_BOLD = 1;\nconst IS_ITALIC = 2;\nconst IS_STRIKETHROUGH = 4;\nconst IS_UNDERLINE = 8;\n\n/** Serialized Lexical text node shape (subset of fields we need). */\ninterface SerializedTextNode {\n type: 'text';\n text: string;\n format: number;\n style?: string;\n [key: string]: unknown;\n}\n\ninterface SerializedLineBreak {\n type: 'linebreak';\n [key: string]: unknown;\n}\n\ntype SerializedInlineNode = SerializedTextNode | SerializedVariableNode | SerializedLineBreak;\n\n/**\n * Decodes Lexical's format bitmask into named boolean marks.\n */\nexport function decodeFormatBitmask(format: number): Pick<TextMarks, 'bold' | 'italic' | 'underline' | 'strikethrough'> {\n const marks: Pick<TextMarks, 'bold' | 'italic' | 'underline' | 'strikethrough'> = {};\n if (format & IS_BOLD) marks.bold = true;\n if (format & IS_ITALIC) marks.italic = true;\n if (format & IS_UNDERLINE) marks.underline = true;\n if (format & IS_STRIKETHROUGH) marks.strikethrough = true;\n return marks;\n}\n\n/**\n * Extracts font-family from a CSS style string.\n */\nexport function extractFontFamily(style: string): string | undefined {\n return extractFontFamilyFromStyle(style);\n}\n\n/**\n * Extracts font-size (in pt) from a CSS style string.\n */\nexport function extractFontSizePt(style: string): number | undefined {\n return extractFontSizePtFromStyle(style);\n}\n\n/**\n * Builds TextMarks from a Lexical format bitmask and style string.\n */\nexport function buildTextMarks(format: number, style?: string): TextMarks | undefined {\n const formatMarks = decodeFormatBitmask(format);\n const fontFamily = style ? extractFontFamily(style) : undefined;\n const fontSize = style ? extractFontSizePt(style) : undefined;\n\n const marks: TextMarks = {\n ...formatMarks,\n ...(fontFamily ? { fontFamily } : {}),\n ...(fontSize ? { fontSize } : {}),\n };\n\n return Object.keys(marks).length > 0 ? marks : undefined;\n}\n\n/**\n * Maps a single serialized Lexical inline node to an AST inline node.\n */\nexport function mapInlineNode(node: SerializedInlineNode): InlineNodeAst {\n switch (node.type) {\n case 'text':\n return mapTextNode(node as SerializedTextNode);\n case 'variable-node':\n return mapVariableNode(node as SerializedVariableNode);\n case 'linebreak':\n return mapLineBreak();\n default:\n // Fallback: treat unknown inline nodes as empty text\n return { type: 'text', text: '' };\n }\n}\n\nfunction mapTextNode(node: SerializedTextNode): TextRunAst {\n const marks = buildTextMarks(node.format, node.style);\n return {\n type: 'text',\n text: node.text,\n ...(marks ? { marks } : {}),\n };\n}\n\nfunction mapVariableNode(node: SerializedVariableNode): VariableAst {\n const marks = buildTextMarks(node.format ?? 0, node.style);\n return {\n type: 'variable',\n key: node.variableKey,\n ...(marks ? { marks } : {}),\n };\n}\n\nfunction mapLineBreak(): LineBreakAst {\n return { type: 'linebreak' };\n}\n\n/**\n * Maps an array of serialized Lexical inline nodes to AST inline nodes.\n */\nexport function mapInlineNodes(nodes: SerializedInlineNode[]): InlineNodeAst[] {\n return nodes.map(mapInlineNode);\n}\n","/**\n * Block mapper — Converts Lexical serialized block nodes to AST block nodes.\n *\n * Handles:\n * - ParagraphNode → ParagraphAst\n * - HeadingNode → HeadingAst\n * - ListNode → ListAst\n * - ListItemNode → ListItemAst (with nested list support)\n * - QuoteNode → BlockQuoteAst\n */\n\nimport type {\n BlockNodeAst,\n ParagraphAst,\n HeadingAst,\n ListAst,\n ListItemAst,\n BlockQuoteAst,\n Alignment,\n InlineNodeAst,\n} from './types';\nimport { mapInlineNodes } from './inline-mapper';\n\n// Lexical format bitmask for element alignment\nconst ALIGN_LEFT = 1;\nconst ALIGN_CENTER = 2;\nconst ALIGN_RIGHT = 3;\nconst ALIGN_JUSTIFY = 4;\n\n/** Generic serialized Lexical element node shape. */\ninterface SerializedElementNode {\n type: string;\n children?: SerializedElementNode[];\n format?: number | string;\n indent?: number;\n direction?: string;\n tag?: string;\n listType?: string;\n start?: number;\n value?: number;\n [key: string]: unknown;\n}\n\nfunction decodeAlignment(format: number | string | undefined): Alignment | undefined {\n if (typeof format === 'string') {\n if (['left', 'center', 'right', 'justify'].includes(format)) {\n return format as Alignment;\n }\n return undefined;\n }\n if (typeof format !== 'number' || format === 0) return undefined;\n switch (format) {\n case ALIGN_LEFT: return 'left';\n case ALIGN_CENTER: return 'center';\n case ALIGN_RIGHT: return 'right';\n case ALIGN_JUSTIFY: return 'justify';\n default: return undefined;\n }\n}\n\n/**\n * Maps a single serialized Lexical block node to an AST block node.\n */\nexport function mapBlockNode(node: SerializedElementNode): BlockNodeAst {\n switch (node.type) {\n case 'paragraph':\n return mapParagraph(node);\n case 'heading':\n return mapHeading(node);\n case 'list':\n return mapList(node);\n case 'quote':\n return mapBlockQuote(node);\n default:\n // Fallback: treat as paragraph with empty children\n return {\n type: 'paragraph',\n children: mapInlineChildren(node),\n };\n }\n}\n\nfunction mapParagraph(node: SerializedElementNode): ParagraphAst {\n const alignment = decodeAlignment(node.format);\n const indent = node.indent && node.indent > 0 ? node.indent : undefined;\n return {\n type: 'paragraph',\n ...(alignment ? { alignment } : {}),\n ...(indent ? { indent } : {}),\n children: mapInlineChildren(node),\n };\n}\n\nfunction mapHeading(node: SerializedElementNode): HeadingAst {\n const alignment = decodeAlignment(node.format);\n const tagMatch = node.tag?.match(/^h([1-6])$/);\n const level = tagMatch ? (parseInt(tagMatch[1], 10) as 1 | 2 | 3 | 4 | 5 | 6) : 1;\n return {\n type: 'heading',\n level,\n ...(alignment ? { alignment } : {}),\n children: mapInlineChildren(node),\n };\n}\n\nfunction mapList(node: SerializedElementNode): ListAst {\n const listType = node.listType === 'number' ? 'ordered' : 'unordered';\n const items = (node.children ?? [])\n .filter(c => c.type === 'listitem')\n .map(mapListItem);\n return {\n type: 'list',\n listType,\n items,\n };\n}\n\nfunction mapListItem(node: SerializedElementNode): ListItemAst {\n const inlineChildren: InlineNodeAst[] = [];\n let nestedList: ListAst | undefined;\n\n for (const child of node.children ?? []) {\n if (child.type === 'list') {\n nestedList = mapList(child);\n } else {\n // Inline children\n const mapped = mapInlineNodes([child as never]);\n inlineChildren.push(...mapped);\n }\n }\n\n return {\n type: 'list-item',\n children: inlineChildren,\n ...(nestedList ? { nestedList } : {}),\n };\n}\n\nfunction mapBlockQuote(node: SerializedElementNode): BlockQuoteAst {\n return {\n type: 'blockquote',\n children: mapInlineChildren(node),\n };\n}\n\n/** Extracts inline children from a block node. */\nfunction mapInlineChildren(node: SerializedElementNode): InlineNodeAst[] {\n if (!node.children || node.children.length === 0) return [];\n return mapInlineNodes(node.children as never[]);\n}\n\n/**\n * Maps an array of serialized Lexical block nodes to AST block nodes.\n */\nexport function mapBlockNodes(nodes: SerializedElementNode[]): BlockNodeAst[] {\n return nodes.map(mapBlockNode);\n}\n","/**\n * Content mapper — Converts a Lexical SerializedEditorState to AST content.\n *\n * This module bridges the gap between Lexical's serialized state\n * (which has a root → children hierarchy) and the flat BlockNodeAst[]\n * used in the AST contract.\n */\n\nimport type { SerializedEditorState } from 'lexical';\nimport type { BlockNodeAst, ContentAst } from './types';\nimport { mapBlockNodes } from './block-mapper';\n\n/**\n * Converts a Lexical SerializedEditorState into a ContentAst.\n *\n * Returns null if the state is null/undefined (e.g. disabled header).\n */\nexport function mapEditorStateToContent(\n state: SerializedEditorState | null | undefined,\n): ContentAst | null {\n if (!state || !state.root || !state.root.children) {\n return null;\n }\n\n const blocks = mapBlockNodes(state.root.children as never[]);\n return { blocks };\n}\n\n/**\n * Converts a Lexical SerializedEditorState to flat BlockNodeAst[].\n *\n * Used for body content where we need the array directly\n * rather than wrapped in a ContentAst.\n */\nexport function mapEditorStateToBlocks(\n state: SerializedEditorState | null | undefined,\n): BlockNodeAst[] {\n if (!state || !state.root || !state.root.children) {\n return [];\n }\n\n return mapBlockNodes(state.root.children as never[]);\n}\n","/**\n * Document serializer — Converts a Lex4Document to a DocumentAst.\n *\n * This is the top-level serialization pipeline that orchestrates\n * all sub-mappers (inline, block, content) to produce the final\n * AST contract object.\n */\n\nimport type {\n DocumentAst,\n PageAst,\n VariableDefinitionAst,\n DocumentMetadataAst,\n} from './types';\nimport { AST_VERSION } from './types';\nimport type { Lex4Document } from '../types/document';\nimport type { VariableDefinition } from '../variables/types';\nimport { mapEditorStateToBlocks, mapEditorStateToContent } from './content-mapper';\nimport {\n PAGE_MARGIN_TOP_PX,\n PAGE_MARGIN_BOTTOM_PX,\n PAGE_MARGIN_LEFT_PX,\n PAGE_MARGIN_RIGHT_PX,\n PX_PER_MM,\n} from '../constants';\n\nconst MARGIN_TOP_MM = Math.round((PAGE_MARGIN_TOP_PX / PX_PER_MM) * 10) / 10;\nconst MARGIN_BOTTOM_MM = Math.round((PAGE_MARGIN_BOTTOM_PX / PX_PER_MM) * 10) / 10;\nconst MARGIN_LEFT_MM = Math.round((PAGE_MARGIN_LEFT_PX / PX_PER_MM) * 10) / 10;\nconst MARGIN_RIGHT_MM = Math.round((PAGE_MARGIN_RIGHT_PX / PX_PER_MM) * 10) / 10;\n\n/**\n * Serializes a Lex4Document into a clean, backend-friendly DocumentAst.\n *\n * @param document - The current editor document state\n * @param variableDefinitions - Optional variable definitions for metadata\n */\nexport function serializeDocument(\n document: Lex4Document,\n variableDefinitions: VariableDefinition[] = [],\n): DocumentAst {\n const pages: PageAst[] = document.pages.map((page, index) =>\n serializePage(page, index),\n );\n\n const metadata = buildMetadata(variableDefinitions);\n\n return {\n version: AST_VERSION,\n page: {\n format: 'A4',\n widthMm: 210,\n heightMm: 297,\n margins: {\n topMm: MARGIN_TOP_MM,\n rightMm: MARGIN_RIGHT_MM,\n bottomMm: MARGIN_BOTTOM_MM,\n leftMm: MARGIN_LEFT_MM,\n },\n },\n headerFooter: {\n enabled: document.headerFooterEnabled,\n pageCounterMode: document.pageCounterMode,\n defaultHeader: document.pages.length > 0\n ? mapEditorStateToContent(document.pages[0].headerState)\n : null,\n defaultFooter: document.pages.length > 0\n ? mapEditorStateToContent(document.pages[0].footerState)\n : null,\n },\n pages,\n metadata,\n };\n}\n\nfunction serializePage(\n page: { bodyState: import('lexical').SerializedEditorState | null; headerState: import('lexical').SerializedEditorState | null; footerState: import('lexical').SerializedEditorState | null },\n pageIndex: number,\n): PageAst {\n return {\n pageIndex,\n body: mapEditorStateToBlocks(page.bodyState),\n header: mapEditorStateToContent(page.headerState),\n footer: mapEditorStateToContent(page.footerState),\n };\n}\n\nfunction buildMetadata(\n variableDefinitions: VariableDefinition[],\n): DocumentMetadataAst {\n const variables: Record<string, VariableDefinitionAst> = {};\n\n for (const def of variableDefinitions) {\n variables[def.key] = {\n key: def.key,\n label: def.label,\n ...(def.description ? { description: def.description } : {}),\n ...(def.valueType ? { valueType: def.valueType } : {}),\n ...(def.group ? { group: def.group } : {}),\n };\n }\n\n return { variables };\n}\n","/**\n * Payload builder — Wraps a DocumentAst into a REST-ready payload.\n *\n * This module provides a simple helper for consumers to construct\n * a request body suitable for sending to a backend document generation API.\n */\n\nimport type { DocumentAst, SaveDocumentRequest } from './types';\n\nexport interface PayloadOptions {\n /** Target export format */\n exportTarget?: 'pdf' | 'docx';\n /** External document identifier */\n documentId?: string;\n /** Additional metadata for the backend */\n metadata?: Record<string, string>;\n}\n\n/**\n * Builds a SaveDocumentRequest payload from a DocumentAst.\n */\nexport function buildSavePayload(\n ast: DocumentAst,\n options?: PayloadOptions,\n): SaveDocumentRequest {\n return {\n document: ast,\n ...(options?.exportTarget ? { exportTarget: options.exportTarget } : {}),\n ...(options?.documentId ? { documentId: options.documentId } : {}),\n ...(options?.metadata ? { metadata: options.metadata } : {}),\n };\n}\n\n/**\n * Serializes a DocumentAst to a JSON string.\n */\nexport function serializeDocumentJson(ast: DocumentAst): string {\n return JSON.stringify(ast, null, 2);\n}\n","import {\n $createLineBreakNode,\n $createParagraphNode,\n $createTextNode,\n $getSelection,\n $isNodeSelection,\n $isRangeSelection,\n $insertNodes,\n type LexicalEditor,\n type LexicalNode,\n type SerializedEditorState,\n} from 'lexical';\nimport {\n $createHeadingNode,\n $createQuoteNode,\n type HeadingTagType,\n} from '@lexical/rich-text';\nimport { $createListItemNode, $createListNode } from '@lexical/list';\nimport type { Lex4Document } from '../../types/document';\nimport { $createVariableNode } from '../../variables/variable-node';\n\ninterface SerializedLexicalBaseNode {\n type: string;\n children?: SerializedLexicalBaseNode[];\n format?: number | string;\n indent?: number;\n listType?: string;\n start?: number;\n text?: string;\n style?: string;\n variableKey?: string;\n [key: string]: unknown;\n}\n\nfunction appendChildren(\n parent: LexicalNode & { append: (...nodes: LexicalNode[]) => void },\n children: SerializedLexicalBaseNode[] = [],\n): void {\n const nodes = children\n .map(buildLexicalNode)\n .filter((node): node is LexicalNode => node !== null);\n\n if (nodes.length > 0) {\n parent.append(...nodes);\n }\n}\n\nfunction applyElementFormatting(\n node: LexicalNode & { setFormat?: (format: 'left' | 'center' | 'right' | 'justify') => void; setIndent?: (indent: number) => void },\n serializedNode: SerializedLexicalBaseNode,\n): void {\n if (\n typeof serializedNode.format === 'string'\n && ['left', 'center', 'right', 'justify'].includes(serializedNode.format)\n && node.setFormat\n ) {\n node.setFormat(serializedNode.format as 'left' | 'center' | 'right' | 'justify');\n }\n\n if (typeof serializedNode.indent === 'number' && serializedNode.indent > 0 && node.setIndent) {\n node.setIndent(serializedNode.indent);\n }\n}\n\nfunction buildLexicalNode(serializedNode: SerializedLexicalBaseNode): LexicalNode | null {\n switch (serializedNode.type) {\n case 'paragraph': {\n const node = $createParagraphNode();\n applyElementFormatting(node, serializedNode);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'heading': {\n const tag = typeof serializedNode.tag === 'string'\n && /^h[1-6]$/.test(serializedNode.tag)\n ? serializedNode.tag as HeadingTagType\n : 'h1';\n const node = $createHeadingNode(tag);\n applyElementFormatting(node, serializedNode);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'quote': {\n const node = $createQuoteNode();\n applyElementFormatting(node, serializedNode);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'list': {\n const listType = serializedNode.listType === 'number' ? 'number' : 'bullet';\n const node = $createListNode(listType, typeof serializedNode.start === 'number' ? serializedNode.start : 1);\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'listitem': {\n const node = $createListItemNode();\n appendChildren(node, serializedNode.children);\n return node;\n }\n case 'text': {\n const node = $createTextNode(serializedNode.text ?? '');\n if (typeof serializedNode.format === 'number' && serializedNode.format > 0) {\n node.setFormat(serializedNode.format);\n }\n if (typeof serializedNode.style === 'string' && serializedNode.style.trim() !== '') {\n node.setStyle(serializedNode.style);\n }\n return node;\n }\n case 'linebreak':\n return $createLineBreakNode();\n case 'variable-node':\n return $createVariableNode(\n serializedNode.variableKey ?? '',\n typeof serializedNode.format === 'number' ? serializedNode.format : 0,\n typeof serializedNode.style === 'string' ? serializedNode.style : '',\n );\n default:\n return null;\n }\n}\n\nfunction getBodyChildren(pageState: SerializedEditorState | null): SerializedLexicalBaseNode[] {\n const root = pageState?.root as { children?: SerializedLexicalBaseNode[] } | undefined;\n return root?.children ?? [];\n}\n\nexport function insertDocumentContent(editor: LexicalEditor, document: Lex4Document): boolean {\n let inserted = false;\n\n editor.update(() => {\n const nodes = document.pages.flatMap((page) => getBodyChildren(page.bodyState))\n .map(buildLexicalNode)\n .filter((node): node is LexicalNode => node !== null);\n\n if (nodes.length === 0) {\n return;\n }\n\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n if (selection.isCollapsed()) {\n selection.insertParagraph();\n }\n\n const nextSelection = $getSelection();\n if ($isRangeSelection(nextSelection) || $isNodeSelection(nextSelection)) {\n nextSelection.insertNodes(nodes);\n } else {\n $insertNodes(nodes);\n }\n } else if ($isNodeSelection(selection)) {\n selection.insertNodes(nodes);\n } else {\n $insertNodes(nodes);\n }\n inserted = true;\n });\n\n return inserted;\n}\n","import type { LexicalEditor } from 'lexical';\nimport type { EditorRegistry } from '../context/document-context';\nimport type { CaretPosition } from '../types/history';\n\ninterface ResolveDocumentInsertTargetOptions {\n activeEditor: LexicalEditor | null;\n activeCaretPosition: CaretPosition | null;\n activePageId: string | null;\n editorRegistry: EditorRegistry;\n}\n\nexport function resolveDocumentInsertTarget({\n activeEditor,\n activeCaretPosition,\n activePageId,\n editorRegistry,\n}: ResolveDocumentInsertTargetOptions): LexicalEditor | null {\n if (activeEditor && activeCaretPosition?.region === 'body') {\n return activeEditor;\n }\n\n if (activePageId) {\n return editorRegistry.get(activePageId) ?? null;\n }\n\n return editorRegistry.all()[0] ?? null;\n}\n","import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';\nimport type { Lex4EditorProps } from '../types/editor-props';\nimport type { Lex4EditorHandle } from '../types/editor-handle';\nimport { DocumentProvider } from '../context/document-provider';\nimport { useDocument } from '../context/document-context';\nimport { useTranslations } from '../i18n';\nimport { HistorySidebar } from './HistorySidebar';\nimport { Toolbar } from './Toolbar';\nimport { DocumentView } from './DocumentView';\nimport {\n ExtensionProvider,\n ExtensionStateProvider,\n useExtensions,\n useExtensionContext,\n} from '../extensions/extension-context';\nimport { TranslationsProvider } from '../i18n';\nimport { serializeDocument } from '../ast/document-serializer';\nimport { serializeDocumentJson } from '../ast/payload-builder';\nimport { ToolbarConfigProvider } from '../context/toolbar-config';\nimport { insertDocumentContent } from '../lexical/utils/import-document-content';\nimport { resolveDocumentInsertTarget } from '../utils/document-insert-target';\nimport '../styles.css';\n\nfunction selectEntireDocument(\n rootElement: HTMLDivElement | null,\n selectionBuffer: HTMLTextAreaElement | null,\n) {\n if (!rootElement || !selectionBuffer) {\n return;\n }\n\n const bodyRoots = Array.from(\n rootElement.querySelectorAll<HTMLElement>('[data-testid^=\"page-body-\"] [data-lexical-editor=\"true\"]'),\n );\n\n if (bodyRoots.length === 0) {\n return;\n }\n\n selectionBuffer.value = bodyRoots\n .map(bodyRoot => bodyRoot.innerText.trim())\n .filter(Boolean)\n .join('\\n');\n selectionBuffer.focus();\n selectionBuffer.select();\n}\n\nconst GLOBAL_SELECTION_BACKGROUND = 'hsl(214 95% 87%)';\nconst GLOBAL_SELECTION_FOREGROUND = 'hsl(224 71% 25%)';\n\nfunction isFormFieldTarget(target: EventTarget | null): boolean {\n const element = target as HTMLElement | null;\n const tagName = element?.tagName;\n return tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';\n}\n\nconst EditorChrome: React.FC<{\n captureHistoryShortcutsOnWindow: boolean;\n onSave?: Lex4EditorProps['onSave'];\n className?: string;\n}> = ({\n captureHistoryShortcutsOnWindow,\n onSave,\n className,\n}) => {\n const {\n document,\n dispatch,\n globalSelectionActive,\n setGlobalSelectionActive,\n undo,\n redo,\n } = useDocument();\n const { sidePanels, cssVariables, rootClassNames } = useExtensions();\n const rootRef = useRef<HTMLDivElement>(null);\n const selectionBufferRef = useRef<HTMLTextAreaElement>(null);\n\n const clearGlobalSelection = useCallback(() => {\n setGlobalSelectionActive(false);\n selectionBufferRef.current?.blur();\n }, [setGlobalSelectionActive]);\n\n const handleHistoryShortcut = useCallback((event: { key: string; metaKey: boolean; ctrlKey: boolean; shiftKey: boolean; preventDefault: () => void; stopPropagation?: () => void }) => {\n const key = event.key.toLowerCase();\n\n if (key === 'z') {\n event.preventDefault();\n event.stopPropagation?.();\n clearGlobalSelection();\n if (event.shiftKey) {\n redo();\n } else {\n undo();\n }\n return true;\n }\n\n if (key === 'y') {\n event.preventDefault();\n event.stopPropagation?.();\n clearGlobalSelection();\n redo();\n return true;\n }\n\n return false;\n }, [clearGlobalSelection, redo, undo]);\n\n const handleKeyDownCapture = useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement | null;\n const isGlobalSelectionBufferTarget = target === selectionBufferRef.current;\n\n if (!isGlobalSelectionBufferTarget && isFormFieldTarget(target)) {\n return;\n }\n\n const key = event.key.toLowerCase();\n\n if (isGlobalSelectionBufferTarget && (key === 'backspace' || key === 'delete')) {\n event.preventDefault();\n event.stopPropagation();\n dispatch({ type: 'CLEAR_DOCUMENT_CONTENT' });\n clearGlobalSelection();\n return;\n }\n\n const hasModifier = event.metaKey || event.ctrlKey;\n if (!hasModifier) {\n return;\n }\n\n if (key === 'a') {\n event.preventDefault();\n event.stopPropagation();\n requestAnimationFrame(() => {\n const activeElement = window.document.activeElement;\n if (activeElement instanceof HTMLElement && activeElement.isContentEditable) {\n activeElement.blur();\n }\n selectEntireDocument(rootRef.current, selectionBufferRef.current);\n setGlobalSelectionActive(true);\n });\n return;\n }\n\n if (key === 's' && onSave) {\n event.preventDefault();\n event.stopPropagation();\n const ast = serializeDocument(document);\n const json = serializeDocumentJson(ast);\n onSave({ document, ast, json });\n return;\n }\n\n if (handleHistoryShortcut(event)) {\n return;\n }\n }, [\n document,\n dispatch,\n handleHistoryShortcut,\n onSave,\n setGlobalSelectionActive,\n ]);\n\n const handleMouseDownCapture = useCallback((event: React.MouseEvent<HTMLDivElement>) => {\n if (!globalSelectionActive) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n const clickedToolbar = target?.closest('[data-testid=\"toolbar\"]');\n\n if (event.target !== selectionBufferRef.current && !clickedToolbar) {\n clearGlobalSelection();\n }\n }, [clearGlobalSelection, globalSelectionActive]);\n\n useEffect(() => {\n const editableRoots =\n rootRef.current?.querySelectorAll<HTMLElement>(\n '[data-testid^=\"page-body-\"] [data-lexical-editor=\"true\"]',\n ) ?? [];\n\n const root = rootRef.current;\n const styles = root ? getComputedStyle(root) : null;\n const selBg = styles?.getPropertyValue('--color-selection-bg').trim() || GLOBAL_SELECTION_BACKGROUND;\n const selFg = styles?.getPropertyValue('--color-selection-text').trim() || GLOBAL_SELECTION_FOREGROUND;\n\n editableRoots.forEach((editableRoot) => {\n editableRoot.style.backgroundColor = globalSelectionActive ? selBg : '';\n editableRoot.style.color = globalSelectionActive ? selFg : '';\n editableRoot.style.caretColor = globalSelectionActive ? 'transparent' : '';\n });\n }, [globalSelectionActive, document.pages.length]);\n\n useEffect(() => {\n if (!captureHistoryShortcutsOnWindow) {\n return;\n }\n\n const handleWindowKeyDown = (event: KeyboardEvent) => {\n const hasModifier = event.metaKey || event.ctrlKey;\n if (!hasModifier) {\n return;\n }\n\n handleHistoryShortcut(event);\n };\n\n window.addEventListener('keydown', handleWindowKeyDown, { capture: true });\n const handleWindowBeforeInput = (event: InputEvent) => {\n if (event.inputType === 'historyUndo') {\n event.preventDefault();\n clearGlobalSelection();\n undo();\n } else if (event.inputType === 'historyRedo') {\n event.preventDefault();\n clearGlobalSelection();\n redo();\n }\n };\n\n window.addEventListener('beforeinput', handleWindowBeforeInput, { capture: true });\n return () => {\n window.removeEventListener('keydown', handleWindowKeyDown, { capture: true });\n window.removeEventListener('beforeinput', handleWindowBeforeInput, { capture: true });\n };\n }, [captureHistoryShortcutsOnWindow, clearGlobalSelection, handleHistoryShortcut, redo, undo]);\n\n const rootClassName = ['lex4-editor', ...rootClassNames, className].filter(Boolean).join(' ');\n const extensionStyle = Object.keys(cssVariables).length > 0\n ? cssVariables as React.CSSProperties\n : undefined;\n\n return (\n <div\n ref={rootRef}\n className={rootClassName}\n style={extensionStyle}\n data-testid=\"lex4-editor\"\n data-global-selection-active={globalSelectionActive ? 'true' : 'false'}\n onKeyDownCapture={handleKeyDownCapture}\n onMouseDownCapture={handleMouseDownCapture}\n >\n <textarea\n ref={selectionBufferRef}\n aria-hidden=\"true\"\n data-testid=\"global-selection-buffer\"\n readOnly\n tabIndex={-1}\n className=\"lex4-selection-buffer\"\n />\n <Toolbar />\n <div className=\"lex4-canvas\">\n <div className=\"lex4-canvas-scroll\">\n <DocumentView />\n </div>\n {sidePanels.map((Panel, idx) => (\n <Panel key={idx} />\n ))}\n <HistorySidebar />\n </div>\n </div>\n );\n};\n\n/**\n * EditorWithHandle — Inner component that wires the imperative handle.\n * Has access to DocumentProvider and extension contexts.\n */\nconst EditorWithHandle = forwardRef<Lex4EditorHandle, {\n captureHistoryShortcutsOnWindow: boolean;\n onSave?: Lex4EditorProps['onSave'];\n className?: string;\n}>(({ captureHistoryShortcutsOnWindow, onSave, className }, ref) => {\n const {\n document: doc,\n activePageId,\n activeEditor,\n activeCaretPosition,\n editorRegistry,\n historySidebarOpen,\n runHistoryAction,\n setHistorySidebarOpen,\n } = useDocument();\n const { handleFactories } = useExtensions();\n const t = useTranslations();\n const documentRef = useRef(doc);\n const activeEditorRef = useRef(activeEditor);\n const historySidebarOpenRef = useRef(historySidebarOpen);\n const runHistoryActionRef = useRef(runHistoryAction);\n const insertedDocumentContentLabelRef = useRef(t.history.actions.insertedDocumentContent);\n\n useEffect(() => {\n documentRef.current = doc;\n }, [doc]);\n\n useEffect(() => {\n activeEditorRef.current = activeEditor;\n }, [activeEditor]);\n\n useEffect(() => {\n historySidebarOpenRef.current = historySidebarOpen;\n }, [historySidebarOpen]);\n\n useEffect(() => {\n runHistoryActionRef.current = runHistoryAction;\n }, [runHistoryAction]);\n\n useEffect(() => {\n insertedDocumentContentLabelRef.current = t.history.actions.insertedDocumentContent;\n }, [t.history.actions.insertedDocumentContent]);\n\n const getDocument = useCallback(() => documentRef.current, []);\n const getActiveEditor = useCallback(() => activeEditorRef.current, []);\n const extensionCtx = useExtensionContext(getDocument, getActiveEditor);\n const handleRef = useRef<Record<string, (...args: never[]) => unknown>>({});\n const extensionMethodKeysRef = useRef<string[]>([]);\n\n const handle = handleRef.current;\n handle.setHistorySidebarOpen = (open: boolean) => {\n setHistorySidebarOpen(open);\n };\n handle.toggleHistorySidebar = () => {\n setHistorySidebarOpen(!historySidebarOpenRef.current);\n };\n handle.insertDocumentContent = (documentToInsert) => {\n const targetEditor = resolveDocumentInsertTarget({\n activeEditor: activeEditorRef.current,\n activeCaretPosition,\n activePageId,\n editorRegistry,\n });\n if (!targetEditor) {\n return false;\n }\n\n let inserted = false;\n runHistoryActionRef.current(\n {\n label: insertedDocumentContentLabelRef.current,\n source: 'toolbar',\n region: 'document',\n },\n () => {\n inserted = insertDocumentContent(targetEditor, documentToInsert);\n },\n );\n return inserted;\n };\n\n for (const key of extensionMethodKeysRef.current) {\n delete handle[key];\n }\n\n const extensionMethodKeys: string[] = [];\n for (const factory of handleFactories) {\n const methods = factory(extensionCtx);\n for (const [key, method] of Object.entries(methods)) {\n handle[key] = method as (...args: never[]) => unknown;\n extensionMethodKeys.push(key);\n }\n }\n extensionMethodKeysRef.current = extensionMethodKeys;\n\n useImperativeHandle(ref, () => handle as unknown as Lex4EditorHandle, []);\n\n return (\n <EditorChrome\n captureHistoryShortcutsOnWindow={captureHistoryShortcutsOnWindow}\n onSave={onSave}\n className={className}\n />\n );\n});\n\nEditorWithHandle.displayName = 'EditorWithHandle';\n\n/**\n * Lex4Editor — The main public component.\n *\n * A paginated A4 document editor built on Meta Lexical.\n * Each page is a true discrete A4 page with its own Lexical editor instance.\n *\n * Uses an extension system for AST export, variables, and theming.\n * Pass extensions via the `extensions` prop:\n * @example\n * ```tsx\n * <Lex4Editor extensions={[defaultTheme(), astExtension(), variablesExtension(defs)]} />\n * ```\n */\nexport const Lex4Editor = forwardRef<Lex4EditorHandle, Lex4EditorProps>(({\n captureHistoryShortcutsOnWindow = true,\n initialDocument,\n onDocumentChange,\n onSave,\n extensions,\n translations,\n toolbar,\n className,\n}, ref) => {\n return (\n <TranslationsProvider translations={translations}>\n <ToolbarConfigProvider toolbar={toolbar}>\n <ExtensionStateProvider>\n <ExtensionProvider extensions={extensions}>\n <DocumentProvider\n initialDocument={initialDocument}\n onDocumentChange={onDocumentChange}\n >\n <EditorWithHandle\n ref={ref}\n captureHistoryShortcutsOnWindow={captureHistoryShortcutsOnWindow}\n onSave={onSave}\n className={className}\n />\n </DocumentProvider>\n </ExtensionProvider>\n </ExtensionStateProvider>\n </ToolbarConfigProvider>\n </TranslationsProvider>\n );\n});\n\nLex4Editor.displayName = 'Lex4Editor';\n","import { useCallback, useRef, useEffect } from 'react';\n\n/**\n * useOverflowDetection — Debounced overflow detection for a page body.\n *\n * Watches a contentEditable element and fires `onOverflow` when the\n * content height exceeds the allowed body height. Uses a debounce\n * to avoid firing on every keystroke.\n */\nexport function useOverflowDetection(\n bodyHeight: number,\n onOverflow: (() => void) | undefined,\n debounceMs: number = 100,\n) {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const check = useCallback(\n (el: HTMLElement) => {\n if (!onOverflow) return;\n if (el.scrollHeight > bodyHeight + 2) {\n // +2 for sub-pixel rounding\n onOverflow();\n }\n },\n [bodyHeight, onOverflow],\n );\n\n const attachRef = useCallback(\n (el: HTMLElement | null) => {\n // Cleanup previous observer\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n if (!el || !onOverflow) return;\n\n observerRef.current = new ResizeObserver(() => {\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => check(el), debounceMs);\n });\n observerRef.current.observe(el);\n },\n [check, debounceMs, onOverflow],\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n if (observerRef.current) observerRef.current.disconnect();\n };\n }, []);\n\n return { attachRef };\n}\n","import { useCallback, useRef, useEffect } from 'react';\n\n/**\n * useHeaderFooter — Tracks header/footer height via ResizeObserver\n * and reports changes to the document context.\n *\n * Clamps the reported height to the maximum allowed.\n */\nexport function useHeaderFooter(\n maxHeight: number,\n onHeightChange: (height: number) => void,\n) {\n const observerRef = useRef<ResizeObserver | null>(null);\n const lastHeightRef = useRef<number>(0);\n\n const attachRef = useCallback(\n (el: HTMLElement | null) => {\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n\n if (!el) return;\n\n const measure = () => {\n const height = Math.min(el.scrollHeight, maxHeight);\n if (height !== lastHeightRef.current) {\n lastHeightRef.current = height;\n onHeightChange(height);\n }\n };\n\n observerRef.current = new ResizeObserver(measure);\n observerRef.current.observe(el);\n\n // Initial measurement\n measure();\n },\n [maxHeight, onHeightChange],\n );\n\n useEffect(() => {\n return () => {\n if (observerRef.current) observerRef.current.disconnect();\n };\n }, []);\n\n return { attachRef };\n}\n","import type { Lex4Extension, ExtensionContext } from './types';\nimport { serializeDocument } from '../ast/document-serializer';\nimport { buildSavePayload, serializeDocumentJson } from '../ast/payload-builder';\nimport type { PayloadOptions } from '../ast/payload-builder';\nimport type { DocumentAst, SaveDocumentRequest } from '../ast/types';\nimport type { VariableDefinition } from '../variables/types';\n\ndeclare module '../types/editor-handle' {\n interface Lex4EditorHandle {\n getDocumentAst: () => DocumentAst;\n getDocumentJson: () => string;\n buildSavePayload: (options?: PayloadOptions) => SaveDocumentRequest;\n }\n}\n\n/**\n * Creates an AST extension that adds document export capabilities.\n *\n * Handle methods provided:\n * - `getDocumentAst()` — returns the current document as a typed AST\n * - `getDocumentJson()` — returns the AST as a JSON string\n * - `buildSavePayload(options?)` — builds a REST payload wrapping the AST\n *\n * @example\n * ```tsx\n * <Lex4Editor extensions={[astExtension()]} />\n * ```\n */\nexport function astExtension(): Lex4Extension {\n return {\n name: 'ast',\n handleMethods: (ctx: ExtensionContext) => {\n const getDefinitions = (): VariableDefinition[] => {\n return ctx.getExtensionState<VariableDefinition[]>('variableDefinitions') ?? [];\n };\n\n return {\n getDocumentAst: () => {\n const doc = ctx.getDocument();\n return serializeDocument(doc, getDefinitions());\n },\n getDocumentJson: () => {\n const doc = ctx.getDocument();\n const ast = serializeDocument(doc, getDefinitions());\n return serializeDocumentJson(ast);\n },\n buildSavePayload: (options?: Parameters<typeof buildSavePayload>[1]) => {\n const doc = ctx.getDocument();\n const ast = serializeDocument(doc, getDefinitions());\n return buildSavePayload(ast, options);\n },\n };\n },\n };\n}\n","import {\n createCommand,\n type LexicalEditor,\n} from 'lexical';\n\n/**\n * Command to insert a variable node at the current selection.\n * Payload is the variable key string (e.g. \"customer.name\").\n */\nexport const INSERT_VARIABLE_COMMAND = createCommand<string>('INSERT_VARIABLE');\n\n/**\n * Inserts a variable node at the current cursor position.\n */\nexport function insertVariable(editor: LexicalEditor, variableKey: string): void {\n editor.dispatchCommand(INSERT_VARIABLE_COMMAND, variableKey);\n}\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $insertNodes,\n COMMAND_PRIORITY_EDITOR,\n} from 'lexical';\nimport { $createVariableNode } from './variable-node';\nimport { INSERT_VARIABLE_COMMAND } from './variable-commands';\n\n/**\n * VariablePlugin — registers the INSERT_VARIABLE_COMMAND handler.\n *\n * When the command fires, a VariableNode is created and inserted\n * at the current selection position.\n */\nexport const VariablePlugin: React.FC = () => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_VARIABLE_COMMAND,\n (variableKey: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const variableNode = $createVariableNode(variableKey);\n $insertNodes([variableNode]);\n });\n return true;\n },\n COMMAND_PRIORITY_EDITOR,\n );\n }, [editor]);\n\n return null;\n};\n","import React, { useCallback, useMemo, useState } from 'react';\nimport { Search, RefreshCw } from 'lucide-react';\nimport { EditorSidebar } from './EditorSidebar';\nimport { useVariables } from '../variables/variable-context';\nimport { useDocument } from '../context/document-context';\nimport { useTranslations, interpolate } from '../i18n';\nimport { INSERT_VARIABLE_COMMAND } from '../variables/variable-commands';\nimport type { VariableDefinition } from '../variables/types';\n\n/**\n * VariablePanel — Right sidebar for browsing and inserting variables.\n *\n * Features:\n * - Search/filter variables by name or key\n * - Grouped list with colored badges\n * - Click-to-insert into the active editor\n * - Refresh button for reloading definitions\n */\nexport const VariablePanel: React.FC<{\n open: boolean;\n onClose: () => void;\n}> = ({ open, onClose }) => {\n const { definitions, refreshDefinitions } = useVariables();\n const { activeEditor, runHistoryAction } = useDocument();\n const t = useTranslations();\n const [filter, setFilter] = useState('');\n const [creating, setCreating] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const [draft, setDraft] = useState<{\n label: string;\n key: string;\n group: string;\n valueType: NonNullable<VariableDefinition['valueType']>;\n }>({\n label: '',\n key: '',\n group: '',\n valueType: 'string',\n });\n\n const filtered = useMemo(() => {\n if (!filter) return definitions;\n const lower = filter.toLowerCase();\n return definitions.filter(\n d => d.key.toLowerCase().includes(lower) || d.label.toLowerCase().includes(lower),\n );\n }, [definitions, filter]);\n\n const grouped = useMemo(() => {\n const groups: Record<string, VariableDefinition[]> = {};\n for (const def of filtered) {\n const g = def.group ?? 'Other';\n if (!groups[g]) groups[g] = [];\n groups[g].push(def);\n }\n return groups;\n }, [filtered]);\n\n const handleInsert = useCallback(\n (key: string) => {\n if (!activeEditor) return;\n runHistoryAction(\n { label: interpolate(t.variables.insertVariable, { key }), source: 'toolbar', region: 'document' },\n () => {\n activeEditor.dispatchCommand(INSERT_VARIABLE_COMMAND, key);\n },\n );\n },\n [activeEditor, runHistoryAction],\n );\n\n const resetCreateState = useCallback(() => {\n setDraft({\n label: '',\n key: '',\n group: '',\n valueType: 'string',\n });\n setCreateError(null);\n setCreating(false);\n }, []);\n\n const handleCreateVariable = useCallback((event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n const label = draft.label.trim();\n const key = draft.key.trim();\n const group = draft.group.trim();\n\n if (!label || !key) {\n setCreateError(t.variables.createVariableMissingFields);\n return;\n }\n\n if (definitions.some(def => def.key === key)) {\n setCreateError(interpolate(t.variables.createVariableDuplicateKey, { key }));\n return;\n }\n\n refreshDefinitions([\n ...definitions,\n {\n key,\n label,\n group: group || undefined,\n valueType: draft.valueType,\n },\n ]);\n\n resetCreateState();\n }, [\n definitions,\n draft.group,\n draft.key,\n draft.label,\n draft.valueType,\n refreshDefinitions,\n resetCreateState,\n t.variables.createVariableDuplicateKey,\n t.variables.createVariableMissingFields,\n ]);\n\n return (\n <EditorSidebar\n title={t.variables.title}\n subtitle={interpolate(t.variables.available, { count: String(definitions.length) })}\n open={open}\n onClose={onClose}\n testId=\"variable-panel\"\n headerActions={\n <button\n type=\"button\"\n className=\"lex4-sidebar-action-btn\"\n title={t.variables.refreshVariables}\n data-testid=\"btn-refresh-variables\"\n >\n <RefreshCw size={12} />\n </button>\n }\n >\n <div className=\"lex4-variable-panel-content\">\n <div className=\"lex4-variable-search-container\">\n <div className=\"lex4-variable-search-wrapper\">\n <Search size={14} className=\"lex4-variable-search-icon\" />\n <input\n type=\"text\"\n className=\"lex4-variable-search-input\"\n placeholder={t.variables.searchPlaceholder}\n data-testid=\"variable-panel-search\"\n value={filter}\n onChange={e => setFilter(e.target.value)}\n />\n </div>\n </div>\n\n <div className=\"lex4-variable-list\">\n {Object.keys(grouped).length === 0 && (\n <div className=\"lex4-variable-list-empty\">{t.variables.noVariablesFound}</div>\n )}\n {Object.entries(grouped).map(([group, defs]) => (\n <div key={group} className=\"lex4-variable-group\" data-variable-group={group}>\n <div className=\"lex4-variable-group-label\">{group}</div>\n <div className=\"lex4-variable-group-items\">\n {defs.map(def => (\n <button\n key={def.key}\n type=\"button\"\n className=\"lex4-variable-list-item\"\n data-testid={`variable-panel-${def.key}`}\n data-variable-group={group}\n onClick={() => handleInsert(def.key)}\n disabled={!activeEditor}\n title={def.key}\n >\n {def.label}\n </button>\n ))}\n </div>\n </div>\n ))}\n </div>\n\n <div className=\"lex4-variable-create\">\n {creating ? (\n <form className=\"lex4-variable-create-form\" onSubmit={handleCreateVariable}>\n <div className=\"lex4-variable-create-title\">{t.variables.createVariableTitle}</div>\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableLabel}</span>\n <input\n value={draft.label}\n onChange={(e) => {\n setDraft(current => ({ ...current, label: e.target.value }));\n if (createError) {\n setCreateError(null);\n }\n }}\n />\n </label>\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableKey}</span>\n <input\n value={draft.key}\n onChange={(e) => {\n setDraft(current => ({ ...current, key: e.target.value }));\n if (createError) {\n setCreateError(null);\n }\n }}\n />\n </label>\n <div className=\"lex4-variable-create-row\">\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableGroup}</span>\n <input\n value={draft.group}\n onChange={(e) => {\n setDraft(current => ({ ...current, group: e.target.value }));\n }}\n />\n </label>\n <label className=\"lex4-variable-create-field\">\n <span>{t.variables.createVariableType}</span>\n <select\n value={draft.valueType}\n onChange={(e) => {\n setDraft(current => ({\n ...current,\n valueType: e.target.value as NonNullable<VariableDefinition['valueType']>,\n }));\n }}\n >\n <option value=\"string\">string</option>\n <option value=\"number\">number</option>\n <option value=\"date\">date</option>\n <option value=\"boolean\">boolean</option>\n </select>\n </label>\n </div>\n {createError && <div className=\"lex4-variable-create-error\">{createError}</div>}\n <div className=\"lex4-variable-create-actions\">\n <button type=\"button\" className=\"lex4-variable-create-cancel\" onClick={resetCreateState}>\n {t.variables.createVariableCancel}\n </button>\n <button type=\"submit\" className=\"lex4-variable-create-submit\">\n {t.variables.createVariableSave}\n </button>\n </div>\n </form>\n ) : (\n <button\n type=\"button\"\n className=\"lex4-variable-create-toggle\"\n onClick={() => setCreating(true)}\n >\n + {t.variables.newVariable}\n </button>\n )}\n </div>\n </div>\n </EditorSidebar>\n );\n};\n","import React, { createContext, useContext, useEffect, useState } from 'react';\nimport { Braces } from 'lucide-react';\nimport type { Lex4Extension, ExtensionContext } from './types';\nimport type { VariableDefinition } from '../variables/types';\nimport { VariableNode } from '../variables/variable-node';\nimport { VariablePlugin } from '../variables/variable-plugin';\nimport { VariableProvider, useVariables } from '../variables/variable-context';\nimport { VariablePanel } from '../components/VariablePanel';\nimport { INSERT_VARIABLE_COMMAND } from '../variables/variable-commands';\n\ndeclare module '../types/editor-handle' {\n interface Lex4EditorHandle {\n insertVariable: (key: string) => void;\n refreshVariables: (newDefs: VariableDefinition[]) => void;\n setVariablePanelOpen: (open: boolean) => void;\n toggleVariablePanel: () => void;\n }\n}\nimport { useExtensionState } from './extension-context';\nimport { useTranslations } from '../i18n';\nimport { useToolbarConfig } from '../context/toolbar-config';\n\n// --- Variable panel open/close context ---\n\ninterface VariablePanelState {\n panelOpen: boolean;\n setPanelOpen: (open: boolean) => void;\n}\n\nconst VariablePanelContext = createContext<VariablePanelState>({\n panelOpen: false,\n setPanelOpen: () => {},\n});\n\nexport function useVariablePanelState(): VariablePanelState {\n return useContext(VariablePanelContext);\n}\n\nconst VariablePanelStateProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [panelOpen, setPanelOpen] = useState(false);\n return (\n <VariablePanelContext.Provider value={{ panelOpen, setPanelOpen }}>\n {children}\n </VariablePanelContext.Provider>\n );\n};\n\n/**\n * Toolbar toggle contributed by the variables extension.\n * Opens and closes the variables side panel from the toolbar end area.\n */\nconst VariableToolbarToggle: React.FC = () => {\n const { panelOpen, setPanelOpen } = useVariablePanelState();\n const toolbarConfig = useToolbarConfig();\n const t = useTranslations();\n\n if (!toolbarConfig.variables.visible) {\n return null;\n }\n\n return (\n <button\n type=\"button\"\n className={`lex4-toolbar-toggle-btn${panelOpen ? ' active' : ''}`}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => setPanelOpen(!panelOpen)}\n data-testid=\"toggle-variable-panel\"\n title={panelOpen ? t.variables.closePanel : t.variables.openPanel}\n aria-label={panelOpen ? t.variables.closePanel : t.variables.openPanel}\n >\n <Braces size={14} />\n {toolbarConfig.variables.showLabel && t.variables.title}\n </button>\n );\n};\n\n/**\n * Wrapped VariablePanel that reads open/close state from VariablePanelContext.\n */\nconst VariablePanelWithState: React.FC = () => {\n const { panelOpen, setPanelOpen } = useVariablePanelState();\n return <VariablePanel open={panelOpen} onClose={() => setPanelOpen(false)} />;\n};\n\nconst VariablePanelStateSync: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const { panelOpen, setPanelOpen } = useVariablePanelState();\n const extState = useExtensionState();\n\n useEffect(() => {\n extState.set('variablePanelOpen', panelOpen);\n extState.set('setVariablePanelOpen', setPanelOpen);\n }, [extState, panelOpen, setPanelOpen]);\n\n return <>{children}</>;\n};\n\n/**\n * Syncs the VariableProvider definitions into the extension state store\n * so astExtension can access them when building the AST.\n */\nconst VariableDefinitionsSync: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const { definitions } = useVariables();\n const extState = useExtensionState();\n\n useEffect(() => {\n extState.set('variableDefinitions', definitions);\n }, [definitions, extState]);\n\n return <>{children}</>;\n};\n\n/**\n * Creates a variables extension that adds variable/placeholder support.\n *\n * Contributes:\n * - VariableNode (custom Lexical node)\n * - VariablePlugin (body plugin for insert command handling)\n * - VariableProvider (context provider for variable catalog)\n * - Variables side panel plus toolbar toggle\n * - VariablePanel side panel with toggle state\n * - Handle methods: insertVariable, refreshVariables\n *\n * @param definitions Initial variable definitions to load\n *\n * @example\n * ```tsx\n * const defs = [\n * { key: 'customer.name', label: 'Customer', group: 'Customer', valueType: 'string' },\n * ];\n * <Lex4Editor extensions={[variablesExtension(defs)]} />\n * ```\n */\nexport function variablesExtension(definitions: VariableDefinition[] = []): Lex4Extension {\n const ProviderWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n return (\n <VariablePanelStateProvider>\n <VariableProvider initialDefinitions={definitions}>\n <VariablePanelStateSync>\n <VariableDefinitionsSync>\n {children}\n </VariableDefinitionsSync>\n </VariablePanelStateSync>\n </VariableProvider>\n </VariablePanelStateProvider>\n );\n };\n\n return {\n name: 'variables',\n nodes: [VariableNode],\n bodyPlugins: [VariablePlugin],\n toolbarEndItems: [VariableToolbarToggle],\n sidePanel: VariablePanelWithState,\n provider: ProviderWrapper,\n handleMethods: (ctx: ExtensionContext) => ({\n insertVariable: (key: string) => {\n const editor = ctx.getActiveEditor();\n if (editor) {\n editor.dispatchCommand(INSERT_VARIABLE_COMMAND, key);\n }\n },\n refreshVariables: (newDefs: VariableDefinition[]) => {\n ctx.setExtensionState('variableDefinitions', newDefs);\n },\n setVariablePanelOpen: (open: boolean) => {\n const setter = ctx.getExtensionState<(open: boolean) => void>('setVariablePanelOpen');\n setter?.(open);\n },\n toggleVariablePanel: () => {\n const current = ctx.getExtensionState<boolean>('variablePanelOpen') ?? false;\n const setter = ctx.getExtensionState<(open: boolean) => void>('setVariablePanelOpen');\n setter?.(!current);\n },\n }),\n };\n}\n"],"names":["createContext","useContext","document","useMemo","selection","$getSelection","$isRangeSelection","$isTextNode","useRef","$createRangeSelectionFromDom","useReducer","useState","useCallback","$getRoot","useEffect","jsx","forwardRef","createElement","__iconNode","jsxs","jumpToHistoryEntry","FORMAT_TEXT_COMMAND","FORMAT_ELEMENT_COMMAND","INSERT_ORDERED_LIST_COMMAND","INSERT_UNORDERED_LIST_COMMAND","INDENT_CONTENT_COMMAND","OUTDENT_CONTENT_COMMAND","DecoratorNode","useLexicalComposerContext","useLexicalNodeSelection","$createNodeSelection","$isNodeSelection","$setSelection","$getNodeByKey","KEY_BACKSPACE_COMMAND","COMMAND_PRIORITY_LOW","KEY_DELETE_COMMAND","KEY_DOWN_COMMAND","$applyNodeReplacement","FORMAT_MASKS","getElementBlockType","$isHeadingNode","$isElementNode","$createParagraphNode","$createHeadingNode","$setBlocksType","$patchStyleText","variable","style","$selectAll","SELECTION_CHANGE_COMMAND","AlignLeft","AlignCenter","AlignRight","AlignJustify","IndentIncrease","IndentDecrease","Fragment","keepState","overflowState","nextPage","HeadingNode","QuoteNode","ListNode","ListItemNode","KEY_TAB_COMMAND","$isParagraphNode","FOCUS_COMMAND","serializeNodeTree","$isListNode","$splitNode","$getNearestNodeFromDOMNode","CONTROLLED_TEXT_INSERTION_COMMAND","PASTE_COMMAND","KEY_ENTER_COMMAND","COMMAND_PRIORITY_HIGH","LexicalComposer","RichTextPlugin","ContentEditable","LexicalErrorBoundary","ListPlugin","OnChangePlugin","COMMAND_PRIORITY_CRITICAL","$createQuoteNode","$createListNode","$createListItemNode","$createTextNode","$createLineBreakNode","$insertNodes","useImperativeHandle","createCommand","COMMAND_PRIORITY_EDITOR"],"mappings":"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","x_google_ignoreList":[9,10,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50]}
|