react-word-editor 0.0.0-stage → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/harsh/Documents/Flabs/flabs-editor/dist/chunk-NNYINC42.cjs","../src/toolbar/constants.js","../src/extensions/paragraphFormat.js","../src/utils/units.js","../src/extensions/tableCells.js","../src/utils/borders.js","../src/extensions/nodeIds.js","../src/utils/meta.js","../src/extensions/index.js","../src/extensions/imageUpload.js","../src/extensions/textCase.js","../src/utils/textCase.js","../src/extensions/tableBorders.js","../src/paste/styleSheet.js","../src/paste/wordLists.js","../src/paste/cleanHtml.js","../src/utils/listMarkers.js","../src/output/text.js","../src/pdf/options.js","../src/utils/colors.js","../src/pdf/inline.js","../src/pdf/table.js","../src/pdf/tree.js","../src/output/convert.js"],"names":["pct","BLOCK_TYPES","_a","Extension"],"mappings":"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AAA;AACR,QAAA;AACQ,UAAA;AACG,UAAA;AACE,UAAA;AACb,QAAA;AACA,QAAA;AACQ,UAAA;AACG,UAAA;AACC,UAAA;AACL,YAAA;AACK,YAAA;AACR,YAAA;AACD,UAAA;AACH,QAAA;AACF,MAAA;AACF,IAAA;AACD,EAAA;AACM,EAAA;AACC,IAAA;AACC,IAAA;AACS,MAAA;AACE,MAAA;AAClB,IAAA;AACU,IAAA;AACZ,EAAA;AACF;AAEsB;AA7EtB,EAAA;AA8EqB,EAAA;AACZ,IAAA;AACI,MAAA;AACL,QAAA;AACS,QAAA;AACV,MAAA;AACa,IAAA;AACR,MAAA;AACA,MAAA;AACC,MAAA;AACL,QAAA;AACY,QAAA;AACD,QAAA;AACX,QAAA;AACS,QAAA;AACA,QAAA;AACV,MAAA;AACH,IAAA;AACK,IAAA;AACA,IAAA;AACI,MAAA;AACJ,IAAA;AACI,MAAA;AACJ,IAAA;AACI,MAAA;AACC,QAAA;AACC,QAAA;AACL,UAAA;AACA,UAAA;AACA,UAAA;AACS,UAAA;AACX,QAAA;AACU,QAAA;AACZ,MAAA;AACG,IAAA;AACI,MAAA;AACC,QAAA;AACC,QAAA;AACL,UAAA;AACA,UAAA;AACS,UAAA;AACX,QAAA;AACW,QAAA;AACb,MAAA;AACY,IAAA;AACC,MAAA;AACH,MAAA;AACI,MAAA;AACH,MAAA;AACC,MAAA;AACG,MAAA;AACjB,IAAA;AACA,IAAA;AACc,MAAA;AAChB,EAAA;AACF;AAK8B;AACf,EAAA;AACC,EAAA;AACR,EAAA;AAEY,EAAA;AACT,EAAA;AACO,EAAA;AACT,EAAA;AACC,IAAA;AACG,IAAA;AACG,IAAA;AACF,IAAA;AACZ,EAAA;AACF;AAE0B;AtB2mDL;AACA;AuBtwDZ;AACA;AAKU;AAEN;AACQ,EAAA;AACZ,EAAA;AACT;AAE2B;AAED;AAGH;AAEH;AAIO;AAMd;AACG,EAAA;AACK,EAAA;AACF,EAAA;AACV,EAAA;AACT;AAE2B;AACV,EAAA;AACD,EAAA;AACK,EAAA;AACR,EAAA;AACO,IAAA;AAClB,EAAA;AACkB,EAAA;AACR,EAAA;AACS,EAAA;AACrB;AAE0B;AACL,EAAA;AACD,EAAA;AACpB;AAE2B;AACV,EAAA;AACF,EAAA;AACI,EAAA;AACC,EAAA;AACR,EAAA;AACO,EAAA;AACnB;AAE2B;AvBkvDN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/harsh/Documents/Flabs/flabs-editor/dist/chunk-NNYINC42.cjs","sourcesContent":[null,"export const BLOCK_TYPES = [\n { value: 'paragraph', label: 'Normal' },\n { value: 'h1', label: 'Heading 1' },\n { value: 'h2', label: 'Heading 2' },\n { value: 'h3', label: 'Heading 3' },\n { value: 'h4', label: 'Heading 4' },\n];\n\nexport const DEFAULT_FONT_FAMILIES = [\n { value: '', label: 'Default font' },\n { value: 'Roboto, sans-serif', label: 'Roboto' },\n { value: 'Arial, Helvetica, sans-serif', label: 'Arial' },\n { value: 'Calibri, Carlito, sans-serif', label: 'Calibri' },\n { value: '\"Times New Roman\", Times, serif', label: 'Times New Roman' },\n { value: 'Georgia, serif', label: 'Georgia' },\n { value: 'Verdana, sans-serif', label: 'Verdana' },\n { value: '\"Courier New\", Courier, monospace', label: 'Courier New' },\n];\n\nexport const DEFAULT_FONT_SIZES = ['8', '9', '10', '11', '12', '14', '16', '18', '20', '24', '28', '36', '48'];\n\nexport const LINE_HEIGHTS = [\n { value: '', label: 'Line spacing', menuLabel: 'Default' },\n { value: '1', label: '1.0' },\n { value: '1.15', label: '1.15' },\n { value: '1.5', label: '1.5' },\n { value: '2', label: '2.0' },\n { value: '2.5', label: '2.5' },\n { value: '3', label: '3.0' },\n];\n\nexport const COLOR_SWATCHES = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#ffffff',\n '#c00000', '#ff0000', '#ffc000', '#ffff00', '#92d050', '#00b050',\n '#00b0f0', '#0070c0', '#002060', '#7030a0', '#2d5cf2', '#f4b183',\n '#fde9d9', '#fff2cc', '#e2efda', '#ddebf7', '#d9e2f3', '#ededed',\n];\n\nexport const DEFAULT_TOOLBAR = [\n 'undo', 'redo', '|',\n 'blockType', 'fontFamily', 'fontSize', 'textCase', '|',\n 'bold', 'italic', 'underline', 'strike', 'subscript', 'superscript', '|',\n 'textColor', 'highlight', '|',\n 'alignLeft', 'alignCenter', 'alignRight', 'alignJustify', '|',\n 'bulletList', 'orderedList', 'outdent', 'indent', 'lineHeight', 'paragraphSpacing', '|',\n 'table', 'image', 'link', 'horizontalRule', '|',\n 'clearFormatting',\n];\n\nexport const TABLE_PICKER_SIZE = { rows: 8, cols: 10 };\n\n// Word's built-in paragraph spacing sets; spacing in pt.\nexport const PARAGRAPH_SPACING = [\n { value: 'default', label: 'Default', before: null, after: null, lineHeight: null },\n { value: 'none', label: 'No Paragraph Space', before: 0, after: 0, lineHeight: 1 },\n { value: 'compact', label: 'Compact', before: 0, after: 4, lineHeight: 1 },\n { value: 'tight', label: 'Tight', before: 0, after: 6, lineHeight: 1.15 },\n { value: 'open', label: 'Open', before: 0, after: 10, lineHeight: 1.15 },\n { value: 'relaxed', label: 'Relaxed', before: 0, after: 6, lineHeight: 1.5 },\n { value: 'double', label: 'Double', before: 0, after: 8, lineHeight: 2 },\n];\n\nexport const TEXT_CASES = [\n { value: 'sentence', label: 'Sentence case.' },\n { value: 'lower', label: 'lowercase' },\n { value: 'upper', label: 'UPPERCASE' },\n { value: 'capitalize', label: 'Capitalise Each Word' },\n { value: 'toggle', label: 'tOGGLE cASE' },\n];\n\nexport const TABLE_BORDER_OPTIONS = [\n { value: 'bottom', label: 'Bottom Border', lines: ['bottom'] },\n { value: 'top', label: 'Top Border', lines: ['top'] },\n { value: 'left', label: 'Left Border', lines: ['left'] },\n { value: 'right', label: 'Right Border', lines: ['right'] },\n '|',\n { value: 'none', label: 'No Border', lines: [] },\n { value: 'all', label: 'All Borders', lines: ['top', 'bottom', 'left', 'right', 'insideH', 'insideV'] },\n { value: 'outside', label: 'Outside Borders', lines: ['top', 'bottom', 'left', 'right'] },\n { value: 'inside', label: 'Inside Borders', lines: ['insideH', 'insideV'] },\n '|',\n { value: 'insideH', label: 'Inside Horizontal Border', lines: ['insideH'] },\n { value: 'insideV', label: 'Inside Vertical Border', lines: ['insideV'] },\n];\n","import { Extension } from '@tiptap/core';\nimport { parseLineHeight, round, toPx } from '../utils/units';\nimport { PARAGRAPH_SPACING } from '../toolbar/constants';\n\nexport const INDENT_STEP_PX = 48;\nconst MAX_INDENT_PX = INDENT_STEP_PX * 12;\nconst BLOCK_TYPES = ['paragraph', 'heading'];\n\nconst pxAttribute = (cssProp, styleKey, { allowNegative = false, keepZero = false } = {}) => ({\n default: null,\n keepOnSplit: true,\n parseHTML: (el) => {\n const px = toPx(el.style?.[styleKey]);\n if (px === null || (!allowNegative && px < 0)) return null;\n if (px === 0 && !keepZero) return null;\n return round(px);\n },\n renderHTML: (attrs) => {\n const value = attrs[styleKey];\n if (value === null || value === undefined) return {};\n return { style: `${cssProp}: ${value}px` };\n },\n});\n\nconst updateBlocks = (tr, state, fn) => {\n const { from, to } = state.selection;\n let changed = false;\n state.doc.nodesBetween(from, to, (node, pos) => {\n if (!BLOCK_TYPES.includes(node.type.name)) return true;\n const next = fn(node.attrs);\n if (next) {\n tr.setNodeMarkup(pos, undefined, { ...node.attrs, ...next });\n changed = true;\n }\n return false;\n });\n return changed;\n};\n\nconst ptToPx = (pt) => (pt === null ? null : round(toPx(`${pt}pt`)));\n\nexport const spacingAttrs = (preset) => ({\n marginTop: preset.before ? ptToPx(preset.before) : null,\n marginBottom: ptToPx(preset.after),\n lineHeight: preset.lineHeight,\n});\n\nexport const matchSpacingPreset = (attrs = {}) =>\n PARAGRAPH_SPACING.find((preset) => {\n const want = spacingAttrs(preset);\n return Object.keys(want).every((k) => (attrs[k] ?? null) === want[k]);\n })?.value || null;\n\nexport const ParagraphFormat = Extension.create({\n name: 'paragraphFormat',\n priority: 50,\n\n addGlobalAttributes() {\n return [\n {\n types: BLOCK_TYPES,\n attributes: {\n marginLeft: {\n ...pxAttribute('margin-left', 'marginLeft'),\n // TinyMCE indents with padding-left; treat both as the indent.\n parseHTML: (el) => {\n const px = (toPx(el.style?.marginLeft) || 0) + (toPx(el.style?.paddingLeft) || 0);\n return px > 0 ? round(px) : null;\n },\n },\n textIndent: pxAttribute('text-indent', 'textIndent', { allowNegative: true }),\n marginTop: pxAttribute('margin-top', 'marginTop'),\n marginBottom: pxAttribute('margin-bottom', 'marginBottom', { keepZero: true }),\n lineHeight: {\n default: null,\n keepOnSplit: true,\n parseHTML: (el) => parseLineHeight(el.style?.lineHeight),\n renderHTML: (attrs) =>\n attrs.lineHeight ? { style: `line-height: ${attrs.lineHeight}` } : {},\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n indent:\n () =>\n ({ editor, tr, state, dispatch }) => {\n if (editor.isActive('listItem')) return editor.commands.sinkListItem('listItem');\n const changed = updateBlocks(tr, state, (attrs) => {\n const next = Math.min((attrs.marginLeft || 0) + INDENT_STEP_PX, MAX_INDENT_PX);\n return next === attrs.marginLeft ? null : { marginLeft: next };\n });\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n outdent:\n () =>\n ({ editor, tr, state, dispatch }) => {\n if (editor.isActive('listItem')) return editor.commands.liftListItem('listItem');\n const changed = updateBlocks(tr, state, (attrs) => {\n if (!attrs.marginLeft && !attrs.textIndent) return null;\n if (!attrs.marginLeft) return { textIndent: null };\n const next = Math.max(attrs.marginLeft - INDENT_STEP_PX, 0);\n return { marginLeft: next || null };\n });\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n setLineHeight:\n (lineHeight) =>\n ({ tr, state, dispatch }) => {\n const value = parseLineHeight(lineHeight);\n const changed = updateBlocks(tr, state, () => ({ lineHeight: value }));\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n setParagraphSpacing:\n (value) =>\n ({ tr, state, dispatch }) => {\n const preset = PARAGRAPH_SPACING.find((p) => p.value === value);\n if (!preset) return false;\n const changed = updateBlocks(tr, state, () => spacingAttrs(preset));\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n unsetParagraphFormat:\n () =>\n ({ tr, state, dispatch }) => {\n const changed = updateBlocks(tr, state, () => ({\n marginLeft: null,\n textIndent: null,\n marginTop: null,\n marginBottom: null,\n lineHeight: null,\n }));\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n Tab: () => {\n if (this.editor.isActive('table')) return false;\n this.editor.commands.indent();\n return true;\n },\n 'Shift-Tab': () => {\n if (this.editor.isActive('table')) return false;\n this.editor.commands.outdent();\n return true;\n },\n };\n },\n});\n","const PX_PER_UNIT = {\n px: 1,\n pt: 96 / 72,\n pc: 16,\n in: 96,\n cm: 96 / 2.54,\n mm: 96 / 25.4,\n};\n\nconst LENGTH_RE = /^(-?\\d*\\.?\\d+)\\s*(px|pt|pc|in|cm|mm|em|rem)?$/i;\n\nexport const toPx = (value, fontSizePx = 16) => {\n if (value === null || value === undefined || value === '') return null;\n if (typeof value === 'number') return Number.isFinite(value) ? value : null;\n const match = String(value).trim().match(LENGTH_RE);\n if (!match) return null;\n const num = parseFloat(match[1]);\n const unit = (match[2] || 'px').toLowerCase();\n if (unit === 'em' || unit === 'rem') return num * fontSizePx;\n return num * PX_PER_UNIT[unit];\n};\n\nexport const round = (n, digits = 2) => {\n const f = 10 ** digits;\n return Math.round(n * f) / f;\n};\n\nexport const pxToPt = (px) => round(px * 0.75);\n\nexport const toPt = (value, fontSizePx) => {\n const px = toPx(value, fontSizePx);\n return px === null ? null : pxToPt(px);\n};\n\nexport const parseLineHeight = (value) => {\n if (value === null || value === undefined || value === '') return null;\n const str = String(value).trim().toLowerCase();\n if (str === 'normal' || str === 'inherit' || str === 'initial') return null;\n if (str.endsWith('%')) {\n const pct = parseFloat(str);\n return Number.isFinite(pct) && pct > 0 ? round(pct / 100) : null;\n }\n const num = Number(str);\n if (Number.isFinite(num) && num > 0) return round(num);\n return null;\n};\n","import { TableCell, TableHeader } from '@tiptap/extension-table';\nimport { toPx } from '../utils/units';\nimport { formatBorder, parseBorders } from '../utils/borders';\n\nconst SIDES = ['Top', 'Right', 'Bottom', 'Left'];\n\nexport const DEFAULT_BORDER = '1px solid #000000';\n\nconst rgbToHex = (color) => {\n const m = String(color || '').match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([\\d.]+))?\\)$/i);\n if (!m) return color;\n if (m[4] !== undefined && parseFloat(m[4]) === 0) return 'transparent';\n return `#${[m[1], m[2], m[3]].map((n) => Number(n).toString(16).padStart(2, '0')).join('')}`;\n};\n\nconst parseBorderSide = (el, side) =>\n formatBorder(parseBorders(el.getAttribute('style'))[side.toLowerCase()]);\n\nconst parseColwidth = (el) => {\n const attr = el.getAttribute('colwidth');\n if (attr) return attr.split(',').map((w) => parseInt(w, 10));\n const raw = el.getAttribute('data-width') || el.style?.width || el.getAttribute('width');\n const px = toPx(raw && /^\\d+(\\.\\d+)?$/.test(raw) ? `${raw}px` : raw);\n if (!px) return null;\n const span = parseInt(el.getAttribute('colspan') || '1', 10) || 1;\n return Array.from({ length: span }, () => Math.max(Math.round(px / span), 20));\n};\n\nconst cellAttributes = (parent) => ({\n ...parent,\n colwidth: {\n default: null,\n parseHTML: parseColwidth,\n renderHTML: (attrs) =>\n attrs.colwidth ? { colwidth: attrs.colwidth.join(',') } : {},\n },\n backgroundColor: {\n default: null,\n parseHTML: (el) => {\n const bg = el.style?.backgroundColor || el.getAttribute('bgcolor');\n const hex = bg ? rgbToHex(bg) : null;\n return hex && hex !== 'transparent' ? hex : null;\n },\n renderHTML: (attrs) =>\n attrs.backgroundColor ? { style: `background-color: ${attrs.backgroundColor}` } : {},\n },\n verticalAlign: {\n default: null,\n parseHTML: (el) => {\n const v = (el.style?.verticalAlign || el.getAttribute('valign') || '').toLowerCase();\n return ['top', 'middle', 'bottom'].includes(v) ? v : null;\n },\n renderHTML: (attrs) =>\n attrs.verticalAlign ? { style: `vertical-align: ${attrs.verticalAlign}` } : {},\n },\n ...Object.fromEntries(\n SIDES.map((side) => [\n `border${side}`,\n {\n default: null,\n parseHTML: (el) => parseBorderSide(el, side),\n renderHTML: (attrs) => {\n const value = attrs[`border${side}`];\n return value ? { style: `border-${side.toLowerCase()}: ${value}` } : {};\n },\n },\n ]),\n ),\n});\n\nexport const RichTableCell = TableCell.extend({\n addAttributes() {\n return cellAttributes(this.parent?.());\n },\n});\n\nexport const RichTableHeader = TableHeader.extend({\n addAttributes() {\n return cellAttributes(this.parent?.());\n },\n});\n","import { round, toPx } from './units';\n\nexport const SIDES = ['top', 'right', 'bottom', 'left'];\n\nconst STYLES = ['none', 'hidden', 'solid', 'dashed', 'dotted', 'double', 'groove', 'ridge', 'inset', 'outset'];\nconst WIDTH_WORDS = { thin: '1px', medium: '3px', thick: '5px' };\n\nconst splitTokens = (value) => value.match(/(rgba?\\([^)]*\\)|[^\\s]+)/g) || [];\n\nconst expandBox = (values) => {\n const [a, b = a, c = a, d = b] = values;\n return [a, b, c, d];\n};\n\nconst parseShorthand = (value) => {\n const out = {};\n splitTokens(value.trim()).forEach((token) => {\n const t = token.toLowerCase();\n if (STYLES.includes(t)) out.style = t;\n else if (WIDTH_WORDS[t] || toPx(t) !== null) out.width = WIDTH_WORDS[t] || t;\n else out.color = token;\n });\n return out;\n};\n\n// Parses a style attribute's border declarations in source order, the way a\n// browser cascades them, without relying on each engine's CSSOM quirks.\nexport const parseBorders = (styleAttr) => {\n const sides = Object.fromEntries(SIDES.map((s) => [s, null]));\n const set = (side, part) => {\n sides[side] = { ...(sides[side] || {}), ...part };\n };\n (styleAttr || '').split(';').forEach((decl) => {\n const idx = decl.indexOf(':');\n if (idx < 1) return;\n const prop = decl.slice(0, idx).trim().toLowerCase();\n const value = decl.slice(idx + 1).trim().replace(/\\s*!important$/i, '');\n if (!prop.startsWith('border') || !value) return;\n if (prop === 'border') {\n const part = parseShorthand(value);\n SIDES.forEach((s) => {\n sides[s] = { width: '3px', style: 'none', color: 'currentcolor', ...part };\n });\n return;\n }\n const m = prop.match(/^border-(top|right|bottom|left)(?:-(width|style|color))?$/);\n if (m) {\n if (!m[2]) {\n sides[m[1]] = { width: '3px', style: 'none', color: 'currentcolor', ...parseShorthand(value) };\n } else set(m[1], { [m[2]]: value });\n return;\n }\n const all = prop.match(/^border-(width|style|color)$/);\n if (all) {\n expandBox(splitTokens(value)).forEach((v, i) => set(SIDES[i], { [all[1]]: v }));\n }\n });\n return sides;\n};\n\nexport const formatBorder = (side) => {\n if (!side) return null;\n const style = (side.style || 'none').toLowerCase();\n if (style === 'none' || style === 'hidden') return 'none';\n const px = toPx(WIDTH_WORDS[side.width] || side.width || '1px');\n if (px === 0) return 'none';\n const w = px === null ? 1 : Math.max(round(px), 0.5);\n const color = !side.color || side.color === 'currentcolor' ? '#000000' : side.color;\n return `${w}px ${style} ${color}`;\n};\n","import { Extension } from '@tiptap/core';\nimport { SILENT_META } from '../utils/meta';\n\nexport const NODE_ID_ATTRIBUTE = 'data-node-id';\n\nexport const NODE_ID_TYPES = [\n 'paragraph',\n 'heading',\n 'listItem',\n 'bulletList',\n 'orderedList',\n 'table',\n 'image',\n 'horizontalRule',\n 'blockquote',\n];\n\nconst newId = () =>\n typeof crypto !== 'undefined' && crypto.randomUUID\n ? crypto.randomUUID()\n : `n-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\n\n// Gives every block a stable, unique data-node-id. Runs on load, on\n// programmatic content changes and on blur rather than on every keystroke.\nexport const ensureNodeIds = (editor) => {\n if (!editor || editor.isDestroyed || !editor.view?.dom?.isConnected) return false;\n const { state } = editor;\n const seen = new Set();\n const tr = state.tr;\n state.doc.descendants((node, pos) => {\n if (!NODE_ID_TYPES.includes(node.type.name)) return true;\n const id = node.attrs.nodeId;\n if (!id || seen.has(id)) {\n const fresh = newId();\n seen.add(fresh);\n tr.setNodeMarkup(pos, undefined, { ...node.attrs, nodeId: fresh });\n } else {\n seen.add(id);\n }\n return true;\n });\n if (!tr.docChanged) return false;\n tr.setMeta('addToHistory', false);\n tr.setMeta(SILENT_META, true);\n editor.view.dispatch(tr);\n return true;\n};\n\nexport const NodeIds = Extension.create({\n name: 'nodeIds',\n\n addGlobalAttributes() {\n return [\n {\n types: NODE_ID_TYPES,\n attributes: {\n nodeId: {\n default: null,\n keepOnSplit: false,\n parseHTML: (el) => el.getAttribute(NODE_ID_ATTRIBUTE),\n renderHTML: (attrs) =>\n attrs.nodeId ? { [NODE_ID_ATTRIBUTE]: attrs.nodeId } : {},\n },\n },\n },\n ];\n },\n\n onBlur() {\n ensureNodeIds(this.editor);\n },\n});\n","export const SILENT_META = 'flabsEditorSilent';\n","import StarterKit from '@tiptap/starter-kit';\nimport { Table, TableRow } from '@tiptap/extension-table';\nimport {\n BackgroundColor,\n Color,\n FontFamily,\n FontSize,\n TextStyle,\n} from '@tiptap/extension-text-style';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Image from '@tiptap/extension-image';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport { Placeholder } from '@tiptap/extensions';\nimport { toPx } from '../utils/units';\nimport { ParagraphFormat } from './paragraphFormat';\nimport { RichTableCell, RichTableHeader } from './tableCells';\nimport { NodeIds } from './nodeIds';\nimport { ImageUpload } from './imageUpload';\nimport { TextCase } from './textCase';\nimport { TableBorders } from './tableBorders';\n\nconst sizeAttr = (key) => ({\n default: null,\n parseHTML: (el) => {\n const raw = el.getAttribute(key) || el.style?.[key];\n const px = toPx(raw && /^\\d+(\\.\\d+)?$/.test(raw) ? `${raw}px` : raw);\n return px ? Math.round(px) : null;\n },\n renderHTML: (attrs) => (attrs[key] ? { [key]: attrs[key] } : {}),\n});\n\nconst RichImage = Image.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n width: sizeAttr('width'),\n height: sizeAttr('height'),\n };\n },\n});\n\n// Schema-only set: used for HTML/JSON conversion outside of a live editor,\n// so stored content is parsed exactly the way the editor parses it.\nexport const buildSchemaExtensions = ({ nodeIds = false } = {}) => {\n const list = [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4] },\n link: { openOnClick: false, autolink: true, defaultProtocol: 'https' },\n undoRedo: { depth: 200 },\n }),\n TextStyle,\n Color,\n BackgroundColor,\n FontFamily,\n FontSize,\n TextAlign.configure({ types: ['heading', 'paragraph'] }),\n Subscript,\n Superscript,\n RichImage.configure({ allowBase64: true, inline: false }),\n Table.configure({ resizable: true, allowTableNodeSelection: true }),\n TableRow,\n RichTableHeader,\n RichTableCell,\n ParagraphFormat,\n ];\n if (nodeIds) list.push(NodeIds);\n return list;\n};\n\nexport const buildEditorExtensions = ({\n nodeIds,\n placeholder,\n onImageUpload,\n maxImageSize,\n onError,\n} = {}) => [\n ...buildSchemaExtensions({ nodeIds }),\n ImageUpload.configure({ onImageUpload, maxImageSize, onError }),\n TextCase,\n TableBorders,\n ...(placeholder ? [Placeholder.configure({ placeholder })] : []),\n];\n","import { Extension } from '@tiptap/core';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\n\nexport const readAsDataUrl = (file) =>\n new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(new Error('Could not read the image'));\n reader.readAsDataURL(file);\n });\n\nconst imageFiles = (list) =>\n Array.from(list || []).filter((f) => f?.type?.startsWith('image/'));\n\nexport const uploadImage = async (file, { onImageUpload, maxImageSize }) => {\n if (maxImageSize && file.size > maxImageSize) {\n const mb = Math.round((maxImageSize / 1024 / 1024) * 10) / 10;\n throw new Error(`Image size must be less than or equal to ${mb}MB`);\n }\n if (onImageUpload) return onImageUpload(file);\n return readAsDataUrl(file);\n};\n\nexport const insertImages = async (editor, files, options, pos) => {\n for (const file of files) {\n try {\n const src = await uploadImage(file, options);\n if (!src || editor.isDestroyed) continue;\n const chain = editor.chain().focus();\n if (typeof pos === 'number') chain.insertContentAt(pos, { type: 'image', attrs: { src } });\n else chain.setImage({ src });\n chain.run();\n } catch (err) {\n options.onError?.(err);\n }\n }\n};\n\nexport const ImageUpload = Extension.create({\n name: 'imageUpload',\n\n addOptions() {\n return { onImageUpload: null, maxImageSize: null, onError: null };\n },\n\n addProseMirrorPlugins() {\n const { editor, options } = this;\n return [\n new Plugin({\n key: new PluginKey('flabsImageUpload'),\n props: {\n handlePaste: (view, event) => {\n const data = event.clipboardData;\n const files = imageFiles(data?.files);\n if (!files.length) return false;\n // Word/Excel also put a picture of the selection on the clipboard;\n // the HTML is what we want whenever it has real content.\n const html = data.getData('text/html');\n if (html && /<(p|table|span|div|li|h\\d)[\\s>]/i.test(html)) return false;\n if (data.getData('text/plain')?.trim()) return false;\n insertImages(editor, files, options);\n return true;\n },\n handleDrop: (view, event) => {\n const files = imageFiles(event.dataTransfer?.files);\n if (!files.length) return false;\n event.preventDefault();\n const coords = view.posAtCoords({ left: event.clientX, top: event.clientY });\n insertImages(editor, files, options, coords?.pos);\n return true;\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from '@tiptap/core';\nimport { TextSelection } from '@tiptap/pm/state';\nimport { TEXT_CASE_MODES, createCaser } from '../utils/textCase';\n\nconst WORD_CHAR = /[\\p{L}\\p{N}'’]/u;\nconst LEAF = '\\n';\n\nconst wordAround = ($pos) => {\n const { parent } = $pos;\n if (!parent.isTextblock) return null;\n const text = parent.textBetween(0, parent.content.size, undefined, LEAF);\n let start = $pos.parentOffset;\n let end = start;\n while (start > 0 && WORD_CHAR.test(text[start - 1])) start -= 1;\n while (end < text.length && WORD_CHAR.test(text[end])) end += 1;\n if (start === end) return null;\n const base = $pos.start();\n return { from: base + start, to: base + end };\n};\n\nconst collectRuns = (doc, from, to) => {\n const blocks = [];\n doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isTextblock) return true;\n const runs = [];\n node.forEach((child, offset) => {\n if (!child.isText) return;\n const start = Math.max(from, pos + 1 + offset);\n const end = Math.min(to, pos + 1 + offset + child.nodeSize);\n if (start < end) runs.push({ start, end, marks: child.marks });\n });\n if (runs.length) {\n const before = node.textBetween(0, runs[0].start - pos - 1, undefined, LEAF);\n blocks.push({ before, runs });\n }\n return false;\n });\n return blocks;\n};\n\nexport const TextCase = Extension.create({\n name: 'textCase',\n\n addCommands() {\n return {\n setTextCase:\n (mode) =>\n ({ state, tr, dispatch }) => {\n if (!TEXT_CASE_MODES.includes(mode)) return false;\n const { selection } = state;\n const range = selection.empty\n ? wordAround(selection.$from)\n : { from: selection.from, to: selection.to };\n if (!range) return false;\n\n const edits = [];\n collectRuns(state.doc, range.from, range.to).forEach(({ before, runs }) => {\n const caser = createCaser(mode, before);\n runs.forEach(({ start, end, marks }) => {\n const text = state.doc.textBetween(start, end);\n const next = caser(text);\n if (next !== text) edits.push({ start, end, next, marks });\n });\n });\n if (!edits.length) return false;\n if (!dispatch) return true;\n\n edits.reverse().forEach(({ start, end, next, marks }) => {\n tr.replaceWith(start, end, state.schema.text(next, marks));\n });\n const sameSize = tr.doc.content.size === state.doc.content.size;\n if (selection instanceof TextSelection) {\n const from = sameSize ? selection.from : tr.mapping.map(selection.from, -1);\n const to = sameSize ? selection.to : tr.mapping.map(selection.to, 1);\n tr.setSelection(TextSelection.create(tr.doc, from, to));\n } else tr.setSelection(selection.map(tr.doc, tr.mapping));\n dispatch(tr);\n return true;\n },\n };\n },\n});\n","const LETTER = /\\p{L}/u;\nconst WORD_CHAR = /[\\p{L}\\p{N}'’]/u;\nconst SENTENCE_END = /[.!?]/;\n\nconst swapCase = (ch) => {\n const upper = ch.toUpperCase();\n return upper === ch ? ch.toLowerCase() : upper;\n};\n\n// Stateful so text split across several marked runs of one paragraph is\n// cased as one string. `before` is the paragraph text ahead of the range.\nexport const createCaser = (mode, before = '') => {\n let sentenceStart = true;\n let afterEnd = false;\n let inWord = false;\n\n const step = (ch) => {\n let out = ch;\n if (mode === 'lower') out = ch.toLowerCase();\n else if (mode === 'upper') out = ch.toUpperCase();\n else if (mode === 'toggle') out = swapCase(ch);\n else if (mode === 'capitalize') {\n if (LETTER.test(ch)) out = inWord ? ch.toLowerCase() : ch.toUpperCase();\n } else if (mode === 'sentence' && LETTER.test(ch)) {\n out = sentenceStart ? ch.toUpperCase() : ch.toLowerCase();\n }\n\n inWord = WORD_CHAR.test(ch);\n if (LETTER.test(ch) || /\\p{N}/u.test(ch)) {\n sentenceStart = false;\n afterEnd = false;\n } else if (SENTENCE_END.test(ch)) afterEnd = true;\n else if (/\\s/.test(ch)) {\n if (afterEnd) sentenceStart = true;\n } else afterEnd = false;\n return out;\n };\n\n Array.from(before).forEach(step);\n return (text) => Array.from(text).map(step).join('');\n};\n\nexport const changeCase = (text, mode, before) => createCaser(mode, before)(text);\n\nexport const TEXT_CASE_MODES = ['sentence', 'lower', 'upper', 'capitalize', 'toggle'];\n","import { Extension } from '@tiptap/core';\nimport { isInTable, selectedRect } from '@tiptap/pm/tables';\nimport { DEFAULT_BORDER } from './tableCells';\n\nconst KINDS = ['top', 'bottom', 'left', 'right', 'insideH', 'insideV'];\n\nexport const BORDER_MODES = {\n top: ['top'],\n bottom: ['bottom'],\n left: ['left'],\n right: ['right'],\n insideH: ['insideH'],\n insideV: ['insideV'],\n outside: ['top', 'bottom', 'left', 'right'],\n inside: ['insideH', 'insideV'],\n all: KINDS,\n none: KINDS,\n};\nconst APPLY_ONLY = ['all', 'none'];\n\n// Each grid line of the selection, with every cell side that draws it,\n// including cells just outside the selection, since collapsed borders share edges.\nconst collectEdges = (state) => {\n if (!isInTable(state)) return null;\n const rect = selectedRect(state);\n const { map, tableStart } = rect;\n const at = (row, col) =>\n row < 0 || col < 0 || row >= map.height || col >= map.width\n ? null\n : tableStart + map.map[row * map.width + col];\n const edges = Object.fromEntries(KINDS.map((k) => [k, []]));\n const add = (kind, pairs) => {\n const members = pairs.filter(([pos]) => pos !== null).map(([pos, attr]) => ({ pos, attr }));\n if (members.length) edges[kind].push(members);\n };\n\n for (let row = rect.top; row <= rect.bottom; row += 1) {\n for (let col = rect.left; col < rect.right; col += 1) {\n const above = at(row - 1, col);\n const below = at(row, col);\n if (above !== null && above === below) continue;\n const kind = row === rect.top ? 'top' : row === rect.bottom ? 'bottom' : 'insideH';\n add(kind, [[above, 'borderBottom'], [below, 'borderTop']]);\n }\n }\n for (let col = rect.left; col <= rect.right; col += 1) {\n for (let row = rect.top; row < rect.bottom; row += 1) {\n const left = at(row, col - 1);\n const right = at(row, col);\n if (left !== null && left === right) continue;\n const kind = col === rect.left ? 'left' : col === rect.right ? 'right' : 'insideV';\n add(kind, [[left, 'borderRight'], [right, 'borderLeft']]);\n }\n }\n return edges;\n};\n\nconst sideOf = (doc, { pos, attr }) => doc.nodeAt(pos)?.attrs?.[attr] ?? null;\n\n// Like CSS border-collapse: an unset side draws the default border and wins over \"none\".\nconst isVisible = (doc, members) => members.some((m) => sideOf(doc, m) !== 'none');\n\nconst kindOn = (doc, list) => list.length > 0 && list.every((members) => isVisible(doc, members));\n\nexport const getTableBorderState = (state) => {\n const edges = collectEdges(state);\n if (!edges) return null;\n const on = Object.fromEntries(KINDS.map((k) => [k, kindOn(state.doc, edges[k])]));\n const exists = Object.fromEntries(KINDS.map((k) => [k, edges[k].length > 0]));\n const present = KINDS.filter((k) => exists[k]);\n const allOff = KINDS.every((k) => edges[k].every((members) => !isVisible(state.doc, members)));\n const modeOn = (mode) => {\n if (mode === 'none') return allOff;\n const kinds = BORDER_MODES[mode].filter((k) => exists[k]);\n return kinds.length > 0 && kinds.every((k) => on[k]);\n };\n return {\n ...Object.fromEntries(Object.keys(BORDER_MODES).map((m) => [m, modeOn(m)])),\n exists,\n hasInside: present.includes('insideH') || present.includes('insideV'),\n };\n};\n\nconst edgeStyle = (doc, members) => {\n const explicit = members.map((m) => sideOf(doc, m)).find((v) => v && v !== 'none');\n return explicit || DEFAULT_BORDER;\n};\n\nexport const TableBorders = Extension.create({\n name: 'tableBorders',\n\n addCommands() {\n return {\n setTableBorders:\n (mode) =>\n ({ state, tr, dispatch }) => {\n if (!BORDER_MODES[mode]) return false;\n const edges = collectEdges(state);\n if (!edges) return false;\n const kinds = BORDER_MODES[mode].filter((k) => edges[k].length);\n if (!kinds.length) return false;\n const lists = kinds.flatMap((k) => edges[k]);\n const turnOn =\n mode === 'none'\n ? false\n : APPLY_ONLY.includes(mode) || !kinds.every((k) => kindOn(state.doc, edges[k]));\n\n const updates = new Map();\n lists.forEach((members) => {\n const value = turnOn ? edgeStyle(state.doc, members) : 'none';\n members.forEach(({ pos, attr }) => {\n updates.set(pos, { ...(updates.get(pos) || {}), [attr]: value });\n });\n });\n if (!dispatch) return true;\n updates.forEach((attrs, pos) => {\n const node = tr.doc.nodeAt(pos);\n if (node) tr.setNodeMarkup(pos, undefined, { ...node.attrs, ...attrs });\n });\n dispatch(tr);\n return true;\n },\n };\n },\n});\n","const RULE_RE = /([^{}@]+)\\{([^{}]*)\\}/g;\n\nconst stripComments = (css) => css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\nconst removeAtRules = (css) => {\n let out = '';\n let i = 0;\n while (i < css.length) {\n const at = css.indexOf('@', i);\n if (at < 0) {\n out += css.slice(i);\n break;\n }\n out += css.slice(i, at);\n let depth = 0;\n let j = at;\n for (; j < css.length; j += 1) {\n const ch = css[j];\n if (ch === ';' && depth === 0) break;\n if (ch === '{') depth += 1;\n if (ch === '}') {\n depth -= 1;\n if (depth === 0) break;\n }\n }\n i = j + 1;\n }\n return out;\n};\n\nexport const parseStyleRules = (cssText) => {\n const css = removeAtRules(stripComments(cssText || '').replace(/<!--|-->/g, ''));\n const rules = [];\n let match;\n RULE_RE.lastIndex = 0;\n while ((match = RULE_RE.exec(css))) {\n const declarations = match[2].trim();\n if (!declarations) continue;\n match[1]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .forEach((selector) => rules.push({ selector, declarations }));\n }\n return rules;\n};\n\n// Word and Excel put most formatting in a <style> block keyed by class\n// (MsoNormal, xl65...). Inline it so the editor schema can see it.\nexport const inlineStyleRules = (doc) => {\n const styleEls = Array.from(doc.querySelectorAll('style'));\n if (!styleEls.length) return;\n const rules = styleEls.flatMap((el) => parseStyleRules(el.textContent));\n const collected = new Map();\n rules.forEach(({ selector, declarations }) => {\n if (/[:]{1,2}[a-z-]+/i.test(selector.replace(/\\\\:/g, ''))) return;\n let nodes;\n try {\n nodes = doc.body.querySelectorAll(selector);\n } catch (e) {\n return;\n }\n nodes.forEach((node) => {\n collected.set(node, `${collected.get(node) || ''}${declarations};`);\n });\n });\n collected.forEach((declarations, node) => {\n const own = node.getAttribute('style') || '';\n node.setAttribute('style', `${declarations}${own}`);\n });\n styleEls.forEach((el) => el.remove());\n};\n","const MSO_LIST_RE = /mso-list\\s*:\\s*(l\\d+)\\s+level(\\d+)/i;\nconst ORDERED_MARKER_RE = /^\\(?([0-9]+|[a-z]|[ivxlcdm]+)[.)]$/i;\n\nconst getStyleAttr = (el) => el.getAttribute('style') || '';\n\nconst isIgnoreSpan = (el) =>\n el.nodeType === 1 && /mso-list\\s*:\\s*ignore/i.test(getStyleAttr(el));\n\nconst takeMarker = (p) => {\n const ignore = Array.from(p.querySelectorAll('span')).find(isIgnoreSpan);\n if (!ignore) return '';\n const text = (ignore.textContent || '').replace(/ /g, ' ').trim();\n let target = ignore;\n while (\n target.parentElement &&\n target.parentElement !== p &&\n (target.parentElement.textContent || '').trim() === (ignore.textContent || '').trim()\n ) {\n target = target.parentElement;\n }\n target.remove();\n return text;\n};\n\nconst listTypeFor = (marker) => {\n const m = marker.match(ORDERED_MARKER_RE);\n if (!m) return { tag: 'ul' };\n const token = m[1];\n if (/^\\d+$/.test(token)) return { tag: 'ol', type: '1', start: parseInt(token, 10) };\n if (/^[ivxlcdm]+$/.test(token) && token.length > 1) {\n return { tag: 'ol', type: token === token.toLowerCase() ? 'i' : 'I' };\n }\n if (/^[a-z]$/.test(token)) return { tag: 'ol', type: 'a', start: token.charCodeAt(0) - 96 };\n return { tag: 'ol', type: 'A', start: token.charCodeAt(0) - 64 };\n};\n\nconst LIST_STYLE_PROPS = ['margin-left', 'text-indent', 'margin'];\n\nconst cleanListParagraphStyle = (p) => {\n const kept = getStyleAttr(p)\n .split(';')\n .filter((decl) => {\n const prop = decl.split(':')[0]?.trim().toLowerCase();\n return prop && !LIST_STYLE_PROPS.includes(prop) && !prop.startsWith('mso-');\n });\n if (kept.length) p.setAttribute('style', kept.join(';'));\n else p.removeAttribute('style');\n};\n\nconst isListParagraph = (el) =>\n el?.nodeType === 1 && el.tagName === 'P' && MSO_LIST_RE.test(getStyleAttr(el));\n\nconst buildList = (doc, items) => {\n const root = { level: 0, el: null, children: [] };\n const stack = [];\n items.forEach(({ level, info, p }) => {\n while (stack.length && stack[stack.length - 1].level > level) stack.pop();\n let current = stack[stack.length - 1];\n if (!current || current.level < level) {\n const listEl = doc.createElement(info.tag);\n if (info.type && info.type !== '1') listEl.setAttribute('type', info.type);\n if (info.start && info.start !== 1) listEl.setAttribute('start', String(info.start));\n const parentLi = current?.lastLi;\n if (parentLi) parentLi.appendChild(listEl);\n else root.children.push(listEl);\n current = { level, el: listEl, lastLi: null };\n stack.push(current);\n }\n const li = doc.createElement('li');\n cleanListParagraphStyle(p);\n li.appendChild(p);\n current.el.appendChild(li);\n current.lastLi = li;\n });\n return root.children;\n};\n\n// Word exports lists as <p style=\"mso-list:l0 level1 lfo1\"> with the bullet\n// drawn as text. Rebuild them as real nested <ul>/<ol>.\nexport const convertWordLists = (doc, container = doc.body) => {\n const children = Array.from(container.children);\n let i = 0;\n while (i < children.length) {\n const el = children[i];\n if (!isListParagraph(el)) {\n if (el.children?.length && !['P', 'UL', 'OL'].includes(el.tagName)) {\n convertWordLists(doc, el);\n }\n i += 1;\n continue;\n }\n const items = [];\n const anchor = el;\n let j = i;\n let listId = null;\n while (j < children.length && isListParagraph(children[j])) {\n const p = children[j];\n const [, id, levelStr] = getStyleAttr(p).match(MSO_LIST_RE);\n if (listId && id !== listId && parseInt(levelStr, 10) === 1) break;\n listId = listId || id;\n const marker = takeMarker(p);\n items.push({ level: parseInt(levelStr, 10), info: listTypeFor(marker), p });\n j += 1;\n }\n const placeholder = doc.createElement('span');\n container.insertBefore(placeholder, anchor);\n buildList(doc, items).forEach((list) => container.insertBefore(list, placeholder));\n placeholder.remove();\n i = j;\n }\n};\n","import { inlineStyleRules } from './styleSheet';\nimport { convertWordLists } from './wordLists';\n\nconst REMOVE_TAGS = ['meta', 'link', 'script', 'title', 'xml', 'head', 'object', 'embed', 'iframe'];\n\nconst DROP_STYLE_PROPS = [\n 'tab-stops',\n 'layout-grid-mode',\n 'text-autospace',\n 'text-justify',\n 'punctuation-wrap',\n 'word-break',\n 'page-break-before',\n 'page-break-after',\n 'page-break-inside',\n 'break-before',\n 'break-after',\n 'font-variant-ligatures',\n 'font-variant-caps',\n 'font-variant-east-asian',\n 'font-variant-numeric',\n 'orphans',\n 'widows',\n 'white-space',\n 'caret-color',\n 'text-decoration-thickness',\n 'text-decoration-style',\n 'text-decoration-color',\n '-webkit-text-stroke-width',\n 'letter-spacing',\n 'word-spacing',\n];\n\n// Formatting Excel/Word set on the cell itself; marks only live on inline\n// content, so move it onto a wrapper span inside the cell.\nconst CELL_TEXT_PROPS = ['color', 'font-weight', 'font-style', 'font-size', 'font-family', 'text-decoration'];\n\nexport const isWordHtml = (html) =>\n /urn:schemas-microsoft-com:office|class=\"?Mso|mso-[a-z-]+\\s*:|<o:p>|ProgId\"? content=\"?(Word|Excel)/i.test(\n html || '',\n );\n\nconst filterDeclarations = (style) =>\n style\n .split(';')\n .map((d) => d.trim())\n .filter(Boolean)\n .filter((decl) => {\n const idx = decl.indexOf(':');\n if (idx < 1) return false;\n const prop = decl.slice(0, idx).trim().toLowerCase();\n if (prop.startsWith('mso-') || prop.startsWith('-ms-')) return false;\n return !DROP_STYLE_PROPS.includes(prop);\n })\n .map((decl) =>\n decl\n .replace(/\\bwindowtext\\b/gi, '#000000')\n .replace(/(\\d)\\.0+(?=[a-z%])/gi, '$1')\n .replace(/\\bauto\\b(?=\\s*$)/i, ''),\n )\n .filter((decl) => !/:\\s*$/.test(decl));\n\nconst cleanStyleAttr = (el) => {\n const style = el.getAttribute('style');\n if (style === null) return;\n const kept = filterDeclarations(style);\n if (kept.length) el.setAttribute('style', kept.join('; '));\n else el.removeAttribute('style');\n};\n\nconst unwrap = (el) => {\n const parent = el.parentNode;\n if (!parent) return;\n while (el.firstChild) parent.insertBefore(el.firstChild, el);\n parent.removeChild(el);\n};\n\nconst removeComments = (root) => {\n const walker = root.ownerDocument.createTreeWalker(root, 128);\n const comments = [];\n while (walker.nextNode()) comments.push(walker.currentNode);\n comments.forEach((c) => c.remove());\n};\n\nconst isNamespaced = (el) => el.tagName.includes(':');\n\nconst appendStyle = (el, decl) => {\n const own = el.getAttribute('style');\n el.setAttribute('style', own ? `${own.replace(/;?\\s*$/, '')}; ${decl}` : decl);\n};\n\nconst moveAlignAttr = (el) => {\n const align = el.getAttribute('align');\n if (!align) return;\n if (!/text-align/i.test(el.getAttribute('style') || '')) {\n appendStyle(el, `text-align: ${align.toLowerCase()}`);\n }\n el.removeAttribute('align');\n};\n\nconst convertFontTag = (doc, el) => {\n const span = doc.createElement('span');\n const decls = [];\n if (el.getAttribute('color')) decls.push(`color: ${el.getAttribute('color')}`);\n if (el.getAttribute('face')) decls.push(`font-family: ${el.getAttribute('face')}`);\n const own = el.getAttribute('style');\n if (own) decls.push(own);\n if (decls.length) span.setAttribute('style', decls.join('; '));\n while (el.firstChild) span.appendChild(el.firstChild);\n el.replaceWith(span);\n};\n\nconst wrapCellText = (doc, cell) => {\n const style = cell.getAttribute('style') || '';\n const moved = [];\n const kept = [];\n style\n .split(';')\n .map((d) => d.trim())\n .filter(Boolean)\n .forEach((decl) => {\n const prop = decl.split(':')[0].trim().toLowerCase();\n (CELL_TEXT_PROPS.includes(prop) ? moved : kept).push(decl);\n });\n if (!moved.length) return;\n const span = doc.createElement('span');\n span.setAttribute('style', moved.join('; '));\n const blocks = cell.querySelectorAll('p, div, h1, h2, h3, h4, h5, h6, li');\n if (blocks.length) {\n blocks.forEach((block) => {\n const inner = span.cloneNode(false);\n while (block.firstChild) inner.appendChild(block.firstChild);\n block.appendChild(inner);\n });\n } else {\n while (cell.firstChild) span.appendChild(cell.firstChild);\n cell.appendChild(span);\n }\n if (kept.length) cell.setAttribute('style', kept.join('; '));\n else cell.removeAttribute('style');\n};\n\nconst cellWidthFromStyle = (cell) => {\n if (cell.getAttribute('colwidth')) return;\n const width = cell.getAttribute('width');\n const styleWidth = (cell.getAttribute('style') || '').match(/(?:^|;)\\s*width\\s*:\\s*([^;]+)/i)?.[1];\n const value = styleWidth || (width && /^\\d+(\\.\\d+)?$/.test(width) ? `${width}px` : null);\n if (value) cell.setAttribute('data-width', value.trim());\n};\n\nconst isEmptyInline = (el) =>\n !el.attributes.length || (el.attributes.length === 1 && el.hasAttribute('lang'));\n\nconst cleanElement = (doc, el, word) => {\n const tag = el.tagName.toLowerCase();\n if (tag === 'font') return convertFontTag(doc, el);\n if (isNamespaced(el)) {\n if (tag === 'o:p' && !el.textContent) return el.remove();\n return unwrap(el);\n }\n if (tag === 'img') {\n const src = el.getAttribute('src') || '';\n if (/^(file|cid|blob):/i.test(src) || !src) return el.remove();\n }\n if (word && el.hasAttribute('v:shapes')) el.removeAttribute('v:shapes');\n ['p', 'div', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) && moveAlignAttr(el);\n if (tag === 'td' || tag === 'th') cellWidthFromStyle(el);\n cleanStyleAttr(el);\n if (tag === 'td' || tag === 'th') wrapCellText(doc, el);\n if (word) {\n el.removeAttribute('class');\n el.removeAttribute('lang');\n }\n if (tag === 'b' && /docs-internal-guid/.test(el.id || '')) return unwrap(el);\n if (tag === 'span' && isEmptyInline(el)) return unwrap(el);\n return undefined;\n};\n\nconst walk = (doc, root, word) => {\n Array.from(root.children).forEach((child) => {\n walk(doc, child, word);\n cleanElement(doc, child, word);\n });\n};\n\n// A table with border=\"0\" draws no cell borders in a browser; make that\n// explicit so the editor and the PDF don't fall back to default borders.\nconst applyBorderlessTables = (doc) => {\n doc.body.querySelectorAll('table').forEach((table) => {\n const attr = table.getAttribute('border');\n const style = (table.getAttribute('style') || '').toLowerCase();\n const noBorder =\n attr === '0' || /(^|;)\\s*border\\s*:\\s*(none|0(px)?)\\s*(;|$)/.test(style);\n if (!noBorder) return;\n Array.from(table.rows || []).forEach((row) =>\n Array.from(row.cells || []).forEach((cell) => {\n if (!/border/i.test(cell.getAttribute('style') || '')) appendStyle(cell, 'border: none');\n }),\n );\n });\n};\n\nconst parse = (html) => new DOMParser().parseFromString(html, 'text/html');\n\nexport const cleanHtml = (html) => {\n if (!html || typeof html !== 'string') return html || '';\n if (typeof DOMParser === 'undefined') return html;\n const word = isWordHtml(html);\n const fragmentMatch = html.match(/<!--StartFragment-->([\\s\\S]*?)<!--EndFragment-->/);\n const doc = parse(html);\n if (fragmentMatch && doc.querySelectorAll('style').length === 0) {\n doc.body.innerHTML = fragmentMatch[1];\n }\n inlineStyleRules(doc);\n if (!word) applyBorderlessTables(doc);\n if (word) convertWordLists(doc);\n removeComments(doc.body);\n REMOVE_TAGS.forEach((t) => doc.body.querySelectorAll(t).forEach((el) => el.remove()));\n walk(doc, doc.body, word);\n return doc.body.innerHTML;\n};\n","const BULLETS = ['•', '◦', '▪'];\n\nconst toAlpha = (n) => {\n let s = '';\n let x = n;\n while (x > 0) {\n const r = (x - 1) % 26;\n s = String.fromCharCode(97 + r) + s;\n x = Math.floor((x - 1) / 26);\n }\n return s;\n};\n\nconst ROMAN = [\n [1000, 'm'],\n [900, 'cm'],\n [500, 'd'],\n [400, 'cd'],\n [100, 'c'],\n [90, 'xc'],\n [50, 'l'],\n [40, 'xl'],\n [10, 'x'],\n [9, 'ix'],\n [5, 'v'],\n [4, 'iv'],\n [1, 'i'],\n];\n\nconst toRoman = (n) => {\n let x = n;\n return ROMAN.reduce((acc, [v, s]) => {\n let out = acc;\n while (x >= v) {\n out += s;\n x -= v;\n }\n return out;\n }, '');\n};\n\nexport const formatNumber = (n, type) => {\n switch (type) {\n case 'a':\n return toAlpha(n);\n case 'A':\n return toAlpha(n).toUpperCase();\n case 'i':\n return toRoman(n);\n case 'I':\n return toRoman(n).toUpperCase();\n default:\n return String(n);\n }\n};\n\nexport const listMarker = (listNode, index, depth = 0, bullets = BULLETS) => {\n if (listNode.type === 'orderedList') {\n const start = listNode.attrs?.start ?? 1;\n return `${formatNumber(start + index, listNode.attrs?.type)}.`;\n }\n return bullets[depth % bullets.length];\n};\n","import { listMarker } from '../utils/listMarkers';\n\nconst inlineText = (node) => {\n if (node.type === 'text') return node.text || '';\n if (node.type === 'hardBreak') return '\\n';\n return (node.content || []).map(inlineText).join('');\n};\n\nconst blockToLines = (node, depth = 0) => {\n const pad = ' '.repeat(depth);\n switch (node.type) {\n case 'paragraph':\n case 'heading':\n return [inlineText(node)];\n case 'bulletList':\n case 'orderedList':\n return (node.content || []).flatMap((item, index) => {\n const marker = listMarker(node, index, depth);\n const [first = '', ...rest] = (item.content || []).flatMap((child) =>\n blockToLines(child, child.type.endsWith('List') ? depth + 1 : depth),\n );\n return [`${pad}${marker} ${first}`, ...rest];\n });\n case 'table':\n return (node.content || []).map((row) =>\n (row.content || [])\n .map((cell) =>\n (cell.content || []).flatMap((c) => blockToLines(c, 0)).join(' ').trim(),\n )\n .join('\\t'),\n );\n case 'blockquote':\n return (node.content || []).flatMap((c) => blockToLines(c, depth));\n case 'horizontalRule':\n return ['---'];\n case 'image':\n return [];\n default:\n return node.content ? node.content.flatMap((c) => blockToLines(c, depth)) : [];\n }\n};\n\nexport const jsonToText = (json) =>\n (json?.content || [])\n .flatMap((node) => blockToLines(node))\n .join('\\n')\n .replace(/ /g, ' ');\n","export const STANDARD_FONTS = [\n 'Helvetica',\n 'Helvetica-Bold',\n 'Helvetica-Oblique',\n 'Helvetica-BoldOblique',\n 'Times-Roman',\n 'Times-Bold',\n 'Times-Italic',\n 'Times-BoldItalic',\n 'Courier',\n 'Courier-Bold',\n 'Courier-Oblique',\n 'Courier-BoldOblique',\n];\n\nexport const DEFAULT_PDF_OPTIONS = {\n // Base text size in pt; headings scale from it. Only set on the output\n // when passed explicitly, otherwise the surrounding react-pdf font size wins.\n fontSize: 10,\n // Drop font sizes stored in the content (like the old removeFontSize helper).\n ignoreFontSizes: false,\n fontFamily: null,\n color: null,\n lineHeight: null,\n // react-pdf throws on fonts that are not registered, so a CSS font-family\n // is only kept when it is in `fonts` (registered names) or `fontMap`.\n fonts: [],\n fontMap: {},\n // Unknown families fall back to inheriting the surrounding font.\n monospaceFont: 'Courier',\n paragraphSpacing: 4,\n listItemSpacing: 1,\n headingScale: { 1: 2, 2: 1.6, 3: 1.3, 4: 1.15 },\n headingSpacing: { top: 6, bottom: 4 },\n listIndent: 14,\n bullets: ['•', '•', '•'],\n tableBorder: '0.75pt solid #000000',\n cellPadding: { vertical: 2, horizontal: 4 },\n linkColor: '#2d5cf2',\n // Keep table rows on one page.\n keepRowsTogether: true,\n // Per-node style overrides merged last, e.g. { paragraph: { color: '#333' } }.\n styles: {},\n};\n\nexport const resolveOptions = (options = {}) => ({\n ...DEFAULT_PDF_OPTIONS,\n ...options,\n explicitFontSize: options.fontSize !== undefined && options.fontSize !== null,\n headingScale: { ...DEFAULT_PDF_OPTIONS.headingScale, ...(options.headingScale || {}) },\n headingSpacing: { ...DEFAULT_PDF_OPTIONS.headingSpacing, ...(options.headingSpacing || {}) },\n cellPadding: { ...DEFAULT_PDF_OPTIONS.cellPadding, ...(options.cellPadding || {}) },\n styles: options.styles || {},\n});\n\nconst cleanFamily = (name) => name.trim().replace(/^[\"']|[\"']$/g, '').trim();\n\nexport const resolveFontFamily = (cssValue, opts) => {\n if (!cssValue) return null;\n const allowed = new Map(\n [...(opts.fonts || []), ...STANDARD_FONTS].map((f) => [f.toLowerCase(), f]),\n );\n const map = Object.fromEntries(\n Object.entries(opts.fontMap || {}).map(([k, v]) => [k.toLowerCase(), v]),\n );\n const candidates = String(cssValue).split(',').map(cleanFamily).filter(Boolean);\n for (const name of candidates) {\n const key = name.toLowerCase();\n if (map[key]) return map[key];\n if (allowed.has(key)) return allowed.get(key);\n }\n return null;\n};\n","const NAMED = {\n black: '#000000',\n white: '#ffffff',\n red: '#ff0000',\n green: '#008000',\n blue: '#0000ff',\n yellow: '#ffff00',\n gray: '#808080',\n grey: '#808080',\n silver: '#c0c0c0',\n maroon: '#800000',\n navy: '#000080',\n teal: '#008080',\n olive: '#808000',\n purple: '#800080',\n orange: '#ffa500',\n lime: '#00ff00',\n aqua: '#00ffff',\n cyan: '#00ffff',\n fuchsia: '#ff00ff',\n magenta: '#ff00ff',\n};\n\nconst hex2 = (n) => Math.max(0, Math.min(255, Math.round(Number(n)))).toString(16).padStart(2, '0');\n\n// Normalises any CSS colour string to #rrggbb, or null when it is\n// transparent / not something a PDF can draw.\nexport const toHexColor = (value) => {\n if (!value) return null;\n const str = String(value).trim().toLowerCase();\n if (!str || str === 'transparent' || str === 'inherit' || str === 'initial' || str === 'auto') return null;\n if (/^#[0-9a-f]{6}$/.test(str)) return str;\n if (/^#[0-9a-f]{3}$/.test(str)) return `#${str[1]}${str[1]}${str[2]}${str[2]}${str[3]}${str[3]}`;\n if (/^#[0-9a-f]{8}$/.test(str)) return str.slice(0, 7);\n const m = str.match(/^rgba?\\(\\s*([\\d.]+)[\\s,]+([\\d.]+)[\\s,]+([\\d.]+)(?:[\\s,/]+([\\d.]+%?))?\\s*\\)$/);\n if (m) {\n if (m[4] !== undefined && parseFloat(m[4]) === 0) return null;\n return `#${hex2(m[1])}${hex2(m[2])}${hex2(m[3])}`;\n }\n if (str === 'windowtext' || str === 'currentcolor') return '#000000';\n return NAMED[str] || null;\n};\n","import { toPt } from '../utils/units';\nimport { toHexColor } from '../utils/colors';\nimport { resolveFontFamily } from './options';\n\nconst SCRIPT_RATIO = 0.7;\n\nconst decorations = (marks) => {\n const parts = [];\n if (marks.some((m) => m.type === 'underline' || m.type === 'link')) parts.push('underline');\n if (marks.some((m) => m.type === 'strike')) parts.push('line-through');\n return parts.length ? parts.join(' ') : null;\n};\n\nexport const markStyle = (marks = [], ctx, opts) => {\n const style = {};\n let fontSize = null;\n marks.forEach((mark) => {\n const a = mark.attrs || {};\n switch (mark.type) {\n case 'bold':\n style.fontWeight = 'bold';\n break;\n case 'italic':\n style.fontStyle = 'italic';\n break;\n case 'code':\n style.fontFamily = opts.monospaceFont;\n break;\n case 'link':\n style.color = opts.linkColor;\n break;\n case 'textStyle': {\n const color = toHexColor(a.color);\n if (color) style.color = color;\n const bg = toHexColor(a.backgroundColor);\n if (bg) style.backgroundColor = bg;\n const pt = toPt(a.fontSize, (ctx.fontSize * 4) / 3);\n if (pt && !opts.ignoreFontSizes) fontSize = pt;\n const family = resolveFontFamily(a.fontFamily, opts);\n if (family) style.fontFamily = family;\n break;\n }\n default:\n break;\n }\n });\n const textDecoration = decorations(marks);\n if (textDecoration) style.textDecoration = textDecoration;\n const script = marks.find((m) => m.type === 'subscript' || m.type === 'superscript');\n if (script) {\n style.verticalAlign = script.type === 'subscript' ? 'sub' : 'super';\n fontSize = (fontSize || ctx.fontSize) * SCRIPT_RATIO;\n }\n if (fontSize) style.fontSize = Math.round(fontSize * 100) / 100;\n return style;\n};\n\nconst isEmptyStyle = (style) => !Object.keys(style).length;\n\nexport const convertInline = (nodes = [], ctx, opts) => {\n const out = [];\n nodes.forEach((node) => {\n if (node.type === 'hardBreak') {\n out.push('\\n');\n return;\n }\n if (node.type !== 'text' || !node.text) return;\n const style = markStyle(node.marks, ctx, opts);\n const textNode = isEmptyStyle(style)\n ? node.text\n : { type: 'text', style: { ...style, ...(opts.styles.text || {}) }, children: [node.text] };\n const link = node.marks?.find((m) => m.type === 'link');\n if (link?.attrs?.href) {\n out.push({\n type: 'link',\n src: link.attrs.href,\n style: { ...(opts.styles.link || {}) },\n children: [textNode],\n });\n } else {\n out.push(textNode);\n }\n });\n return out;\n};\n","import { toHexColor } from '../utils/colors';\nimport { parseBorders, formatBorder } from '../utils/borders';\nimport { pxToPt, round, toPx } from '../utils/units';\n\nconst PDF_BORDER_STYLES = ['solid', 'dashed', 'dotted'];\n\nexport const borderToPdf = (value) => {\n if (!value || value === 'none') return null;\n const side = parseBorders(`border-top: ${value}`).top;\n const formatted = formatBorder(side);\n if (!formatted || formatted === 'none') return null;\n const [width, style] = formatted.split(' ');\n const pt = Math.max(pxToPt(toPx(width) || 1), 0.25);\n const color = toHexColor(side.color) || '#000000';\n return `${pt}pt ${PDF_BORDER_STYLES.includes(style) ? style : 'solid'} ${color}`;\n};\n\nconst buildGrid = (rows) => {\n const occupied = [];\n const placements = [];\n let numCols = 0;\n rows.forEach((row, r) => {\n occupied[r] = occupied[r] || [];\n let c = 0;\n (row.content || []).forEach((cell) => {\n while (occupied[r][c]) c += 1;\n const colspan = cell.attrs?.colspan || 1;\n const rowspan = cell.attrs?.rowspan || 1;\n const placement = { cell, r, c, colspan, rowspan };\n placements.push(placement);\n for (let dr = 0; dr < rowspan; dr += 1) {\n occupied[r + dr] = occupied[r + dr] || [];\n for (let dc = 0; dc < colspan; dc += 1) occupied[r + dr][c + dc] = placement;\n }\n c += colspan;\n numCols = Math.max(numCols, c);\n });\n });\n return { occupied: occupied.slice(0, rows.length), placements, numCols };\n};\n\nconst columnWidths = (placements, numCols) => {\n const widths = Array(numCols).fill(null);\n placements.forEach(({ cell, c, colspan }) => {\n const cw = cell.attrs?.colwidth;\n if (!Array.isArray(cw)) return;\n for (let i = 0; i < colspan; i += 1) {\n if (widths[c + i] === null && cw[i]) widths[c + i] = cw[i];\n }\n });\n const known = widths.filter((w) => w !== null);\n const complete = known.length === numCols;\n const fallback = known.length ? known.reduce((a, b) => a + b, 0) / known.length : 100;\n const filled = widths.map((w) => (w === null ? fallback : w));\n const total = filled.reduce((a, b) => a + b, 0) || 1;\n return {\n percents: filled.map((w) => (w / total) * 100),\n totalPt: complete ? pxToPt(total) : null,\n };\n};\n\nconst VALIGN = { middle: 'center', bottom: 'flex-end', top: 'flex-start' };\n\n// Mirrors CSS border-collapse: each shared edge is drawn once, by the cell\n// above or to the left; a visible side wins, and an unset side beats \"none\".\nconst resolveEdge = (own, other, hasNeighbour, opts) => {\n const visible = [own, other].find((v) => v && v !== 'none');\n if (visible) return borderToPdf(visible);\n if (!own || (hasNeighbour && !other)) return opts.tableBorder;\n return null;\n};\n\nconst cellBorders = (p, r, c, occupied, opts) => {\n const attrs = p.cell.attrs || {};\n const right = occupied[r]?.[c + p.colspan];\n const below = occupied[p.r + p.rowspan]?.[c];\n const style = {\n borderTop: p.r === 0 ? resolveEdge(attrs.borderTop, null, false, opts) : null,\n borderLeft: c === 0 ? resolveEdge(attrs.borderLeft, null, false, opts) : null,\n borderRight: resolveEdge(attrs.borderRight, right?.cell.attrs?.borderLeft, !!right, opts),\n borderBottom: resolveEdge(attrs.borderBottom, below?.cell.attrs?.borderTop, !!below, opts),\n };\n return Object.fromEntries(Object.entries(style).filter(([, v]) => v));\n};\n\nconst pct = (n) => `${round(n, 4)}%`;\n\nexport const convertTable = (node, ctx, opts, convertBlocks) => {\n const rows = node.content || [];\n if (!rows.length) return null;\n const { occupied, numCols, placements } = buildGrid(rows);\n const { percents, totalPt } = columnWidths(placements, numCols);\n const { vertical, horizontal } = opts.cellPadding;\n\n const rowNodes = occupied.map((slots, r) => {\n const children = [];\n for (let c = 0; c < numCols; c += 1) {\n const p = slots?.[c];\n if (!p) {\n children.push({ type: 'view', style: { width: pct(percents[c]) }, children: [] });\n continue;\n }\n if (p.c !== c) continue;\n const width = pct(percents.slice(c, c + p.colspan).reduce((a, b) => a + b, 0));\n const attrs = p.cell.attrs || {};\n const borders = cellBorders(p, r, c, occupied, opts);\n const bg = toHexColor(attrs.backgroundColor);\n const isStart = p.r === r;\n const isEnd = p.r + p.rowspan - 1 === r;\n const style = {\n width,\n paddingTop: isStart ? vertical : 0,\n paddingBottom: isEnd ? vertical : 0,\n paddingLeft: horizontal,\n paddingRight: horizontal,\n ...(bg ? { backgroundColor: bg } : {}),\n ...(borders.borderLeft ? { borderLeft: borders.borderLeft } : {}),\n ...(borders.borderRight ? { borderRight: borders.borderRight } : {}),\n ...(isStart && borders.borderTop ? { borderTop: borders.borderTop } : {}),\n ...(isEnd && borders.borderBottom ? { borderBottom: borders.borderBottom } : {}),\n justifyContent: VALIGN[attrs.verticalAlign] || 'flex-start',\n ...(opts.styles[p.cell.type] || {}),\n };\n const content = isStart\n ? convertBlocks(p.cell.content || [], {\n ...ctx,\n inCell: true,\n align: attrs.align || null,\n bold: p.cell.type === 'tableHeader',\n })\n : [];\n children.push({ type: 'view', style, children: content });\n }\n return {\n type: 'view',\n style: { flexDirection: 'row', ...(opts.styles.tableRow || {}) },\n props: opts.keepRowsTogether ? { wrap: false } : undefined,\n children,\n };\n });\n\n return {\n type: 'view',\n style: {\n flexDirection: 'column',\n width: totalPt ? `${totalPt}pt` : '100%',\n maxWidth: '100%',\n marginBottom: ctx.inCell ? 2 : opts.paragraphSpacing,\n ...(opts.styles.table || {}),\n },\n children: rowNodes,\n };\n};\n","import { pxToPt } from '../utils/units';\nimport { listMarker } from '../utils/listMarkers';\nimport { convertInline } from './inline';\nimport { resolveOptions } from './options';\nimport { convertTable } from './table';\n\nexport const PDF_TREE_VERSION = 1;\n\nconst paragraphStyle = (attrs = {}, ctx, opts, base = {}) => {\n const style = { ...base };\n const align = attrs.textAlign || ctx.align;\n if (align && align !== 'left') style.textAlign = align;\n if (attrs.marginLeft) style.marginLeft = pxToPt(attrs.marginLeft);\n if (attrs.textIndent) {\n const indent = pxToPt(attrs.textIndent);\n style.textIndent = Math.max(indent, -(style.marginLeft || 0));\n }\n if (attrs.marginTop) style.marginTop = pxToPt(attrs.marginTop);\n if (attrs.marginBottom !== null && attrs.marginBottom !== undefined) {\n style.marginBottom = pxToPt(attrs.marginBottom);\n }\n const lineHeight = attrs.lineHeight || opts.lineHeight;\n if (lineHeight) style.lineHeight = lineHeight;\n if (ctx.bold) style.fontWeight = 'bold';\n return style;\n};\n\nconst textBlock = (node, ctx, opts, base) => {\n const children = convertInline(node.content, ctx, opts);\n return {\n type: 'text',\n style: paragraphStyle(node.attrs, ctx, opts, base),\n children: children.length ? children : [' '],\n };\n};\n\nconst defaultSpacing = (ctx, opts) => {\n if (ctx.inCell) return 0;\n if (ctx.inList) return opts.listItemSpacing;\n return opts.paragraphSpacing;\n};\n\nconst convertList = (node, ctx, opts, convertBlocks) => {\n const depth = ctx.listDepth || 0;\n const items = (node.content || []).map((item, index) => {\n const marker = listMarker(node, index, depth, opts.bullets);\n return {\n type: 'view',\n style: { flexDirection: 'row', ...(opts.styles.listItem || {}) },\n children: [\n {\n type: 'text',\n style: { width: opts.listIndent, ...(opts.styles.listMarker || {}) },\n children: [marker],\n },\n {\n type: 'view',\n style: { flex: 1 },\n children: convertBlocks(item.content || [], {\n ...ctx,\n inList: true,\n listDepth: depth + 1,\n }),\n },\n ],\n };\n });\n return {\n type: 'view',\n style: {\n marginBottom: depth ? 0 : defaultSpacing({ ...ctx, inList: false }, opts),\n ...(opts.styles.list || {}),\n },\n children: items,\n };\n};\n\nconst convertBlock = (node, ctx, opts, convertBlocks) => {\n switch (node.type) {\n case 'paragraph':\n return textBlock(node, ctx, opts, {\n marginBottom: defaultSpacing(ctx, opts),\n ...(opts.styles.paragraph || {}),\n });\n case 'heading': {\n const level = node.attrs?.level || 1;\n const fontSize = Math.round(opts.fontSize * (opts.headingScale[level] || 1) * 100) / 100;\n return textBlock(node, { ...ctx, fontSize }, opts, {\n fontSize,\n fontWeight: 'bold',\n marginTop: ctx.inCell ? 0 : opts.headingSpacing.top,\n marginBottom: ctx.inCell ? 0 : opts.headingSpacing.bottom,\n ...(opts.styles.heading || {}),\n ...(opts.styles[`heading${level}`] || {}),\n });\n }\n case 'bulletList':\n case 'orderedList':\n return convertList(node, ctx, opts, convertBlocks);\n case 'table':\n return convertTable(node, ctx, opts, convertBlocks);\n case 'blockquote':\n return {\n type: 'view',\n style: {\n borderLeft: '2pt solid #cccccc',\n paddingLeft: 8,\n marginBottom: defaultSpacing(ctx, opts),\n ...(opts.styles.blockquote || {}),\n },\n children: convertBlocks(node.content || [], ctx),\n };\n case 'horizontalRule':\n return {\n type: 'view',\n style: {\n borderBottom: '0.75pt solid #999999',\n marginVertical: 4,\n ...(opts.styles.horizontalRule || {}),\n },\n children: [],\n };\n case 'image': {\n const { src, width, height } = node.attrs || {};\n if (!src) return null;\n const style = { maxWidth: '100%', marginBottom: defaultSpacing(ctx, opts) };\n if (width) style.width = pxToPt(width);\n if (height) style.height = pxToPt(height);\n return { type: 'image', src, style: { ...style, ...(opts.styles.image || {}) } };\n }\n default:\n return node.content ? { type: 'view', style: {}, children: convertBlocks(node.content, ctx) } : null;\n }\n};\n\n// Converts editor JSON into a plain, serialisable tree that maps 1:1 onto\n// react-pdf primitives (View / Text / Link / Image). Store it, send it to a\n// worker, or render it with renderPdfTree / <RichTextPdf>.\nexport const jsonToPdfTree = (json, options) => {\n const opts = resolveOptions(options);\n const ctx = { fontSize: opts.fontSize };\n const convertBlocks = (nodes, c) =>\n (nodes || []).map((n) => convertBlock(n, c, opts, convertBlocks)).filter(Boolean);\n const rootStyle = opts.explicitFontSize ? { fontSize: opts.fontSize } : {};\n if (opts.fontFamily) rootStyle.fontFamily = opts.fontFamily;\n if (opts.color) rootStyle.color = opts.color;\n return {\n type: 'root',\n version: PDF_TREE_VERSION,\n style: { ...rootStyle, ...(opts.styles.root || {}) },\n children: convertBlocks(json?.content || [], ctx),\n };\n};\n\nexport const isPdfTree = (value) =>\n !!value && typeof value === 'object' && value.type === 'root' && Array.isArray(value.children);\n","import { getSchema } from '@tiptap/core';\nimport { DOMParser as PMDOMParser, DOMSerializer, Node as PMNode } from '@tiptap/pm/model';\nimport { buildSchemaExtensions } from '../extensions';\nimport { cleanHtml } from '../paste/cleanHtml';\nimport { jsonToText } from './text';\n\nlet cachedSchema = null;\n\nexport const getEditorSchema = () => {\n if (!cachedSchema) cachedSchema = getSchema(buildSchemaExtensions({ nodeIds: true }));\n return cachedSchema;\n};\n\nexport const EMPTY_DOC = { type: 'doc', content: [{ type: 'paragraph' }] };\n\nexport const isDocJson = (value) =>\n !!value && typeof value === 'object' && value.type === 'doc';\n\nconst looksLikeHtml = (str) => /<\\/?[a-z][\\s\\S]*>/i.test(str);\n\nconst escapeHtml = (str) =>\n str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\n// Plain text keeps its line breaks instead of collapsing into one paragraph.\nexport const textToHtml = (text) =>\n String(text)\n .split(/\\r?\\n/)\n .map((line) => `<p>${escapeHtml(line)}</p>`)\n .join('');\n\nexport const normalizeHtmlInput = (value) => {\n if (value === null || value === undefined) return '';\n const str = String(value);\n if (!str.trim()) return '';\n return looksLikeHtml(str) ? cleanHtml(str) : textToHtml(str);\n};\n\nexport const htmlToJSON = (html) => {\n const schema = getEditorSchema();\n const clean = normalizeHtmlInput(html);\n if (!clean) return EMPTY_DOC;\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n throw new Error('htmlToJSON needs a DOM (browser, jsdom or happy-dom)');\n }\n const container = document.createElement('div');\n container.innerHTML = clean;\n return PMDOMParser.fromSchema(schema).parse(container).toJSON();\n};\n\nexport const toDocJson = (value) => {\n if (isDocJson(value)) return value;\n return htmlToJSON(value);\n};\n\nexport const jsonToHTML = (json) => {\n const schema = getEditorSchema();\n const node = PMNode.fromJSON(schema, isDocJson(json) ? json : EMPTY_DOC);\n const fragment = DOMSerializer.fromSchema(schema).serializeFragment(node.content);\n const container = document.createElement('div');\n container.appendChild(fragment);\n return container.innerHTML;\n};\n\nexport const htmlToText = (html) => jsonToText(htmlToJSON(html));\n\nexport { jsonToText };\n"]}
@@ -0,0 +1,43 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkCTVYA4A3cjs = require('./chunk-CTVYA4A3.cjs');
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+ var _chunkNNYINC42cjs = require('./chunk-NNYINC42.cjs');
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ exports.DEFAULT_PDF_OPTIONS = _chunkNNYINC42cjs.DEFAULT_PDF_OPTIONS; exports.EMPTY_DOC = _chunkNNYINC42cjs.EMPTY_DOC; exports.PDF_TREE_VERSION = _chunkNNYINC42cjs.PDF_TREE_VERSION; exports.STANDARD_FONTS = _chunkNNYINC42cjs.STANDARD_FONTS; exports.cleanPastedHtml = _chunkNNYINC42cjs.cleanHtml; exports.getEditorSchema = _chunkNNYINC42cjs.getEditorSchema; exports.htmlToJSON = _chunkNNYINC42cjs.htmlToJSON; exports.htmlToText = _chunkNNYINC42cjs.htmlToText; exports.isDocJson = _chunkNNYINC42cjs.isDocJson; exports.isPdfTree = _chunkNNYINC42cjs.isPdfTree; exports.isWordHtml = _chunkNNYINC42cjs.isWordHtml; exports.jsonToHTML = _chunkNNYINC42cjs.jsonToHTML; exports.jsonToPdfTree = _chunkNNYINC42cjs.jsonToPdfTree; exports.jsonToText = _chunkNNYINC42cjs.jsonToText; exports.normalizeHtmlInput = _chunkNNYINC42cjs.normalizeHtmlInput; exports.replaceVariablesInString = _chunkCTVYA4A3cjs.replaceVariablesInString; exports.textToHtml = _chunkNNYINC42cjs.textToHtml; exports.toDocJson = _chunkNNYINC42cjs.toDocJson;
43
+ //# sourceMappingURL=convert.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/harsh/Documents/Flabs/flabs-editor/dist/convert.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,m/BAAC","file":"/Users/harsh/Documents/Flabs/flabs-editor/dist/convert.cjs"}
@@ -0,0 +1,43 @@
1
+ import {
2
+ replaceVariablesInString
3
+ } from "./chunk-DCMBE2J7.js";
4
+ import {
5
+ DEFAULT_PDF_OPTIONS,
6
+ EMPTY_DOC,
7
+ PDF_TREE_VERSION,
8
+ STANDARD_FONTS,
9
+ cleanHtml,
10
+ getEditorSchema,
11
+ htmlToJSON,
12
+ htmlToText,
13
+ isDocJson,
14
+ isPdfTree,
15
+ isWordHtml,
16
+ jsonToHTML,
17
+ jsonToPdfTree,
18
+ jsonToText,
19
+ normalizeHtmlInput,
20
+ textToHtml,
21
+ toDocJson
22
+ } from "./chunk-JQEG2JQ7.js";
23
+ export {
24
+ DEFAULT_PDF_OPTIONS,
25
+ EMPTY_DOC,
26
+ PDF_TREE_VERSION,
27
+ STANDARD_FONTS,
28
+ cleanHtml as cleanPastedHtml,
29
+ getEditorSchema,
30
+ htmlToJSON,
31
+ htmlToText,
32
+ isDocJson,
33
+ isPdfTree,
34
+ isWordHtml,
35
+ jsonToHTML,
36
+ jsonToPdfTree,
37
+ jsonToText,
38
+ normalizeHtmlInput,
39
+ replaceVariablesInString,
40
+ textToHtml,
41
+ toDocJson
42
+ };
43
+ //# sourceMappingURL=convert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}