@notectl/core 0.0.2 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"notectl-core.js","sources":["../src/schema/Schema.ts","../src/schema/NodeFactory.ts","../src/state/EditorState.ts","../src/plugins/PluginManager.ts","../../../node_modules/dompurify/dist/purify.es.mjs","../src/utils/security.ts","../src/utils/accessibility.ts","../src/editor/NotectlEditor.ts","../src/plugins/Plugin.ts","../src/delta/Delta.ts","../src/delta/Operations.ts","../src/delta/Transform.ts","../src/index.ts"],"sourcesContent":["/**\n * Document schema definition for Notectl\n * Defines the structure and validation rules for the document model\n */\n\nimport type { NodeType, BlockNode, TextNode, Node, Mark } from '../types/index.js';\n\n/**\n * Node specification in the schema\n */\nexport interface NodeSpec {\n type: NodeType;\n group?: 'block' | 'inline' | 'table';\n content?: string; // Content expression (e.g., \"block+\", \"inline*\", \"text*\")\n marks?: string; // Allowed marks (e.g., \"_\", \"strong em\")\n attrs?: Record<string, AttributeSpec>;\n defining?: boolean; // Node defines its content boundaries\n isolating?: boolean; // Node isolates content from surroundings\n toDOM?: (node: Node) => HTMLElement | [string, Record<string, string>, ...unknown[]];\n parseDOM?: Array<{\n tag?: string;\n attrs?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Attribute specification\n */\nexport interface AttributeSpec {\n default?: unknown;\n validate?: (value: unknown) => boolean;\n required?: boolean;\n}\n\n/**\n * Mark specification in the schema\n */\nexport interface MarkSpec {\n type: string;\n attrs?: Record<string, AttributeSpec>;\n inclusive?: boolean;\n excludes?: string; // Marks that cannot coexist\n group?: string;\n spanning?: boolean;\n toDOM?: (mark: Mark) => [string, Record<string, string>];\n parseDOM?: Array<{\n tag?: string;\n style?: string;\n attrs?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Document schema\n */\nexport class Schema {\n nodes: Map<NodeType, NodeSpec>;\n marks: Map<string, MarkSpec>;\n topNode: NodeType;\n\n constructor(config: { nodes: NodeSpec[]; marks: MarkSpec[]; topNode?: NodeType }) {\n this.nodes = new Map(config.nodes.map((spec) => [spec.type, spec]));\n this.marks = new Map(config.marks.map((spec) => [spec.type, spec]));\n this.topNode = config.topNode || 'paragraph';\n }\n\n /**\n * Get node specification\n */\n node(type: NodeType): NodeSpec | undefined {\n return this.nodes.get(type);\n }\n\n /**\n * Get mark specification\n */\n mark(type: string): MarkSpec | undefined {\n return this.marks.get(type);\n }\n\n /**\n * Validate if a node conforms to the schema\n */\n validateNode(node: Node): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if ('text' in node) {\n // Text node validation\n const textNode = node as TextNode;\n if (typeof textNode.text !== 'string') {\n errors.push('Text node must have a string text property');\n }\n if (textNode.marks) {\n for (const mark of textNode.marks) {\n if (!this.marks.has(mark.type)) {\n errors.push(`Unknown mark type: ${mark.type}`);\n }\n }\n }\n } else {\n // Block node validation\n const blockNode = node as BlockNode;\n const spec = this.nodes.get(blockNode.type);\n \n if (!spec) {\n errors.push(`Unknown node type: ${blockNode.type}`);\n return { valid: false, errors };\n }\n\n // Validate required attributes\n if (spec.attrs) {\n for (const [attrName, attrSpec] of Object.entries(spec.attrs)) {\n if (attrSpec.required && (!blockNode.attrs || !(attrName in blockNode.attrs))) {\n errors.push(`Required attribute missing: ${attrName}`);\n }\n if (blockNode.attrs?.[attrName] && attrSpec.validate) {\n if (!attrSpec.validate(blockNode.attrs[attrName])) {\n errors.push(`Invalid attribute value: ${attrName}`);\n }\n }\n }\n }\n\n // Validate children if present\n if (blockNode.children) {\n for (const child of blockNode.children) {\n const childValidation = this.validateNode(child);\n errors.push(...childValidation.errors);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Check if a mark is allowed on a node\n */\n markAllowedOn(markType: string, nodeType: NodeType): boolean {\n const nodeSpec = this.nodes.get(nodeType);\n if (!nodeSpec || !nodeSpec.marks) {\n return false;\n }\n \n if (nodeSpec.marks === '_') {\n return true; // All marks allowed\n }\n \n return nodeSpec.marks.split(' ').includes(markType);\n }\n\n /**\n * Check if two marks can coexist\n */\n marksCompatible(markA: string, markB: string): boolean {\n const specA = this.marks.get(markA);\n const specB = this.marks.get(markB);\n \n if (specA?.excludes && specA.excludes.split(' ').includes(markB)) {\n return false;\n }\n if (specB?.excludes && specB.excludes.split(' ').includes(markA)) {\n return false;\n }\n \n return true;\n }\n}\n\n/**\n * Create default Notectl schema\n */\nexport function createDefaultSchema(): Schema {\n return new Schema({\n nodes: [\n {\n type: 'paragraph',\n group: 'block',\n content: 'inline*',\n marks: '_',\n },\n {\n type: 'heading',\n group: 'block',\n content: 'inline*',\n marks: '_',\n attrs: {\n level: {\n default: 1,\n validate: (val) => typeof val === 'number' && val >= 1 && val <= 6,\n },\n },\n },\n {\n type: 'list',\n group: 'block',\n content: 'list_item+',\n },\n {\n type: 'list_item',\n content: 'paragraph block*',\n defining: true,\n },\n {\n type: 'table',\n group: 'block',\n content: 'table_row+',\n isolating: true,\n },\n {\n type: 'table_row',\n content: 'table_cell+',\n },\n {\n type: 'table_cell',\n content: 'block+',\n isolating: true,\n },\n {\n type: 'image',\n group: 'inline',\n attrs: {\n src: { required: true },\n alt: { default: '' },\n decorative: { default: false },\n },\n },\n {\n type: 'code_block',\n group: 'block',\n content: 'text*',\n marks: '',\n },\n {\n type: 'text',\n group: 'inline',\n },\n ],\n marks: [\n { type: 'bold', excludes: '' },\n { type: 'italic', excludes: '' },\n { type: 'underline', excludes: '' },\n { type: 'strikethrough', excludes: '' },\n { type: 'code', excludes: 'link' },\n {\n type: 'link',\n attrs: {\n href: { required: true },\n title: { default: '' },\n },\n excludes: 'code',\n },\n ],\n topNode: 'paragraph',\n });\n}\n","/**\n * Factory for creating document nodes\n */\n\nimport type { BlockNode, TextNode, BlockId, NodeType, Mark, BlockAttrs } from '../types/index.js';\nimport { Schema } from './Schema.js';\n\n/**\n * Generate a unique block ID\n */\nexport function generateBlockId(): BlockId {\n // Simple UUID v4 implementation\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Node factory for creating valid nodes\n */\nexport class NodeFactory {\n constructor(private schema: Schema) {}\n\n /**\n * Create a text node\n */\n text(text: string, marks?: Mark[]): TextNode {\n return {\n type: 'text',\n text,\n marks: marks || [],\n };\n }\n\n /**\n * Create a paragraph node\n */\n paragraph(content?: TextNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'paragraph',\n attrs,\n children: content || [],\n };\n }\n\n /**\n * Create a heading node\n */\n heading(level: number, content?: TextNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'heading',\n attrs: { ...attrs, level },\n children: content || [],\n };\n }\n\n /**\n * Create a list node\n */\n list(items: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'list',\n attrs,\n children: items,\n };\n }\n\n /**\n * Create a list item node\n */\n listItem(content: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'list_item',\n attrs,\n children: content,\n };\n }\n\n /**\n * Create a table node\n */\n table(rows: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'table',\n attrs,\n children: rows,\n };\n }\n\n /**\n * Create a table row node\n */\n tableRow(cells: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'table_row',\n attrs,\n children: cells,\n };\n }\n\n /**\n * Create a table cell node\n */\n tableCell(content: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'table_cell',\n attrs,\n children: content,\n };\n }\n\n /**\n * Create an image node\n */\n image(src: string, alt?: string, attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'image',\n attrs: { src, alt: alt || '', decorative: !alt, ...attrs },\n children: [],\n };\n }\n\n /**\n * Create a code block node\n */\n codeBlock(content: string, attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'code_block',\n attrs,\n children: [this.text(content)],\n };\n }\n\n /**\n * Create a generic block node\n */\n block(type: NodeType, attrs?: BlockAttrs, children?: (TextNode | BlockNode)[]): BlockNode {\n const spec = this.schema.node(type);\n if (!spec) {\n throw new Error(`Unknown node type: ${type}`);\n }\n\n return {\n id: generateBlockId(),\n type,\n attrs,\n children,\n };\n }\n\n /**\n * Create a mark\n */\n mark(type: string, attrs?: Record<string, unknown>): Mark {\n const spec = this.schema.mark(type);\n if (!spec) {\n throw new Error(`Unknown mark type: ${type}`);\n }\n\n return {\n type,\n attrs,\n };\n }\n\n /**\n * Clone a node with new children\n */\n cloneNode(node: BlockNode, children?: (TextNode | BlockNode)[]): BlockNode {\n return {\n ...node,\n id: generateBlockId(), // Generate new ID for cloned node\n children: children !== undefined ? children : node.children,\n };\n }\n}\n\n/**\n * Create a node factory with the given schema\n */\nexport function createNodeFactory(schema: Schema): NodeFactory {\n return new NodeFactory(schema);\n}\n","/**\n * Editor state management\n * Maintains the document state and provides methods for querying and updating\n */\n\nimport type { Document, Selection, BlockNode, BlockId, Node } from '../types/index.js';\nimport { Schema, createDefaultSchema } from '../schema/Schema.js';\nimport { NodeFactory, createNodeFactory } from '../schema/NodeFactory.js';\nimport type { Delta } from '../delta/Delta.js';\nimport type { Operation } from '../delta/Operations.js';\n\n/**\n * History entry for undo/redo\n */\ninterface HistoryEntry {\n delta: Delta;\n inverseOps: Operation[];\n timestamp: number;\n}\n\n/**\n * Editor state class\n */\nexport class EditorState {\n private document: Document;\n private selection: Selection | null = null;\n private history: HistoryEntry[] = [];\n private historyIndex: number = -1;\n private maxHistoryDepth: number;\n \n readonly schema: Schema;\n readonly nodeFactory: NodeFactory;\n\n constructor(\n initialDoc?: Document,\n schema?: Schema,\n options?: { maxHistoryDepth?: number }\n ) {\n this.schema = schema || createDefaultSchema();\n this.nodeFactory = createNodeFactory(this.schema);\n this.maxHistoryDepth = options?.maxHistoryDepth || 100;\n\n this.document = initialDoc || {\n version: 0,\n schemaVersion: '1.0.0',\n children: [this.nodeFactory.paragraph()],\n };\n }\n\n /**\n * Get current document\n */\n getDocument(): Document {\n return this.document;\n }\n\n /**\n * Get document version\n */\n getVersion(): number {\n return this.document.version;\n }\n\n /**\n * Get current selection\n */\n getSelection(): Selection | null {\n return this.selection;\n }\n\n /**\n * Set selection\n */\n setSelection(selection: Selection | null): void {\n this.selection = selection;\n }\n\n /**\n * Apply a delta to the state\n */\n applyDelta(delta: Delta): void {\n // Validate delta version\n if (delta.baseVersion !== this.document.version) {\n throw new Error(\n `Delta version mismatch: expected ${this.document.version}, got ${delta.baseVersion}`\n );\n }\n\n // Store in history (only if not a selection update)\n const hasContentOps = delta.ops.some((op) => op.op !== 'update_selection');\n if (hasContentOps) {\n this.addToHistory(delta);\n }\n\n // Apply each operation\n for (const op of delta.ops) {\n this.applyOperation(op);\n }\n\n // Increment version\n this.document.version++;\n }\n\n /**\n * Apply a single operation\n */\n private applyOperation(op: Operation): void {\n switch (op.op) {\n case 'insert_text':\n this.applyInsertText(op);\n break;\n case 'delete_range':\n this.applyDeleteRange(op);\n break;\n case 'apply_mark':\n this.applyMark(op);\n break;\n case 'insert_block_after':\n this.applyInsertBlockAfter(op);\n break;\n case 'insert_block_before':\n this.applyInsertBlockBefore(op);\n break;\n case 'delete_block':\n this.applyDeleteBlock(op);\n break;\n case 'set_attrs':\n this.applySetAttrs(op);\n break;\n case 'update_selection':\n this.selection = {\n anchor: op.selection.anchor,\n head: op.selection.head,\n };\n break;\n // Table operations would be implemented here\n default:\n console.warn('Unhandled operation type:', (op as Operation).op);\n }\n }\n\n /**\n * Apply insert text operation\n */\n private applyInsertText(op: Extract<Operation, { op: 'insert_text' }>): void {\n const block = this.findBlock(op.target.blockId);\n if (!block || !block.children) return;\n\n // Find text node at offset and insert text\n // Simplified implementation - would need proper offset handling\n const textNode = block.children.find((n): n is Extract<Node, { type: 'text' }> => 'text' in n);\n if (textNode) {\n const before = textNode.text.slice(0, op.target.offset);\n const after = textNode.text.slice(op.target.offset);\n textNode.text = before + op.text + after;\n if (op.marks && op.marks.length > 0) {\n textNode.marks = op.marks;\n }\n }\n }\n\n /**\n * Apply delete range operation\n */\n private applyDeleteRange(op: Extract<Operation, { op: 'delete_range' }>): void {\n const block = this.findBlock(op.range.start.blockId);\n if (!block || !block.children) return;\n\n const textNode = block.children.find((n): n is Extract<Node, { type: 'text' }> => 'text' in n);\n if (textNode) {\n const before = textNode.text.slice(0, op.range.start.offset);\n const after = textNode.text.slice(op.range.end.offset);\n textNode.text = before + after;\n }\n }\n\n /**\n * Apply mark operation\n */\n private applyMark(op: Extract<Operation, { op: 'apply_mark' }>): void {\n const block = this.findBlock(op.range.start.blockId);\n if (!block || !block.children) return;\n\n const textNode = block.children.find((n): n is Extract<Node, { type: 'text' }> => 'text' in n);\n if (textNode) {\n if (op.add) {\n textNode.marks = textNode.marks || [];\n if (!textNode.marks.some((m) => m.type === op.mark.type)) {\n textNode.marks.push(op.mark);\n }\n } else {\n textNode.marks = textNode.marks?.filter((m) => m.type !== op.mark.type);\n }\n }\n }\n\n /**\n * Apply insert block after operation\n */\n private applyInsertBlockAfter(op: Extract<Operation, { op: 'insert_block_after' }>): void {\n const index = this.document.children.findIndex((b) => b.id === op.after);\n if (index !== -1) {\n this.document.children.splice(index + 1, 0, op.block);\n }\n }\n\n /**\n * Apply insert block before operation\n */\n private applyInsertBlockBefore(op: Extract<Operation, { op: 'insert_block_before' }>): void {\n const index = this.document.children.findIndex((b) => b.id === op.before);\n if (index !== -1) {\n this.document.children.splice(index, 0, op.block);\n }\n }\n\n /**\n * Apply delete block operation\n */\n private applyDeleteBlock(op: Extract<Operation, { op: 'delete_block' }>): void {\n const index = this.document.children.findIndex((b) => b.id === op.target.blockId);\n if (index !== -1) {\n this.document.children.splice(index, 1);\n }\n }\n\n /**\n * Apply set attributes operation\n */\n private applySetAttrs(op: Extract<Operation, { op: 'set_attrs' }>): void {\n const block = this.findBlock(op.target.blockId);\n if (block) {\n block.attrs = { ...block.attrs, ...op.attrs };\n }\n }\n\n /**\n * Find a block by ID\n */\n findBlock(blockId: BlockId): BlockNode | undefined {\n const search = (nodes: BlockNode[]): BlockNode | undefined => {\n for (const node of nodes) {\n if (node.id === blockId) {\n return node;\n }\n if (node.children) {\n const blockChildren = node.children.filter((n): n is BlockNode => 'id' in n);\n const found = search(blockChildren);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n return search(this.document.children);\n }\n\n /**\n * Add delta to history\n */\n private addToHistory(delta: Delta): void {\n // Remove any redo entries\n if (this.historyIndex < this.history.length - 1) {\n this.history = this.history.slice(0, this.historyIndex + 1);\n }\n\n // Add to history\n this.history.push({\n delta,\n inverseOps: delta.inverseOps || [],\n timestamp: Date.now(),\n });\n\n // Maintain max depth\n if (this.history.length > this.maxHistoryDepth) {\n this.history.shift();\n } else {\n this.historyIndex++;\n }\n }\n\n /**\n * Undo last change\n */\n canUndo(): boolean {\n return this.historyIndex >= 0;\n }\n\n undo(): Delta | null {\n if (!this.canUndo()) return null;\n\n const entry = this.history[this.historyIndex];\n this.historyIndex--;\n\n // Create undo delta with inverse operations\n return {\n txnId: `undo-${entry.delta.txnId}`,\n clientId: entry.delta.clientId,\n timestamp: new Date().toISOString(),\n baseVersion: this.document.version,\n ltime: Date.now(),\n intent: 'edit',\n ops: entry.inverseOps,\n };\n }\n\n /**\n * Redo last undone change\n */\n canRedo(): boolean {\n return this.historyIndex < this.history.length - 1;\n }\n\n redo(): Delta | null {\n if (!this.canRedo()) return null;\n\n this.historyIndex++;\n const entry = this.history[this.historyIndex];\n\n return entry.delta;\n }\n\n /**\n * Export state as JSON\n */\n toJSON(): Document {\n return this.document;\n }\n\n /**\n * Create state from JSON\n */\n static fromJSON(json: Document, schema?: Schema): EditorState {\n return new EditorState(json, schema);\n }\n}\n","/**\n * Plugin manager for registering and managing plugins\n */\n\nimport type { Plugin, PluginContext } from './Plugin.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Delta } from '../delta/Delta.js';\n\n/**\n * Plugin manager class\n */\nexport class PluginManager {\n private plugins: Map<string, Plugin> = new Map();\n private initializationOrder: string[] = [];\n\n constructor() {}\n\n /**\n * Register a plugin\n */\n async register(plugin: Plugin, context: PluginContext): Promise<void> {\n if (this.plugins.has(plugin.id)) {\n throw new Error(`Plugin ${plugin.id} is already registered`);\n }\n\n // Check dependencies\n if (plugin.dependencies) {\n for (const depId of plugin.dependencies) {\n if (!this.plugins.has(depId)) {\n throw new Error(`Plugin ${plugin.id} depends on ${depId} which is not registered`);\n }\n }\n }\n\n // Initialize plugin\n await plugin.init(context);\n\n // Store plugin\n this.plugins.set(plugin.id, plugin);\n this.initializationOrder.push(plugin.id);\n\n // Emit event\n context.emit('plugin-registered', { pluginId: plugin.id, plugin });\n }\n\n /**\n * Unregister a plugin\n */\n async unregister(pluginId: string, context: PluginContext): Promise<void> {\n const plugin = this.plugins.get(pluginId);\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} is not registered`);\n }\n\n // Check if other plugins depend on this one\n for (const [id, p] of this.plugins.entries()) {\n if (p.dependencies?.includes(pluginId)) {\n throw new Error(`Cannot unregister ${pluginId}: plugin ${id} depends on it`);\n }\n }\n\n // Destroy plugin\n if (plugin.destroy) {\n await plugin.destroy();\n }\n\n // Remove plugin\n this.plugins.delete(pluginId);\n this.initializationOrder = this.initializationOrder.filter((id) => id !== pluginId);\n\n // Emit event\n context.emit('plugin-unregistered', { pluginId });\n }\n\n /**\n * Get a plugin by ID\n */\n get(pluginId: string): Plugin | undefined {\n return this.plugins.get(pluginId);\n }\n\n /**\n * Check if a plugin is registered\n */\n has(pluginId: string): boolean {\n return this.plugins.has(pluginId);\n }\n\n /**\n * Get all registered plugins\n */\n getAll(): Plugin[] {\n return this.initializationOrder.map((id) => this.plugins.get(id)!);\n }\n\n /**\n * Notify plugins of state update\n */\n notifyStateUpdate(oldState: EditorState, newState: EditorState): void {\n for (const pluginId of this.initializationOrder) {\n const plugin = this.plugins.get(pluginId);\n if (plugin?.onStateUpdate) {\n try {\n plugin.onStateUpdate(oldState, newState);\n } catch (error) {\n console.error(`Error in plugin ${pluginId} onStateUpdate:`, error);\n }\n }\n }\n }\n\n /**\n * Notify plugins of delta application\n */\n notifyDeltaApplied(delta: Delta): void {\n for (const pluginId of this.initializationOrder) {\n const plugin = this.plugins.get(pluginId);\n if (plugin?.onDeltaApplied) {\n try {\n plugin.onDeltaApplied(delta);\n } catch (error) {\n console.error(`Error in plugin ${pluginId} onDeltaApplied:`, error);\n }\n }\n }\n }\n\n /**\n * Destroy all plugins\n */\n async destroyAll(): Promise<void> {\n // Destroy in reverse order\n const pluginIds = [...this.initializationOrder].reverse();\n \n for (const pluginId of pluginIds) {\n const plugin = this.plugins.get(pluginId);\n if (plugin?.destroy) {\n try {\n await plugin.destroy();\n } catch (error) {\n console.error(`Error destroying plugin ${pluginId}:`, error);\n }\n }\n }\n\n this.plugins.clear();\n this.initializationOrder = [];\n }\n}\n","/*! @license DOMPurify 3.2.7 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.7/LICENSE */\n\nconst {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor\n} = Object;\nlet {\n freeze,\n seal,\n create\n} = Object; // eslint-disable-line import/no-mutable-exports\nlet {\n apply,\n construct\n} = typeof Reflect !== 'undefined' && Reflect;\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\nif (!apply) {\n apply = function apply(func, thisArg) {\n for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n return func.apply(thisArg, args);\n };\n}\nif (!construct) {\n construct = function construct(Func) {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n return new Func(...args);\n };\n}\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySplice = unapply(Array.prototype.splice);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return function (thisArg) {\n if (thisArg instanceof RegExp) {\n thisArg.lastIndex = 0;\n }\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n return apply(func, thisArg, args);\n };\n}\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(Func) {\n return function () {\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n return construct(Func, args);\n };\n}\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(set, array) {\n let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n element = lcElement;\n }\n }\n set[element] = true;\n }\n return set;\n}\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n return array;\n}\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (value && typeof value === 'object' && value.constructor === Object) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n return newObject;\n}\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n object = getPrototypeOf(object);\n }\n function fallbackValue() {\n return null;\n }\n return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'slot', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\$\\{[\\w\\W]*/gm); // eslint-disable-line unicorn/better-regex\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\nconst CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n __proto__: null,\n ARIA_ATTR: ARIA_ATTR,\n ATTR_WHITESPACE: ATTR_WHITESPACE,\n CUSTOM_ELEMENT: CUSTOM_ELEMENT,\n DATA_ATTR: DATA_ATTR,\n DOCTYPE_NAME: DOCTYPE_NAME,\n ERB_EXPR: ERB_EXPR,\n IS_ALLOWED_URI: IS_ALLOWED_URI,\n IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n MUSTACHE_EXPR: MUSTACHE_EXPR,\n TMPLIT_EXPR: TMPLIT_EXPR\n});\n\n/* eslint-disable @typescript-eslint/indent */\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5,\n // Deprecated\n entityNode: 6,\n // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12 // Deprecated\n};\nconst getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\nconst _createHooksMap = function _createHooksMap() {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: []\n };\n};\nfunction createDOMPurify() {\n let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n const DOMPurify = root => createDOMPurify(root);\n DOMPurify.version = '3.2.7';\n DOMPurify.removed = [];\n if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n return DOMPurify;\n }\n let {\n document\n } = window;\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes\n } = window;\n const ElementPrototype = Element.prototype;\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n let trustedTypesPolicy;\n let emptyHTML = '';\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName\n } = document;\n const {\n importNode\n } = originalDocument;\n let hooks = _createHooksMap();\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT\n } = EXPRESSIONS;\n let {\n IS_ALLOWED_URI: IS_ALLOWED_URI$1\n } = EXPRESSIONS;\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false\n }\n }));\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n const formElement = document.createElement('form');\n const isRegexOrFunction = function isRegexOrFunction(testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function _parseConfig() {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;\n HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html$1);\n addToSet(ALLOWED_ATTR, html);\n }\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg$1);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl$1);\n addToSet(ALLOWED_ATTR, mathMl);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n }\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n }\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n }\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n CONFIG = cfg;\n };\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);\n const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function _checkValidNamespace(element) {\n let parent = getParentNode(element);\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template'\n };\n }\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either <annotation-xml> or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n // For XHTML and XML documents that support custom namespaces\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n return true;\n }\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, {\n element: node\n });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function _removeAttribute(name, element) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element\n });\n }\n element.removeAttribute(name);\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty = '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' + dirty + '</body></html>';\n }\n const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n const body = doc.body || doc.documentElement;\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function _createNodeIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);\n };\n /**\n * _isClobbered\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function _isClobbered(element) {\n return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');\n };\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param value object to check whether it's a DOM node\n * @return true is object is a DOM node\n */\n const _isNode = function _isNode(value) {\n return typeof Node === 'function' && value instanceof Node;\n };\n function _executeHooks(hooks, currentNode, data) {\n arrayForEach(hooks, hook => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n const _sanitizeElements = function _sanitizeElements(currentNode) {\n let content = null;\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS\n });\n /* Detect mXSS attempts abusing namespace confusion */\n if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\\w!]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any kind of possibly harmful comments */\n if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\\w]/g, currentNode.data)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {\n return false;\n }\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {\n return false;\n }\n }\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n _forceRemove(currentNode);\n return true;\n }\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n content = stringReplace(content, expr, ' ');\n });\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, {\n element: currentNode.cloneNode()\n });\n currentNode.textContent = content;\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n return false;\n };\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n return false;\n } else ;\n return true;\n };\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function _isBasicCustomElement(tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n const {\n attributes\n } = currentNode;\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined\n };\n let l = attributes.length;\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const {\n name,\n namespaceURI,\n value: attrValue\n } = attr;\n const lcName = transformCaseFunc(name);\n const initValue = attrValue;\n let value = name === 'value' ? initValue : stringTrim(initValue);\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title|textarea)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Make sure we cannot easily use animated hrefs, even if animations are allowed */\n if (lcName === 'attributename' && stringMatch(value, 'href')) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n value = stringReplace(value, expr, ' ');\n });\n }\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Handle attributes that require Trusted Types */\n if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n if (namespaceURI) ; else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML':\n {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n case 'TrustedScriptURL':\n {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n }\n }\n }\n /* Handle invalid data-* attribute set by try-catching it */\n if (value !== initValue) {\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {\n _removeAttribute(name, currentNode);\n }\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode);\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty) {\n let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n /* Clean up removed elements */\n DOMPurify.removed = [];\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode);\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n return returnNode;\n }\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n /* Serialize doctype if allowed */\n if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n DOMPurify.setConfig = function () {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n arrayPush(hooks[entryPoint], hookFunction);\n };\n DOMPurify.removeHook = function (entryPoint, hookFunction) {\n if (hookFunction !== undefined) {\n const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];\n }\n return arrayPop(hooks[entryPoint]);\n };\n DOMPurify.removeHooks = function (entryPoint) {\n hooks[entryPoint] = [];\n };\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n return DOMPurify;\n}\nvar purify = createDOMPurify();\n\nexport { purify as default };\n//# sourceMappingURL=purify.es.mjs.map\n","/**\n * Security utilities for XSS prevention and content sanitization\n */\n\nimport DOMPurify from 'dompurify';\nimport type { Delta } from '../delta/Delta.js';\nimport type { Config } from 'dompurify';\n\n/**\n * DOMPurify configuration for editor content\n */\nconst EDITOR_SANITIZE_CONFIG: Config = {\n ALLOWED_TAGS: [\n 'p', 'br', 'strong', 'em', 'u', 's', 'code', 'pre',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'ul', 'ol', 'li',\n 'blockquote',\n 'a', 'img',\n 'table', 'thead', 'tbody', 'tr', 'th', 'td',\n 'div', 'span'\n ],\n ALLOWED_ATTR: [\n 'href', 'src', 'alt', 'title', 'class', 'id',\n 'style', 'data-*',\n 'role', 'aria-*'\n ],\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\n KEEP_CONTENT: true,\n SANITIZE_DOM: true,\n SAFE_FOR_TEMPLATES: true,\n};\n\n/**\n * Strict DOMPurify configuration for untrusted content\n */\nconst STRICT_SANITIZE_CONFIG: Config = {\n ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'u', 'code'],\n ALLOWED_ATTR: [],\n KEEP_CONTENT: true,\n SANITIZE_DOM: true,\n SAFE_FOR_TEMPLATES: true,\n};\n\n/**\n * Sanitize HTML content using DOMPurify\n * @param html - HTML content to sanitize\n * @param strict - Use strict configuration (default: false)\n * @returns Sanitized HTML\n */\nexport function sanitizeHTML(html: string, strict: boolean = false): string {\n const config = strict ? STRICT_SANITIZE_CONFIG : EDITOR_SANITIZE_CONFIG;\n return DOMPurify.sanitize(html, config) as string;\n}\n\n/**\n * Sanitize user content (text and HTML)\n * @param content - Content to sanitize\n * @param allowHTML - Allow HTML tags (default: true)\n * @returns Sanitized content\n */\nexport function sanitizeContent(content: string, allowHTML: boolean = true): string {\n if (!allowHTML) {\n // Escape all HTML\n return escapeHTML(content);\n }\n\n // Sanitize HTML while preserving allowed tags\n return sanitizeHTML(content);\n}\n\n/**\n * Escape HTML entities\n * @param text - Text to escape\n * @returns Escaped text\n */\nexport function escapeHTML(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n}\n\n/**\n * Unescape HTML entities\n * @param html - HTML to unescape\n * @returns Unescaped text\n */\nexport function unescapeHTML(html: string): string {\n const div = document.createElement('div');\n div.innerHTML = html;\n return div.textContent || '';\n}\n\n/**\n * Validate delta operations for potential XSS\n * @param delta - Delta to validate\n * @returns True if delta is safe\n */\nexport function validateDelta(delta: Delta): boolean {\n try {\n // Check if delta has required structure\n if (!delta || typeof delta !== 'object') {\n return false;\n }\n\n // Validate operations array\n if (!Array.isArray(delta.ops)) {\n return false;\n }\n\n // Check each operation\n for (const op of delta.ops) {\n // Validate insert operations\n if ('insert' in op) {\n const insert = op.insert;\n\n // Check for script injection in strings\n if (typeof insert === 'string') {\n const sanitized = sanitizeHTML(insert);\n if (sanitized !== insert && insert.includes('<script')) {\n return false;\n }\n }\n\n // Check for dangerous attributes\n if (typeof insert === 'object' && insert !== null) {\n const insertObj = insert as Record<string, unknown>;\n if ('script' in insertObj || 'onerror' in insertObj || 'onclick' in insertObj) {\n return false;\n }\n }\n }\n\n // Validate attributes\n if ('attributes' in op && op.attributes) {\n const attrs = op.attributes as Record<string, unknown>;\n\n // Check for event handlers\n for (const key in attrs) {\n if (key.startsWith('on') || key.toLowerCase().includes('script')) {\n return false;\n }\n }\n }\n }\n\n return true;\n } catch (error) {\n console.error('Error validating delta:', error);\n return false;\n }\n}\n\n/**\n * Prevent XSS in URLs\n * @param url - URL to validate\n * @returns Sanitized URL or empty string if invalid\n */\nexport function sanitizeURL(url: string): string {\n try {\n const trimmed = url.trim();\n\n // Block javascript: and data: URLs\n if (\n trimmed.toLowerCase().startsWith('javascript:') ||\n trimmed.toLowerCase().startsWith('data:') ||\n trimmed.toLowerCase().startsWith('vbscript:')\n ) {\n return '';\n }\n\n // Validate URL format\n const urlObj = new URL(trimmed, window.location.origin);\n\n // Only allow http, https, mailto, tel protocols\n const allowedProtocols = ['http:', 'https:', 'mailto:', 'tel:'];\n if (!allowedProtocols.includes(urlObj.protocol)) {\n return '';\n }\n\n return urlObj.href;\n } catch {\n // Invalid URL\n return '';\n }\n}\n\n/**\n * Create a safe HTML string with sanitization\n * @param strings - Template strings\n * @param values - Template values\n * @returns Sanitized HTML\n */\nexport function safeHTML(strings: TemplateStringsArray, ...values: unknown[]): string {\n let html = strings[0];\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n const escaped = typeof value === 'string' ? escapeHTML(value) : String(value);\n html += escaped + strings[i + 1];\n }\n\n return sanitizeHTML(html);\n}\n\n/**\n * Remove dangerous attributes from an element\n * @param element - Element to clean\n */\nexport function removeDangerousAttributes(element: Element): void {\n const dangerousAttrs = [\n 'onerror', 'onload', 'onclick', 'onmouseover', 'onfocus', 'onblur',\n 'onchange', 'onsubmit', 'onkeydown', 'onkeyup', 'onkeypress'\n ];\n\n dangerousAttrs.forEach(attr => {\n if (element.hasAttribute(attr)) {\n element.removeAttribute(attr);\n }\n });\n\n // Check all attributes for javascript:\n Array.from(element.attributes).forEach(attr => {\n if (attr.value.toLowerCase().includes('javascript:')) {\n element.removeAttribute(attr.name);\n }\n });\n}\n\n/**\n * Sanitize DOM element and its children\n * @param element - Element to sanitize\n */\nexport function sanitizeElement(element: Element): void {\n // Remove dangerous attributes from current element\n removeDangerousAttributes(element);\n\n // Recursively sanitize children\n Array.from(element.children).forEach(child => {\n sanitizeElement(child);\n });\n}\n\n/**\n * Check if content contains potential XSS\n * @param content - Content to check\n * @returns True if potentially dangerous\n */\nexport function containsXSS(content: string): boolean {\n const dangerous = [\n '<script',\n 'javascript:',\n 'onerror=',\n 'onclick=',\n 'onload=',\n '<iframe',\n '<object',\n '<embed',\n 'data:text/html'\n ];\n\n const lower = content.toLowerCase();\n return dangerous.some(pattern => lower.includes(pattern));\n}\n","/**\n * Accessibility utilities for ARIA attributes and screen reader support\n */\n\n/**\n * ARIA live region politeness levels\n */\nexport type AriaLive = 'off' | 'polite' | 'assertive';\n\n/**\n * Keyboard shortcut configuration\n */\nexport interface KeyboardShortcut {\n key: string;\n ctrlKey?: boolean;\n metaKey?: boolean;\n shiftKey?: boolean;\n altKey?: boolean;\n description: string;\n action: () => void;\n}\n\n/**\n * Focus trap configuration\n */\nexport interface FocusTrapConfig {\n container: HTMLElement;\n initialFocus?: HTMLElement;\n returnFocus?: HTMLElement;\n escapeDeactivates?: boolean;\n}\n\n/**\n * Announce message to screen readers\n * @param message - Message to announce\n * @param politeness - ARIA live politeness level\n */\nexport function announceToScreenReader(\n message: string,\n politeness: AriaLive = 'polite'\n): void {\n // Create or get existing live region\n let liveRegion = document.getElementById('notectl-sr-live');\n\n if (!liveRegion) {\n liveRegion = document.createElement('div');\n liveRegion.id = 'notectl-sr-live';\n liveRegion.setAttribute('role', 'status');\n liveRegion.setAttribute('aria-live', politeness);\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.style.position = 'absolute';\n liveRegion.style.left = '-10000px';\n liveRegion.style.width = '1px';\n liveRegion.style.height = '1px';\n liveRegion.style.overflow = 'hidden';\n document.body.appendChild(liveRegion);\n } else {\n liveRegion.setAttribute('aria-live', politeness);\n }\n\n // Clear and set message (ensures announcement)\n liveRegion.textContent = '';\n setTimeout(() => {\n liveRegion!.textContent = message;\n }, 100);\n}\n\n/**\n * Get all focusable elements within a container\n * @param container - Container element\n * @returns Array of focusable elements\n */\nexport function getFocusableElements(container: HTMLElement): HTMLElement[] {\n const selector = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]'\n ].join(',');\n\n return Array.from(container.querySelectorAll<HTMLElement>(selector)).filter(\n el => {\n // Check if element is visible\n return el.offsetParent !== null &&\n getComputedStyle(el).visibility !== 'hidden' &&\n !el.hasAttribute('hidden');\n }\n );\n}\n\n/**\n * Trap focus within a container\n * @param config - Focus trap configuration\n * @returns Cleanup function\n */\nexport function trapFocus(config: FocusTrapConfig): () => void {\n const { container, initialFocus, returnFocus, escapeDeactivates = true } = config;\n\n const focusableElements = getFocusableElements(container);\n if (focusableElements.length === 0) {\n console.warn('No focusable elements found in container');\n return () => {};\n }\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n // Focus initial element\n if (initialFocus && focusableElements.includes(initialFocus)) {\n initialFocus.focus();\n } else {\n firstElement.focus();\n }\n\n // Handle keyboard events\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n // Shift+Tab\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n } else if (escapeDeactivates && event.key === 'Escape') {\n event.preventDefault();\n deactivate();\n }\n };\n\n // Deactivate focus trap\n const deactivate = (): void => {\n document.removeEventListener('keydown', handleKeyDown);\n if (returnFocus) {\n returnFocus.focus();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return deactivate;\n}\n\n/**\n * Generate ARIA label for editor actions\n * @param action - Action name\n * @param state - Current state description\n * @returns ARIA label\n */\nexport function getAriaLabel(action: string, state?: string): string {\n const labels: Record<string, string> = {\n bold: 'Toggle bold formatting',\n italic: 'Toggle italic formatting',\n underline: 'Toggle underline formatting',\n strikethrough: 'Toggle strikethrough formatting',\n code: 'Toggle code formatting',\n heading1: 'Format as heading level 1',\n heading2: 'Format as heading level 2',\n heading3: 'Format as heading level 3',\n bulletList: 'Create bullet list',\n orderedList: 'Create numbered list',\n blockquote: 'Create blockquote',\n codeBlock: 'Create code block',\n link: 'Insert link',\n image: 'Insert image',\n undo: 'Undo last action',\n redo: 'Redo last action',\n clear: 'Clear formatting'\n };\n\n const baseLabel = labels[action] || action;\n return state ? `${baseLabel} (${state})` : baseLabel;\n}\n\n/**\n * Get keyboard shortcut description\n * @param shortcut - Keyboard shortcut\n * @returns Human-readable description\n */\nexport function getShortcutDescription(shortcut: KeyboardShortcut): string {\n const parts: string[] = [];\n\n const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n\n if (shortcut.ctrlKey || shortcut.metaKey) {\n parts.push(isMac ? 'Cmd' : 'Ctrl');\n }\n if (shortcut.shiftKey) {\n parts.push('Shift');\n }\n if (shortcut.altKey) {\n parts.push(isMac ? 'Option' : 'Alt');\n }\n\n parts.push(shortcut.key.toUpperCase());\n\n return `${parts.join('+')} - ${shortcut.description}`;\n}\n\n/**\n * Register keyboard shortcuts with announcements\n * @param shortcuts - Array of keyboard shortcuts\n * @param container - Container element to attach listeners\n * @returns Cleanup function\n */\nexport function registerKeyboardShortcuts(\n shortcuts: KeyboardShortcut[],\n container: HTMLElement\n): () => void {\n const handleKeyDown = (event: KeyboardEvent): void => {\n for (const shortcut of shortcuts) {\n const ctrlMatch = shortcut.ctrlKey ? event.ctrlKey : true;\n const metaMatch = shortcut.metaKey ? event.metaKey : true;\n const shiftMatch = shortcut.shiftKey ? event.shiftKey : !event.shiftKey;\n const altMatch = shortcut.altKey ? event.altKey : !event.altKey;\n\n if (\n event.key.toLowerCase() === shortcut.key.toLowerCase() &&\n ctrlMatch &&\n metaMatch &&\n shiftMatch &&\n altMatch\n ) {\n event.preventDefault();\n shortcut.action();\n announceToScreenReader(shortcut.description);\n break;\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n };\n}\n\n/**\n * Set ARIA attributes for an element\n * @param element - Element to update\n * @param attributes - ARIA attributes\n */\nexport function setAriaAttributes(\n element: HTMLElement,\n attributes: Record<string, string | boolean | number>\n): void {\n for (const [key, value] of Object.entries(attributes)) {\n const attrName = key.startsWith('aria-') ? key : `aria-${key}`;\n element.setAttribute(attrName, String(value));\n }\n}\n\n/**\n * Create a visually hidden element (accessible to screen readers)\n * @param text - Text content\n * @returns Visually hidden element\n */\nexport function createVisuallyHidden(text: string): HTMLElement {\n const element = document.createElement('span');\n element.textContent = text;\n element.style.position = 'absolute';\n element.style.left = '-10000px';\n element.style.width = '1px';\n element.style.height = '1px';\n element.style.overflow = 'hidden';\n element.setAttribute('aria-hidden', 'false');\n return element;\n}\n\n/**\n * Update ARIA live region\n * @param id - Live region ID\n * @param message - Message to announce\n * @param politeness - Politeness level\n */\nexport function updateAriaLive(\n id: string,\n message: string,\n politeness: AriaLive = 'polite'\n): void {\n let liveRegion = document.getElementById(id);\n\n if (!liveRegion) {\n liveRegion = document.createElement('div');\n liveRegion.id = id;\n liveRegion.setAttribute('role', 'status');\n liveRegion.setAttribute('aria-live', politeness);\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.style.position = 'absolute';\n liveRegion.style.left = '-10000px';\n liveRegion.style.width = '1px';\n liveRegion.style.height = '1px';\n liveRegion.style.overflow = 'hidden';\n document.body.appendChild(liveRegion);\n }\n\n liveRegion.textContent = message;\n}\n\n/**\n * Check if reduced motion is preferred\n * @returns True if reduced motion is preferred\n */\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/**\n * Check if high contrast is enabled\n * @returns True if high contrast is enabled\n */\nexport function prefersHighContrast(): boolean {\n return window.matchMedia('(prefers-contrast: high)').matches;\n}\n\n/**\n * Get accessible color contrast ratio\n * @param foreground - Foreground color (hex)\n * @param background - Background color (hex)\n * @returns Contrast ratio\n */\nexport function getContrastRatio(foreground: string, background: string): number {\n const getLuminance = (color: string): number => {\n const rgb = parseInt(color.slice(1), 16);\n const r = ((rgb >> 16) & 0xff) / 255;\n const g = ((rgb >> 8) & 0xff) / 255;\n const b = (rgb & 0xff) / 255;\n\n const [rs, gs, bs] = [r, g, b].map(c => {\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n });\n\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n };\n\n const l1 = getLuminance(foreground);\n const l2 = getLuminance(background);\n\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n","/**\n * NotectlEditor Web Component\n * Framework-agnostic rich text editor\n */\n\nimport { EditorState } from '../state/EditorState.js';\nimport { PluginManager } from '../plugins/PluginManager.js';\nimport type { Plugin, PluginContext, CommandHandler } from '../plugins/Plugin.js';\nimport type { Delta } from '../delta/Delta.js';\nimport type { EditorConfig, EditorEvent, EditorEventCallback, Document } from '../types/index.js';\nimport { createDefaultSchema } from '../schema/Schema.js';\nimport { sanitizeHTML, sanitizeContent, validateDelta } from '../utils/security.js';\nimport {\n announceToScreenReader,\n registerKeyboardShortcuts,\n setAriaAttributes,\n type KeyboardShortcut\n} from '../utils/accessibility.js';\n\n/**\n * NotectlEditor custom element\n */\nexport class NotectlEditor extends HTMLElement {\n private state: EditorState;\n private pluginManager: PluginManager;\n private eventListeners: Map<string, Set<EditorEventCallback>> = new Map();\n private commands: Map<string, CommandHandler> = new Map();\n private contentElement: HTMLDivElement | null = null;\n private pluginContainerTop: HTMLDivElement | null = null;\n private pluginContainerBottom: HTMLDivElement | null = null;\n private config: EditorConfig;\n private keyboardShortcutCleanup?: () => void;\n private ariaLiveRegion: HTMLDivElement | null = null;\n\n constructor() {\n super();\n\n // Default config\n this.config = {\n placeholder: 'Start typing...',\n readonly: false,\n autofocus: false,\n sanitizeHTML: true,\n maxHistoryDepth: 100,\n };\n\n // Initialize state\n const schema = createDefaultSchema();\n this.state = new EditorState(undefined, schema, {\n maxHistoryDepth: this.config.maxHistoryDepth,\n });\n\n // Initialize plugin manager\n this.pluginManager = new PluginManager();\n\n // Attach shadow DOM\n this.attachShadow({ mode: 'open' });\n }\n\n /**\n * Observed attributes for the web component\n */\n static get observedAttributes(): string[] {\n return ['placeholder', 'readonly', 'autofocus'];\n }\n\n /**\n * Called when element is connected to DOM\n */\n connectedCallback(): void {\n this.render();\n this.attachEventListeners();\n this.setupAccessibility();\n this.setupKeyboardShortcuts();\n\n if (this.config.autofocus) {\n this.focus();\n }\n }\n\n /**\n * Called when element is disconnected from DOM\n */\n disconnectedCallback(): void {\n this.detachEventListeners();\n this.pluginManager.destroyAll();\n if (this.keyboardShortcutCleanup) {\n this.keyboardShortcutCleanup();\n }\n if (this.ariaLiveRegion && this.ariaLiveRegion.parentNode) {\n this.ariaLiveRegion.parentNode.removeChild(this.ariaLiveRegion);\n }\n }\n\n /**\n * Called when attributes change\n */\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n\n switch (name) {\n case 'placeholder':\n this.config.placeholder = newValue || '';\n this.updatePlaceholder();\n break;\n case 'readonly':\n this.config.readonly = newValue !== null;\n this.updateReadonly();\n break;\n case 'autofocus':\n this.config.autofocus = newValue !== null;\n break;\n }\n }\n\n /**\n * Render the editor UI\n */\n private render(): void {\n if (!this.shadowRoot) return;\n\n this.shadowRoot.innerHTML = `\n <style>\n :host {\n display: block;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 16px;\n line-height: 1.5;\n }\n\n .notectl-container {\n display: flex;\n flex-direction: column;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n background: white;\n }\n\n .notectl-plugin-container {\n display: block;\n background: transparent;\n }\n\n .notectl-plugin-container[data-position=\"top\"] {\n order: -1;\n }\n\n .notectl-plugin-container[data-position=\"bottom\"] {\n order: 1;\n }\n\n .notectl-editor-wrapper {\n position: relative;\n flex: 1;\n }\n\n .notectl-editor {\n min-height: 200px;\n padding: 1rem;\n outline: none;\n background: white;\n }\n\n .notectl-container:focus-within {\n border-color: #2196F3;\n box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.1);\n }\n\n .notectl-editor[data-readonly=\"true\"] {\n background: #f5f5f5;\n cursor: not-allowed;\n }\n\n .notectl-editor table {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n }\n\n .notectl-editor table td,\n .notectl-editor table th {\n border: 1px solid #ddd;\n padding: 8px;\n min-width: 100px;\n }\n\n .notectl-placeholder {\n position: absolute;\n top: 1rem;\n left: 1rem;\n color: #9e9e9e;\n pointer-events: none;\n user-select: none;\n }\n\n .notectl-placeholder.hidden {\n display: none;\n }\n\n .visually-hidden {\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n }\n </style>\n\n <div class=\"notectl-container\">\n <div class=\"notectl-plugin-container\" data-position=\"top\"></div>\n <div class=\"notectl-editor-wrapper\">\n <div class=\"notectl-placeholder\" aria-hidden=\"true\">${this.config.placeholder}</div>\n <div\n class=\"notectl-editor\"\n contenteditable=\"${!this.config.readonly}\"\n data-readonly=\"${this.config.readonly}\"\n role=\"textbox\"\n aria-label=\"Rich text editor\"\n aria-multiline=\"true\"\n aria-describedby=\"notectl-help-text\"\n tabindex=\"0\"\n ></div>\n </div>\n <div class=\"notectl-plugin-container\" data-position=\"bottom\"></div>\n </div>\n <div id=\"notectl-help-text\" class=\"visually-hidden\">\n Use arrow keys to navigate. Press Ctrl+B for bold, Ctrl+I for italic, Ctrl+U for underline.\n Press Ctrl+Z to undo, Ctrl+Shift+Z to redo.\n </div>\n <div id=\"notectl-aria-live\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"visually-hidden\"></div>\n `;\n\n this.contentElement = this.shadowRoot.querySelector('.notectl-editor');\n this.pluginContainerTop = this.shadowRoot.querySelector('.notectl-plugin-container[data-position=\"top\"]');\n this.pluginContainerBottom = this.shadowRoot.querySelector('.notectl-plugin-container[data-position=\"bottom\"]');\n this.ariaLiveRegion = this.shadowRoot.querySelector('#notectl-aria-live');\n this.renderContent();\n }\n\n /**\n * Render document content\n */\n private renderContent(): void {\n if (!this.contentElement) return;\n\n const doc = this.state.getDocument();\n const html = this.documentToHTML(doc);\n\n // Sanitize HTML before rendering\n this.contentElement.innerHTML = this.config.sanitizeHTML\n ? sanitizeHTML(html)\n : html;\n }\n\n /**\n * Convert document to HTML\n */\n private documentToHTML(doc: Document): string {\n return doc.children.map((block) => this.blockToHTML(block)).join('');\n }\n\n /**\n * Convert block to HTML (simplified)\n */\n private blockToHTML(block: any): string {\n switch (block.type) {\n case 'paragraph':\n return `<p>${this.childrenToHTML(block.children || [])}</p>`;\n case 'heading':\n const level = block.attrs?.level || 1;\n return `<h${level}>${this.childrenToHTML(block.children || [])}</h${level}>`;\n default:\n return `<div>${this.childrenToHTML(block.children || [])}</div>`;\n }\n }\n\n /**\n * Convert children to HTML\n */\n private childrenToHTML(children: any[]): string {\n return children\n .map((child) => {\n if (child.type === 'text') {\n let html = this.escapeHTML(child.text);\n if (child.marks) {\n for (const mark of child.marks) {\n html = this.applyMarkHTML(html, mark);\n }\n }\n return html;\n }\n return this.blockToHTML(child);\n })\n .join('');\n }\n\n /**\n * Apply mark as HTML\n */\n private applyMarkHTML(text: string, mark: any): string {\n switch (mark.type) {\n case 'bold':\n return `<strong>${text}</strong>`;\n case 'italic':\n return `<em>${text}</em>`;\n case 'underline':\n return `<u>${text}</u>`;\n case 'strikethrough':\n return `<s>${text}</s>`;\n case 'code':\n return `<code>${text}</code>`;\n default:\n return text;\n }\n }\n\n /**\n * Escape HTML\n */\n private escapeHTML(text: string): string {\n if (!this.config.sanitizeHTML) return text;\n\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n /**\n * Setup accessibility features\n */\n private setupAccessibility(): void {\n if (!this.contentElement) return;\n\n // Set comprehensive ARIA attributes\n setAriaAttributes(this.contentElement, {\n 'role': 'textbox',\n 'aria-multiline': true,\n 'aria-label': 'Rich text editor',\n 'aria-describedby': 'notectl-help-text',\n 'aria-autocomplete': 'none'\n });\n\n // Update ARIA attributes based on readonly state\n if (this.config.readonly) {\n this.contentElement.setAttribute('aria-readonly', 'true');\n }\n }\n\n /**\n * Setup keyboard shortcuts with screen reader announcements\n */\n private setupKeyboardShortcuts(): void {\n if (!this.contentElement) return;\n\n const shortcuts: KeyboardShortcut[] = [\n {\n key: 'b',\n ctrlKey: true,\n description: 'Bold formatting applied',\n action: () => this.toggleFormat('bold')\n },\n {\n key: 'i',\n ctrlKey: true,\n description: 'Italic formatting applied',\n action: () => this.toggleFormat('italic')\n },\n {\n key: 'u',\n ctrlKey: true,\n description: 'Underline formatting applied',\n action: () => this.toggleFormat('underline')\n },\n {\n key: 'z',\n ctrlKey: true,\n description: 'Action undone',\n action: () => this.undo()\n },\n {\n key: 'z',\n ctrlKey: true,\n shiftKey: true,\n description: 'Action redone',\n action: () => this.redo()\n }\n ];\n\n this.keyboardShortcutCleanup = registerKeyboardShortcuts(shortcuts, this.contentElement);\n }\n\n /**\n * Toggle formatting\n */\n private toggleFormat(format: string): void {\n // Get current selection\n const selection = window.getSelection();\n if (!selection || !this.contentElement) return;\n\n // Apply formatting via execCommand (will be replaced with Delta operations)\n try {\n switch (format) {\n case 'bold':\n document.execCommand('bold', false);\n break;\n case 'italic':\n document.execCommand('italic', false);\n break;\n case 'underline':\n document.execCommand('underline', false);\n break;\n case 'strikethrough':\n document.execCommand('strikeThrough', false);\n break;\n case 'code':\n // Wrap selection in <code> tag\n const code = document.createElement('code');\n if (selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n code.appendChild(range.extractContents());\n range.insertNode(code);\n }\n break;\n }\n\n this.announceToScreenReader(`${format} formatting applied`);\n this.emit('change', { state: this.state });\n } catch (error) {\n console.error(`Failed to apply ${format} formatting:`, error);\n this.announceToScreenReader(`Failed to apply ${format} formatting`);\n }\n }\n\n /**\n * Insert table at current selection\n */\n insertTable(rows: number = 3, cols: number = 3): void {\n if (!this.contentElement) return;\n\n try {\n // Focus the editor if not already focused\n this.contentElement.focus();\n\n // Create table element\n const table = document.createElement('table');\n table.setAttribute('data-notectl-table', 'true');\n\n // Create tbody\n const tbody = document.createElement('tbody');\n\n // Generate rows - all cells are equal, user can style as needed\n for (let i = 0; i < rows; i++) {\n const tr = document.createElement('tr');\n\n for (let j = 0; j < cols; j++) {\n const cell = document.createElement('td');\n cell.textContent = ''; // Empty cells - user fills them\n tr.appendChild(cell);\n }\n\n tbody.appendChild(tr);\n }\n\n table.appendChild(tbody);\n\n // Get the current selection\n const selection = window.getSelection();\n let insertPosition = this.contentElement.childNodes.length;\n\n // Try to find the cursor position\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n\n // Check if the range is inside contentElement\n if (this.contentElement.contains(range.commonAncestorContainer)) {\n // Find the position in childNodes\n let node = range.startContainer;\n\n // If it's a text node, get its parent\n if (node.nodeType === Node.TEXT_NODE) {\n node = node.parentNode as Node;\n }\n\n // Find position among contentElement's children\n if (node === this.contentElement) {\n insertPosition = range.startOffset;\n } else {\n // Find the index of the node or its ancestor\n let child = node;\n while (child.parentNode && child.parentNode !== this.contentElement) {\n child = child.parentNode;\n }\n if (child.parentNode === this.contentElement) {\n insertPosition = Array.from(this.contentElement.childNodes).indexOf(child as ChildNode) + 1;\n }\n }\n }\n }\n\n // Add a paragraph after the table\n const p = document.createElement('p');\n p.innerHTML = '<br>';\n\n // Insert at the correct position\n if (insertPosition >= this.contentElement.childNodes.length) {\n this.contentElement.appendChild(table);\n this.contentElement.appendChild(p);\n } else {\n const refNode = this.contentElement.childNodes[insertPosition];\n this.contentElement.insertBefore(table, refNode);\n this.contentElement.insertBefore(p, refNode);\n }\n\n // Set cursor in the new paragraph\n if (selection) {\n const range = document.createRange();\n range.setStart(p, 0);\n range.setEnd(p, 0);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n // Update placeholder visibility (content is no longer empty)\n this.updatePlaceholder();\n\n // Force sync to state\n this.syncContentToState();\n\n this.announceToScreenReader(`Table with ${rows} rows and ${cols} columns inserted`);\n this.emit('change', { state: this.state });\n } catch (error) {\n console.error('Failed to insert table:', error);\n this.announceToScreenReader('Failed to insert table');\n }\n }\n\n /**\n * Announce message to screen readers\n */\n private announceToScreenReader(message: string): void {\n if (this.ariaLiveRegion) {\n this.ariaLiveRegion.textContent = '';\n setTimeout(() => {\n if (this.ariaLiveRegion) {\n this.ariaLiveRegion.textContent = message;\n }\n }, 100);\n } else {\n announceToScreenReader(message);\n }\n }\n\n /**\n * Attach event listeners\n */\n private attachEventListeners(): void {\n if (!this.contentElement) return;\n\n this.contentElement.addEventListener('input', this.handleInput.bind(this));\n this.contentElement.addEventListener('keydown', this.handleKeydown.bind(this));\n this.contentElement.addEventListener('focus', this.handleFocus.bind(this));\n this.contentElement.addEventListener('blur', this.handleBlur.bind(this));\n }\n\n /**\n * Detach event listeners\n */\n private detachEventListeners(): void {\n if (!this.contentElement) return;\n\n this.contentElement.removeEventListener('input', this.handleInput.bind(this));\n this.contentElement.removeEventListener('keydown', this.handleKeydown.bind(this));\n this.contentElement.removeEventListener('focus', this.handleFocus.bind(this));\n this.contentElement.removeEventListener('blur', this.handleBlur.bind(this));\n }\n\n /**\n * Handle input event\n */\n private handleInput(_event: Event): void {\n this.updatePlaceholder();\n\n // Sync content back to state\n this.syncContentToState();\n\n this.emit('change', { state: this.state });\n }\n\n /**\n * Handle keydown event\n */\n private handleKeydown(event: KeyboardEvent): void {\n // Handle undo/redo\n if ((event.ctrlKey || event.metaKey) && event.key === 'z') {\n event.preventDefault();\n if (event.shiftKey) {\n this.redo();\n this.announceToScreenReader('Action redone');\n } else {\n this.undo();\n this.announceToScreenReader('Action undone');\n }\n }\n\n // Announce navigation\n if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {\n if (event.ctrlKey || event.metaKey) {\n this.announceToScreenReader(`Navigating ${event.key.replace('Arrow', '').toLowerCase()}`);\n }\n }\n }\n\n /**\n * Handle focus event\n */\n private handleFocus(): void {\n this.emit('focus', { state: this.state });\n }\n\n /**\n * Handle blur event\n */\n private handleBlur(): void {\n this.emit('blur', { state: this.state });\n }\n\n /**\n * Update placeholder visibility\n */\n private updatePlaceholder(): void {\n if (!this.shadowRoot) return;\n\n const placeholder = this.shadowRoot.querySelector('.notectl-placeholder');\n const isEmpty = !this.contentElement?.textContent?.trim();\n\n if (placeholder) {\n placeholder.classList.toggle('hidden', !isEmpty);\n }\n }\n\n /**\n * Sync content from DOM to state\n */\n private syncContentToState(): void {\n if (!this.contentElement) return;\n\n try {\n const doc = this.htmlToDocument(this.contentElement.innerHTML);\n this.state = EditorState.fromJSON(doc, this.state.schema);\n } catch (error) {\n console.error('Failed to sync content to state:', error);\n }\n }\n\n /**\n * Convert HTML to document structure\n */\n private htmlToDocument(html: string): Document {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n const body = doc.body;\n\n const children: any[] = [];\n\n // Parse child nodes\n Array.from(body.childNodes).forEach((node) => {\n const block = this.nodeToBlock(node);\n if (block) {\n children.push(block);\n }\n });\n\n // If no children, create empty paragraph\n if (children.length === 0) {\n children.push({\n id: crypto.randomUUID(),\n type: 'paragraph',\n children: [],\n });\n }\n\n return {\n version: this.state.getDocument().version + 1,\n schemaVersion: '1.0.0',\n children,\n };\n }\n\n /**\n * Convert DOM node to block\n */\n private nodeToBlock(node: Node): any {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || '';\n if (!text.trim()) return null;\n return {\n type: 'text',\n text,\n marks: [],\n };\n }\n\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n\n // Block elements\n if (tagName === 'p') {\n return {\n id: crypto.randomUUID(),\n type: 'paragraph',\n children: this.parseChildren(element),\n };\n }\n\n if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tagName)) {\n const level = parseInt(tagName.charAt(1), 10);\n return {\n id: crypto.randomUUID(),\n type: 'heading',\n attrs: { level },\n children: this.parseChildren(element),\n };\n }\n\n // Inline elements - extract text with marks\n return this.parseInlineElement(element);\n }\n\n return null;\n }\n\n /**\n * Parse children nodes\n */\n private parseChildren(element: Element): any[] {\n const children: any[] = [];\n\n Array.from(element.childNodes).forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || '';\n if (text) {\n children.push({\n type: 'text',\n text,\n marks: [],\n });\n }\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const childElement = node as Element;\n const result = this.parseInlineElement(childElement);\n if (result) {\n if (Array.isArray(result)) {\n children.push(...result);\n } else {\n children.push(result);\n }\n }\n }\n });\n\n return children;\n }\n\n /**\n * Parse inline element with marks\n */\n private parseInlineElement(element: Element): any {\n const tagName = element.tagName.toLowerCase();\n const marks: any[] = [];\n\n // Determine mark type\n if (tagName === 'strong' || tagName === 'b') {\n marks.push({ type: 'bold' });\n } else if (tagName === 'em' || tagName === 'i') {\n marks.push({ type: 'italic' });\n } else if (tagName === 'u') {\n marks.push({ type: 'underline' });\n } else if (tagName === 's' || tagName === 'strike') {\n marks.push({ type: 'strikethrough' });\n } else if (tagName === 'code') {\n marks.push({ type: 'code' });\n }\n\n // Get text content and nested marks\n const children: any[] = [];\n Array.from(element.childNodes).forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || '';\n if (text) {\n children.push({\n type: 'text',\n text,\n marks,\n });\n }\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const childElement = node as Element;\n const childResult = this.parseInlineElement(childElement);\n if (childResult) {\n // Merge marks\n if (childResult.type === 'text') {\n childResult.marks = [...marks, ...(childResult.marks || [])];\n children.push(childResult);\n } else if (Array.isArray(childResult)) {\n childResult.forEach((item: any) => {\n if (item.type === 'text') {\n item.marks = [...marks, ...(item.marks || [])];\n }\n children.push(item);\n });\n }\n }\n }\n });\n\n return children.length === 1 ? children[0] : children;\n }\n\n /**\n * Update readonly state\n */\n private updateReadonly(): void {\n if (this.contentElement) {\n this.contentElement.contentEditable = String(!this.config.readonly);\n this.contentElement.setAttribute('data-readonly', String(this.config.readonly));\n }\n }\n\n /**\n * Register a plugin\n */\n async registerPlugin(plugin: Plugin): Promise<void> {\n const context = this.createPluginContext();\n await this.pluginManager.register(plugin, context);\n }\n\n /**\n * Unregister a plugin\n */\n async unregisterPlugin(pluginId: string): Promise<void> {\n const context = this.createPluginContext();\n await this.pluginManager.unregister(pluginId, context);\n }\n\n /**\n * Create plugin context\n */\n private createPluginContext(): PluginContext {\n return {\n getState: () => this.state,\n applyDelta: (delta: Delta) => this.applyDelta(delta),\n on: (event: string, callback: (data: unknown) => void) => this.on(event as EditorEvent, callback),\n off: (event: string, callback: (data: unknown) => void) => this.off(event as EditorEvent, callback),\n emit: (event: string, data?: unknown) => this.emit(event, data),\n registerCommand: (name: string, handler: CommandHandler) => this.registerCommand(name, handler),\n executeCommand: (name: string, ...args: unknown[]) => this.executeCommand(name, ...args),\n getContainer: () => this.contentElement!,\n getPluginContainer: (position: 'top' | 'bottom') => {\n if (position === 'top') {\n return this.pluginContainerTop!;\n }\n return this.pluginContainerBottom!;\n },\n };\n }\n\n /**\n * Apply a delta\n */\n applyDelta(delta: Delta): void {\n // Validate delta for security\n if (!validateDelta(delta)) {\n console.error('Invalid or unsafe delta rejected');\n this.announceToScreenReader('Action blocked due to security validation');\n return;\n }\n\n this.state.applyDelta(delta);\n this.renderContent();\n this.pluginManager.notifyDeltaApplied(delta);\n this.emit('change', { delta, state: this.state });\n }\n\n /**\n * Register event listener\n */\n on(event: EditorEvent, callback: EditorEventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Unregister event listener\n */\n off(event: EditorEvent, callback: EditorEventCallback): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Emit event\n */\n private emit(event: string, data?: unknown): void {\n this.eventListeners.get(event)?.forEach((callback) => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event listener for ${event}:`, error);\n }\n });\n }\n\n /**\n * Register command\n */\n registerCommand(name: string, handler: CommandHandler): void {\n this.commands.set(name, handler);\n }\n\n /**\n * Execute command\n */\n executeCommand(name: string, ...args: unknown[]): unknown {\n const handler = this.commands.get(name);\n if (!handler) {\n throw new Error(`Command not found: ${name}`);\n }\n return handler(...args);\n }\n\n /**\n * Undo last change\n */\n undo(): void {\n const undoDelta = this.state.undo();\n if (undoDelta) {\n this.renderContent();\n this.announceToScreenReader('Undo performed');\n this.emit('change', { delta: undoDelta, state: this.state });\n } else {\n this.announceToScreenReader('Nothing to undo');\n }\n }\n\n /**\n * Redo last undone change\n */\n redo(): void {\n const redoDelta = this.state.redo();\n if (redoDelta) {\n this.renderContent();\n this.announceToScreenReader('Redo performed');\n this.emit('change', { delta: redoDelta, state: this.state });\n } else {\n this.announceToScreenReader('Nothing to redo');\n }\n }\n\n /**\n * Configure editor options\n * @param config - Configuration options to apply\n */\n configure(config: EditorConfig): void {\n this.config = { ...this.config, ...config };\n\n // Apply configuration changes\n if (config.readonly !== undefined) {\n this.updateReadonly();\n }\n\n if (config.placeholder !== undefined && this.shadowRoot) {\n const placeholder = this.shadowRoot.querySelector('.notectl-placeholder');\n if (placeholder) {\n placeholder.textContent = config.placeholder;\n }\n }\n\n if (config.initialContent) {\n if (typeof config.initialContent === 'object') {\n this.setJSON(config.initialContent);\n }\n }\n\n if (config.content) {\n if (typeof config.content === 'string') {\n this.setContent(config.content);\n } else {\n this.setJSON(config.content as Document);\n }\n }\n }\n\n /**\n * Destroy the editor and clean up resources\n */\n destroy(): void {\n this.detachEventListeners();\n this.pluginManager.destroyAll();\n\n if (this.keyboardShortcutCleanup) {\n this.keyboardShortcutCleanup();\n }\n\n if (this.ariaLiveRegion && this.ariaLiveRegion.parentNode) {\n this.ariaLiveRegion.parentNode.removeChild(this.ariaLiveRegion);\n }\n\n this.eventListeners.clear();\n this.commands.clear();\n }\n\n /**\n * Get current content as string or JSON\n * @returns Current document content\n */\n getContent(): Document | string {\n return this.getJSON();\n }\n\n /**\n * Get current state\n */\n getState(): EditorState {\n return this.state;\n }\n\n /**\n * Get document as JSON\n */\n getJSON(): Document {\n return this.state.toJSON();\n }\n\n /**\n * Set document from JSON\n */\n setJSON(doc: Document): void {\n this.state = EditorState.fromJSON(doc, this.state.schema);\n this.renderContent();\n }\n\n /**\n * Get HTML content (sanitized)\n */\n getHTML(): string {\n const html = this.documentToHTML(this.state.getDocument());\n return this.config.sanitizeHTML ? sanitizeHTML(html) : html;\n }\n\n /**\n * Set HTML content (with sanitization)\n * @param html - HTML content to set\n */\n setHTML(html: string): void {\n const sanitized = this.config.sanitizeHTML ? sanitizeHTML(html) : html;\n if (this.contentElement) {\n this.contentElement.innerHTML = sanitized;\n this.announceToScreenReader('Content updated');\n }\n }\n\n /**\n * Set content from string (with sanitization)\n * @param content - Content to set\n * @param allowHTML - Allow HTML tags\n */\n setContent(content: string, allowHTML: boolean = true): void {\n const sanitized = this.config.sanitizeHTML\n ? sanitizeContent(content, allowHTML)\n : content;\n\n if (this.contentElement) {\n this.contentElement.innerHTML = sanitized;\n this.announceToScreenReader('Content updated');\n }\n }\n\n /**\n * Export HTML content (sanitized)\n * @returns Sanitized HTML\n */\n exportHTML(): string {\n return this.getHTML();\n }\n\n /**\n * Focus the editor\n */\n focus(): void {\n this.contentElement?.focus();\n }\n\n /**\n * Blur the editor\n */\n blur(): void {\n this.contentElement?.blur();\n }\n}\n\n/**\n * Register custom element\n */\nif (!customElements.get('notectl-editor')) {\n customElements.define('notectl-editor', NotectlEditor);\n}\n","/**\n * Plugin interface and types for Notectl\n */\n\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Delta } from '../delta/Delta.js';\n\n/**\n * Plugin context provided to plugins\n */\nexport interface PluginContext {\n /**\n * Get current editor state\n */\n getState(): EditorState;\n\n /**\n * Apply a delta to the editor\n */\n applyDelta(delta: Delta): void;\n\n /**\n * Register event listener\n */\n on(event: string, callback: (data: unknown) => void): void;\n\n /**\n * Unregister event listener\n */\n off(event: string, callback: (data: unknown) => void): void;\n\n /**\n * Emit an event\n */\n emit(event: string, data?: unknown): void;\n\n /**\n * Register a command\n */\n registerCommand(name: string, handler: CommandHandler): void;\n\n /**\n * Execute a command\n */\n executeCommand(name: string, ...args: unknown[]): unknown;\n\n /**\n * Access DOM container (editable area)\n */\n getContainer(): HTMLElement;\n\n /**\n * Access plugin container for UI elements (toolbar, etc.)\n * @param position - 'top' or 'bottom'\n */\n getPluginContainer(position: 'top' | 'bottom'): HTMLElement;\n}\n\n/**\n * Command handler function\n */\nexport type CommandHandler = (...args: unknown[]) => unknown;\n\n/**\n * Plugin interface\n */\nexport interface Plugin {\n /**\n * Unique plugin identifier\n */\n id: string;\n\n /**\n * Plugin name\n */\n name: string;\n\n /**\n * Plugin version\n */\n version: string;\n\n /**\n * Plugin dependencies (optional)\n */\n dependencies?: string[];\n\n /**\n * Initialize the plugin\n */\n init(context: PluginContext): Promise<void> | void;\n\n /**\n * Cleanup the plugin\n */\n destroy?(): Promise<void> | void;\n\n /**\n * Handle state updates (optional)\n */\n onStateUpdate?(oldState: EditorState, newState: EditorState): void;\n\n /**\n * Handle delta application (optional)\n */\n onDeltaApplied?(delta: Delta): void;\n}\n\n/**\n * Plugin factory function type\n */\nexport type PluginFactory<TConfig = unknown> = (config?: TConfig) => Plugin;\n\n/**\n * Base plugin class for convenience\n */\nexport abstract class BasePlugin implements Plugin {\n abstract id: string;\n abstract name: string;\n abstract version: string;\n dependencies?: string[];\n\n protected context?: PluginContext;\n\n async init(context: PluginContext): Promise<void> {\n this.context = context;\n }\n\n async destroy(): Promise<void> {\n this.context = undefined;\n }\n\n protected getContext(): PluginContext {\n if (!this.context) {\n throw new Error('Plugin not initialized');\n }\n return this.context;\n }\n}\n","/**\n * Delta envelope - transactional container for operations\n */\n\nimport type { Operation } from './Operations.js';\nimport type { ValidationConstraint } from '../types/index.js';\n\n/**\n * Validation metadata for delta\n */\nexport interface DeltaValidation {\n requiresSchemaVersion: string;\n constraints: ValidationConstraint[];\n}\n\n/**\n * Delta envelope containing operations and metadata\n */\nexport interface Delta {\n txnId: string;\n clientId: string;\n timestamp: string;\n baseVersion: number;\n ltime: number;\n intent: 'edit' | 'comment' | 'format' | 'import' | string;\n undoGroup?: string;\n ops: Operation[];\n inverseOps?: Operation[];\n validation?: DeltaValidation;\n}\n\n/**\n * Delta class for creating and managing deltas\n */\nexport class DeltaBuilder {\n private delta: Partial<Delta>;\n private operations: Operation[] = [];\n\n constructor(clientId: string, baseVersion: number) {\n this.delta = {\n txnId: this.generateTxnId(),\n clientId,\n timestamp: new Date().toISOString(),\n baseVersion,\n ltime: Date.now(),\n ops: [],\n };\n }\n\n /**\n * Set the intent of this delta\n */\n setIntent(intent: Delta['intent']): this {\n this.delta.intent = intent;\n return this;\n }\n\n /**\n * Set the undo group for batch operations\n */\n setUndoGroup(group: string): this {\n this.delta.undoGroup = group;\n return this;\n }\n\n /**\n * Add an operation to this delta\n */\n addOperation(op: Operation): this {\n this.operations.push(op);\n return this;\n }\n\n /**\n * Add multiple operations\n */\n addOperations(ops: Operation[]): this {\n this.operations.push(...ops);\n return this;\n }\n\n /**\n * Set inverse operations for fast undo\n */\n setInverseOps(inverseOps: Operation[]): this {\n this.delta.inverseOps = inverseOps;\n return this;\n }\n\n /**\n * Set validation constraints\n */\n setValidation(validation: DeltaValidation): this {\n this.delta.validation = validation;\n return this;\n }\n\n /**\n * Build the final delta\n */\n build(): Delta {\n if (this.operations.length === 0) {\n throw new Error('Delta must contain at least one operation');\n }\n\n return {\n ...this.delta,\n ops: this.operations,\n } as Delta;\n }\n\n /**\n * Generate a unique transaction ID\n */\n private generateTxnId(): string {\n // Simple UUID v4 implementation\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n\n/**\n * Utility function to create a delta builder\n */\nexport function createDelta(clientId: string, baseVersion: number): DeltaBuilder {\n return new DeltaBuilder(clientId, baseVersion);\n}\n\n/**\n * Compute inverse operations for undo\n * This is a simplified implementation - full implementation would inspect document state\n */\nexport function computeInverse(delta: Delta): Operation[] {\n // In a real implementation, this would:\n // 1. Examine each operation\n // 2. Query the document state to determine the inverse\n // 3. Return the inverse operations in reverse order\n \n // For now, return empty array (inverse ops should be provided explicitly)\n return delta.inverseOps || [];\n}\n\n/**\n * Validate a delta against constraints\n */\nexport function validateDelta(delta: Delta): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if (!delta.txnId) {\n errors.push('Delta must have a transaction ID');\n }\n\n if (!delta.clientId) {\n errors.push('Delta must have a client ID');\n }\n\n if (delta.ops.length === 0) {\n errors.push('Delta must contain at least one operation');\n }\n\n if (delta.baseVersion < 0) {\n errors.push('Base version must be non-negative');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * Delta operation definitions for Notectl\n * Implements the operations specified in the Delta Design document\n */\n\nimport type { BlockId, Position, Range, Mark, BlockNode, BlockAttrs } from '../types/index.js';\n\n/**\n * Base operation interface\n */\nexport interface BaseOperation {\n op: string;\n}\n\n/**\n * Insert text at a position\n */\nexport interface InsertTextOp extends BaseOperation {\n op: 'insert_text';\n target: Position;\n text: string;\n marks?: Mark[];\n}\n\n/**\n * Delete text across a range\n */\nexport interface DeleteRangeOp extends BaseOperation {\n op: 'delete_range';\n range: Range;\n}\n\n/**\n * Apply or remove a mark across a range\n */\nexport interface ApplyMarkOp extends BaseOperation {\n op: 'apply_mark';\n range: Range;\n mark: Mark;\n add: boolean;\n}\n\n/**\n * Insert a block before another block\n */\nexport interface InsertBlockBeforeOp extends BaseOperation {\n op: 'insert_block_before';\n before: BlockId;\n block: BlockNode;\n}\n\n/**\n * Insert a block after another block\n */\nexport interface InsertBlockAfterOp extends BaseOperation {\n op: 'insert_block_after';\n after: BlockId;\n block: BlockNode;\n}\n\n/**\n * Delete a block\n */\nexport interface DeleteBlockOp extends BaseOperation {\n op: 'delete_block';\n target: { blockId: BlockId };\n}\n\n/**\n * Set attributes on a block\n */\nexport interface SetAttrsOp extends BaseOperation {\n op: 'set_attrs';\n target: { blockId: BlockId };\n attrs: BlockAttrs;\n}\n\n/**\n * Wrap blocks in a container\n */\nexport interface WrapInOp extends BaseOperation {\n op: 'wrap_in';\n blockIds: BlockId[];\n wrapperType: string;\n wrapperAttrs?: BlockAttrs;\n}\n\n/**\n * Lift blocks out of their container\n */\nexport interface LiftOutOp extends BaseOperation {\n op: 'lift_out';\n blockIds: BlockId[];\n}\n\n/**\n * Table operation: insert row\n */\nexport interface TableInsertRowOp extends BaseOperation {\n op: 'table_insert_row';\n target: { tableId: BlockId; rowIndex: number };\n row: BlockNode;\n}\n\n/**\n * Table operation: delete row\n */\nexport interface TableDeleteRowOp extends BaseOperation {\n op: 'table_delete_row';\n target: { tableId: BlockId; rowIndex: number };\n}\n\n/**\n * Table operation: insert column\n */\nexport interface TableInsertColOp extends BaseOperation {\n op: 'table_insert_col';\n target: { tableId: BlockId; colIndex: number };\n}\n\n/**\n * Table operation: delete column\n */\nexport interface TableDeleteColOp extends BaseOperation {\n op: 'table_delete_col';\n target: { tableId: BlockId; colIndex: number };\n}\n\n/**\n * Table operation: merge cells\n */\nexport interface TableMergeCellsOp extends BaseOperation {\n op: 'table_merge_cells';\n target: { tableId: BlockId; cells: BlockId[] };\n}\n\n/**\n * Table operation: split cell\n */\nexport interface TableSplitCellOp extends BaseOperation {\n op: 'table_split_cell';\n target: { tableId: BlockId; cellId: BlockId };\n}\n\n/**\n * Update selection/cursor\n */\nexport interface UpdateSelectionOp extends BaseOperation {\n op: 'update_selection';\n actorId: string;\n selection: {\n anchor: Position;\n head: Position;\n };\n}\n\n/**\n * Union of all operation types\n */\nexport type Operation =\n | InsertTextOp\n | DeleteRangeOp\n | ApplyMarkOp\n | InsertBlockBeforeOp\n | InsertBlockAfterOp\n | DeleteBlockOp\n | SetAttrsOp\n | WrapInOp\n | LiftOutOp\n | TableInsertRowOp\n | TableDeleteRowOp\n | TableInsertColOp\n | TableDeleteColOp\n | TableMergeCellsOp\n | TableSplitCellOp\n | UpdateSelectionOp;\n\n/**\n * Type guard for operation types\n */\nexport function isTextOperation(op: Operation): op is InsertTextOp | DeleteRangeOp | ApplyMarkOp {\n return op.op === 'insert_text' || op.op === 'delete_range' || op.op === 'apply_mark';\n}\n\nexport function isBlockOperation(\n op: Operation\n): op is InsertBlockBeforeOp | InsertBlockAfterOp | DeleteBlockOp | SetAttrsOp {\n return (\n op.op === 'insert_block_before' ||\n op.op === 'insert_block_after' ||\n op.op === 'delete_block' ||\n op.op === 'set_attrs'\n );\n}\n\nexport function isTableOperation(op: Operation): boolean {\n return op.op.startsWith('table_');\n}\n\nexport function isSelectionOperation(op: Operation): op is UpdateSelectionOp {\n return op.op === 'update_selection';\n}\n","/**\n * Operational Transformation (OT) logic for concurrent editing\n */\n\nimport type { Operation } from './Operations.js';\nimport type { Delta } from './Delta.js';\n\n/**\n * Transform operation A against operation B\n * Returns transformed version of A that can be applied after B\n */\nexport function transformOperation(opA: Operation, opB: Operation, side: 'left' | 'right'): Operation {\n // This is a simplified OT implementation\n // Full OT would require detailed transformation rules for each operation pair\n \n // For text operations, we need to adjust positions\n if (opA.op === 'insert_text' && opB.op === 'insert_text') {\n return transformInsertInsert(opA, opB, side);\n }\n \n if (opA.op === 'insert_text' && opB.op === 'delete_range') {\n return transformInsertDelete(opA, opB);\n }\n \n if (opA.op === 'delete_range' && opB.op === 'insert_text') {\n return transformDeleteInsert(opA, opB);\n }\n \n if (opA.op === 'delete_range' && opB.op === 'delete_range') {\n return transformDeleteDelete(opA, opB, side);\n }\n \n // For other operations, return as-is (naive approach)\n // A full implementation would handle all operation pairs\n return opA;\n}\n\n/**\n * Transform two concurrent insert operations\n */\nfunction transformInsertInsert(\n opA: Extract<Operation, { op: 'insert_text' }>,\n opB: Extract<Operation, { op: 'insert_text' }>,\n side: 'left' | 'right'\n): Operation {\n // If insertions are in the same block\n if (opA.target.blockId === opB.target.blockId) {\n // If B inserted before A's position, adjust A's offset\n if (opB.target.offset <= opA.target.offset) {\n return {\n ...opA,\n target: {\n ...opA.target,\n offset: opA.target.offset + opB.text.length,\n },\n };\n }\n // If B inserted at same position, use side to determine order\n if (opB.target.offset === opA.target.offset && side === 'right') {\n return {\n ...opA,\n target: {\n ...opA.target,\n offset: opA.target.offset + opB.text.length,\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform insert against delete\n */\nfunction transformInsertDelete(\n opA: Extract<Operation, { op: 'insert_text' }>,\n opB: Extract<Operation, { op: 'delete_range' }>\n): Operation {\n // If insertion is in the deleted range, move it to start of range\n if (opA.target.blockId === opB.range.start.blockId) {\n if (opA.target.offset >= opB.range.start.offset) {\n const deleteLength = opB.range.end.offset - opB.range.start.offset;\n return {\n ...opA,\n target: {\n ...opA.target,\n offset: Math.max(opB.range.start.offset, opA.target.offset - deleteLength),\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform delete against insert\n */\nfunction transformDeleteInsert(\n opA: Extract<Operation, { op: 'delete_range' }>,\n opB: Extract<Operation, { op: 'insert_text' }>\n): Operation {\n // If insert is before delete range, adjust delete positions\n if (opA.range.start.blockId === opB.target.blockId) {\n if (opB.target.offset <= opA.range.start.offset) {\n return {\n ...opA,\n range: {\n start: {\n ...opA.range.start,\n offset: opA.range.start.offset + opB.text.length,\n },\n end: {\n ...opA.range.end,\n offset: opA.range.end.offset + opB.text.length,\n },\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform two concurrent delete operations\n */\nfunction transformDeleteDelete(\n opA: Extract<Operation, { op: 'delete_range' }>,\n opB: Extract<Operation, { op: 'delete_range' }>,\n _side: 'left' | 'right'\n): Operation {\n // If ranges overlap, need to adjust A's range\n if (opA.range.start.blockId === opB.range.start.blockId) {\n const aStart = opA.range.start.offset;\n const aEnd = opA.range.end.offset;\n const bStart = opB.range.start.offset;\n const bEnd = opB.range.end.offset;\n \n // If B's delete is completely before A\n if (bEnd <= aStart) {\n const bLength = bEnd - bStart;\n return {\n ...opA,\n range: {\n start: { ...opA.range.start, offset: aStart - bLength },\n end: { ...opA.range.end, offset: aEnd - bLength },\n },\n };\n }\n \n // If B's delete overlaps with A, adjust accordingly\n // This is complex - simplified version here\n if (bStart <= aStart && bEnd >= aEnd) {\n // B deletes all of A's range - A becomes no-op (delete zero chars)\n return {\n ...opA,\n range: {\n start: { ...opA.range.start, offset: bStart },\n end: { ...opA.range.end, offset: bStart },\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform a delta against another delta\n * Returns transformed version of deltaA that can be applied after deltaB\n */\nexport function transformDelta(deltaA: Delta, deltaB: Delta, side: 'left' | 'right' = 'left'): Delta {\n const transformedOps = deltaA.ops.map((opA) => {\n let transformed = opA;\n for (const opB of deltaB.ops) {\n transformed = transformOperation(transformed, opB, side);\n }\n return transformed;\n });\n\n return {\n ...deltaA,\n ops: transformedOps,\n baseVersion: deltaB.baseVersion + 1, // Update to new base\n };\n}\n\n/**\n * Compose two deltas into a single delta\n * Applies deltaB after deltaA\n */\nexport function composeDelta(deltaA: Delta, deltaB: Delta): Delta {\n // Compose operations - this is simplified\n // Full implementation would optimize/merge operations\n return {\n ...deltaB,\n ops: [...deltaA.ops, ...deltaB.ops],\n baseVersion: deltaA.baseVersion,\n };\n}\n\n/**\n * Check if two deltas can be safely composed\n */\nexport function canCompose(deltaA: Delta, deltaB: Delta): boolean {\n // DeltaB should be based on the version after deltaA\n return deltaB.baseVersion === deltaA.baseVersion || deltaB.clientId === deltaA.clientId;\n}\n","/**\n * Notectl Core - Framework-agnostic rich text editor\n * @packageDocumentation\n */\n\n// Main editor\nexport { NotectlEditor } from './editor/NotectlEditor.js';\nimport { NotectlEditor } from './editor/NotectlEditor.js';\n\n// State management\nexport { EditorState } from './state/EditorState.js';\n\n// Schema\nexport { Schema, createDefaultSchema } from './schema/Schema.js';\nexport type { NodeSpec, MarkSpec, AttributeSpec } from './schema/Schema.js';\n\n// Node factory\nexport { NodeFactory, createNodeFactory, generateBlockId } from './schema/NodeFactory.js';\n\n// Plugin system\nexport { PluginManager } from './plugins/PluginManager.js';\nexport { BasePlugin } from './plugins/Plugin.js';\nexport type {\n Plugin,\n PluginContext,\n PluginFactory,\n CommandHandler,\n} from './plugins/Plugin.js';\n\n// Delta system\nexport { DeltaBuilder, createDelta, computeInverse, validateDelta } from './delta/Delta.js';\nexport type { Delta, DeltaValidation } from './delta/Delta.js';\n\n// Operations\nexport type {\n Operation,\n InsertTextOp,\n DeleteRangeOp,\n ApplyMarkOp,\n InsertBlockBeforeOp,\n InsertBlockAfterOp,\n DeleteBlockOp,\n SetAttrsOp,\n WrapInOp,\n LiftOutOp,\n TableInsertRowOp,\n TableDeleteRowOp,\n TableInsertColOp,\n TableDeleteColOp,\n TableMergeCellsOp,\n TableSplitCellOp,\n UpdateSelectionOp,\n} from './delta/Operations.js';\nexport {\n isTextOperation,\n isBlockOperation,\n isTableOperation,\n isSelectionOperation,\n} from './delta/Operations.js';\n\n// Transformation\nexport { transformOperation, transformDelta, composeDelta, canCompose } from './delta/Transform.js';\n\n// Core types\nexport type {\n BlockId,\n Position,\n Range,\n Mark,\n NodeType,\n TextNode,\n BlockNode,\n BlockAttrs,\n Node,\n Document,\n Selection,\n EditorEvent,\n EditorEventCallback,\n EditorConfig,\n EditorAPI,\n ValidationConstraint,\n ErrorEnvelope,\n} from './types/index.js';\nimport type { EditorConfig } from './types/index.js';\n\n// Utility function to initialize editor\nexport function createEditor(container: HTMLElement, config?: EditorConfig) {\n const editor = new NotectlEditor();\n\n // Apply configuration if provided\n if (config) {\n // Config would be applied here\n }\n\n container.appendChild(editor);\n return editor;\n}\n\n// Version\nexport const VERSION = '0.0.1';\n"],"names":["Schema","config","spec","type","node","errors","textNode","mark","blockNode","attrName","attrSpec","child","childValidation","markType","nodeType","nodeSpec","markA","markB","specA","specB","createDefaultSchema","val","generateBlockId","c","r","NodeFactory","schema","text","marks","content","attrs","level","items","rows","cells","src","alt","children","createNodeFactory","EditorState","initialDoc","options","selection","delta","op","block","n","before","after","m","index","b","blockId","search","nodes","blockChildren","found","entry","json","PluginManager","plugin","context","depId","pluginId","id","p","oldState","newState","error","pluginIds","entries","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","freeze","seal","create","apply","construct","x","func","thisArg","_len","args","_key","Func","_len2","_key2","arrayForEach","unapply","arrayLastIndexOf","arrayPop","arrayPush","arraySplice","stringToLowerCase","stringToString","stringMatch","stringReplace","stringIndexOf","stringTrim","objectHasOwnProperty","regExpTest","typeErrorCreate","unconstruct","_len3","_key3","_len4","_key4","addToSet","set","array","transformCaseFunc","l","element","lcElement","cleanArray","clone","object","newObject","property","value","lookupGetter","prop","desc","fallbackValue","html$1","svg$1","svgFilters","svgDisallowed","mathMl$1","mathMlDisallowed","html","svg","mathMl","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","CUSTOM_ELEMENT","EXPRESSIONS","NODE_TYPE","getGlobal","_createTrustedTypesPolicy","trustedTypes","purifyHostElement","suffix","ATTR_NAME","policyName","scriptUrl","_createHooksMap","createDOMPurify","window","DOMPurify","root","document","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","HTMLFormElement","DOMParser","ElementPrototype","cloneNode","remove","getNextSibling","getChildNodes","getParentNode","template","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","IS_ALLOWED_URI$1","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","CUSTOM_ELEMENT_HANDLING","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","SAFE_FOR_XML","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","SANITIZE_NAMED_PROPS_PREFIX","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","DEFAULT_PARSER_MEDIA_TYPE","CONFIG","formElement","isRegexOrFunction","testValue","_parseConfig","cfg","ALL_SVG_TAGS","ALL_MATHML_TAGS","_checkValidNamespace","parent","tagName","parentTagName","_forceRemove","_removeAttribute","name","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","body","_createNodeIterator","_isClobbered","_isNode","_executeHooks","currentNode","data","hook","_sanitizeElements","_isBasicCustomElement","parentNode","childNodes","childCount","i","childClone","expr","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","attributes","hookEvent","attr","namespaceURI","attrValue","initValue","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","importedNode","returnNode","nodeIterator","serializedHTML","tag","entryPoint","hookFunction","purify","EDITOR_SANITIZE_CONFIG","STRICT_SANITIZE_CONFIG","sanitizeHTML","strict","sanitizeContent","allowHTML","escapeHTML","div","validateDelta","insert","insertObj","key","announceToScreenReader","message","politeness","liveRegion","registerKeyboardShortcuts","shortcuts","container","handleKeyDown","event","shortcut","ctrlMatch","metaMatch","shiftMatch","altMatch","setAriaAttributes","NotectlEditor","oldValue","newValue","format","code","range","cols","table","tbody","tr","j","cell","insertPosition","refNode","_event","placeholder","isEmpty","childElement","result","childResult","item","callback","handler","position","undoDelta","redoDelta","sanitized","BasePlugin","DeltaBuilder","clientId","baseVersion","intent","group","ops","inverseOps","validation","createDelta","computeInverse","isTextOperation","isBlockOperation","isTableOperation","isSelectionOperation","transformOperation","opA","opB","side","transformInsertInsert","transformInsertDelete","transformDeleteInsert","transformDeleteDelete","deleteLength","_side","aStart","aEnd","bStart","bEnd","bLength","transformDelta","deltaA","deltaB","transformedOps","transformed","composeDelta","canCompose","createEditor","editor","VERSION"],"mappings":"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","x_google_ignoreList":[4]}
1
+ {"version":3,"file":"notectl-core.js","sources":["../src/schema/Schema.ts","../src/schema/NodeFactory.ts","../src/state/EditorState.ts","../src/constants.ts","../src/plugins/PluginManager.ts","../../../node_modules/dompurify/dist/purify.es.mjs","../src/utils/security.ts","../src/utils/accessibility.ts","../src/editor/NotectlEditor.ts","../src/plugins/Plugin.ts","../src/delta/Delta.ts","../src/delta/Operations.ts","../src/delta/Transform.ts","../src/utils/helpers.ts","../src/index.ts"],"sourcesContent":["/**\n * Document schema definition for Notectl\n * Defines the structure and validation rules for the document model\n */\n\nimport type { NodeType, BlockNode, TextNode, Node, Mark } from '../types/index.js';\n\n/**\n * Node specification in the schema\n */\nexport interface NodeSpec {\n type: NodeType;\n group?: 'block' | 'inline' | 'table';\n content?: string; // Content expression (e.g., \"block+\", \"inline*\", \"text*\")\n marks?: string; // Allowed marks (e.g., \"_\", \"strong em\")\n attrs?: Record<string, AttributeSpec>;\n defining?: boolean; // Node defines its content boundaries\n isolating?: boolean; // Node isolates content from surroundings\n toDOM?: (node: Node) => HTMLElement | [string, Record<string, string>, ...unknown[]];\n parseDOM?: Array<{\n tag?: string;\n attrs?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Attribute specification\n */\nexport interface AttributeSpec {\n default?: unknown;\n validate?: (value: unknown) => boolean;\n required?: boolean;\n}\n\n/**\n * Mark specification in the schema\n */\nexport interface MarkSpec {\n type: string;\n attrs?: Record<string, AttributeSpec>;\n inclusive?: boolean;\n excludes?: string; // Marks that cannot coexist\n group?: string;\n spanning?: boolean;\n toDOM?: (mark: Mark) => [string, Record<string, string>];\n parseDOM?: Array<{\n tag?: string;\n style?: string;\n attrs?: Record<string, unknown>;\n }>;\n}\n\n/**\n * Document schema\n */\nexport class Schema {\n nodes: Map<NodeType, NodeSpec>;\n marks: Map<string, MarkSpec>;\n topNode: NodeType;\n\n constructor(config: { nodes: NodeSpec[]; marks: MarkSpec[]; topNode?: NodeType }) {\n this.nodes = new Map(config.nodes.map((spec) => [spec.type, spec]));\n this.marks = new Map(config.marks.map((spec) => [spec.type, spec]));\n this.topNode = config.topNode || 'paragraph';\n }\n\n /**\n * Get node specification\n */\n node(type: NodeType): NodeSpec | undefined {\n return this.nodes.get(type);\n }\n\n /**\n * Get mark specification\n */\n mark(type: string): MarkSpec | undefined {\n return this.marks.get(type);\n }\n\n /**\n * Validate if a node conforms to the schema\n */\n validateNode(node: Node): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if ('text' in node) {\n // Text node validation\n const textNode = node as TextNode;\n if (typeof textNode.text !== 'string') {\n errors.push('Text node must have a string text property');\n }\n if (textNode.marks) {\n for (const mark of textNode.marks) {\n if (!this.marks.has(mark.type)) {\n errors.push(`Unknown mark type: ${mark.type}`);\n }\n }\n }\n } else {\n // Block node validation\n const blockNode = node as BlockNode;\n const spec = this.nodes.get(blockNode.type);\n \n if (!spec) {\n errors.push(`Unknown node type: ${blockNode.type}`);\n return { valid: false, errors };\n }\n\n // Validate required attributes\n if (spec.attrs) {\n for (const [attrName, attrSpec] of Object.entries(spec.attrs)) {\n if (attrSpec.required && (!blockNode.attrs || !(attrName in blockNode.attrs))) {\n errors.push(`Required attribute missing: ${attrName}`);\n }\n if (blockNode.attrs?.[attrName] && attrSpec.validate) {\n if (!attrSpec.validate(blockNode.attrs[attrName])) {\n errors.push(`Invalid attribute value: ${attrName}`);\n }\n }\n }\n }\n\n // Validate children if present\n if (blockNode.children) {\n for (const child of blockNode.children) {\n const childValidation = this.validateNode(child);\n errors.push(...childValidation.errors);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Check if a mark is allowed on a node\n */\n markAllowedOn(markType: string, nodeType: NodeType): boolean {\n const nodeSpec = this.nodes.get(nodeType);\n if (!nodeSpec || !nodeSpec.marks) {\n return false;\n }\n \n if (nodeSpec.marks === '_') {\n return true; // All marks allowed\n }\n \n return nodeSpec.marks.split(' ').includes(markType);\n }\n\n /**\n * Check if two marks can coexist\n */\n marksCompatible(markA: string, markB: string): boolean {\n const specA = this.marks.get(markA);\n const specB = this.marks.get(markB);\n \n if (specA?.excludes && specA.excludes.split(' ').includes(markB)) {\n return false;\n }\n if (specB?.excludes && specB.excludes.split(' ').includes(markA)) {\n return false;\n }\n \n return true;\n }\n}\n\n/**\n * Create default Notectl schema\n */\nexport function createDefaultSchema(): Schema {\n return new Schema({\n nodes: [\n {\n type: 'paragraph',\n group: 'block',\n content: 'inline*',\n marks: '_',\n },\n {\n type: 'heading',\n group: 'block',\n content: 'inline*',\n marks: '_',\n attrs: {\n level: {\n default: 1,\n validate: (val) => typeof val === 'number' && val >= 1 && val <= 6,\n },\n },\n },\n {\n type: 'list',\n group: 'block',\n content: 'list_item+',\n },\n {\n type: 'list_item',\n content: 'paragraph block*',\n defining: true,\n },\n {\n type: 'table',\n group: 'block',\n content: 'table_row+',\n isolating: true,\n },\n {\n type: 'table_row',\n content: 'table_cell+',\n },\n {\n type: 'table_cell',\n content: 'block+',\n isolating: true,\n },\n {\n type: 'image',\n group: 'inline',\n attrs: {\n src: { required: true },\n alt: { default: '' },\n decorative: { default: false },\n },\n },\n {\n type: 'code_block',\n group: 'block',\n content: 'text*',\n marks: '',\n },\n {\n type: 'text',\n group: 'inline',\n },\n ],\n marks: [\n { type: 'bold', excludes: '' },\n { type: 'italic', excludes: '' },\n { type: 'underline', excludes: '' },\n { type: 'strikethrough', excludes: '' },\n { type: 'code', excludes: 'link' },\n {\n type: 'link',\n attrs: {\n href: { required: true },\n title: { default: '' },\n },\n excludes: 'code',\n },\n ],\n topNode: 'paragraph',\n });\n}\n","/**\n * Factory for creating document nodes\n */\n\nimport type { BlockNode, TextNode, BlockId, NodeType, Mark, BlockAttrs } from '../types/index.js';\nimport { Schema } from './Schema.js';\n\n/**\n * Generate a unique block ID\n */\nexport function generateBlockId(): BlockId {\n // Simple UUID v4 implementation\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Node factory for creating valid nodes\n */\nexport class NodeFactory {\n constructor(private schema: Schema) {}\n\n /**\n * Create a text node\n */\n text(text: string, marks?: Mark[]): TextNode {\n return {\n type: 'text',\n text,\n marks: marks || [],\n };\n }\n\n /**\n * Create a paragraph node\n */\n paragraph(content?: TextNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'paragraph',\n attrs,\n children: content || [],\n };\n }\n\n /**\n * Create a heading node\n */\n heading(level: number, content?: TextNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'heading',\n attrs: { ...attrs, level },\n children: content || [],\n };\n }\n\n /**\n * Create a list node\n */\n list(items: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'list',\n attrs,\n children: items,\n };\n }\n\n /**\n * Create a list item node\n */\n listItem(content: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'list_item',\n attrs,\n children: content,\n };\n }\n\n /**\n * Create a table node\n */\n table(rows: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'table',\n attrs,\n children: rows,\n };\n }\n\n /**\n * Create a table row node\n */\n tableRow(cells: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'table_row',\n attrs,\n children: cells,\n };\n }\n\n /**\n * Create a table cell node\n */\n tableCell(content: BlockNode[], attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'table_cell',\n attrs,\n children: content,\n };\n }\n\n /**\n * Create an image node\n */\n image(src: string, alt?: string, attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'image',\n attrs: { src, alt: alt || '', decorative: !alt, ...attrs },\n children: [],\n };\n }\n\n /**\n * Create a code block node\n */\n codeBlock(content: string, attrs?: BlockAttrs): BlockNode {\n return {\n id: generateBlockId(),\n type: 'code_block',\n attrs,\n children: [this.text(content)],\n };\n }\n\n /**\n * Create a generic block node\n */\n block(type: NodeType, attrs?: BlockAttrs, children?: (TextNode | BlockNode)[]): BlockNode {\n const spec = this.schema.node(type);\n if (!spec) {\n throw new Error(`Unknown node type: ${type}`);\n }\n\n return {\n id: generateBlockId(),\n type,\n attrs,\n children,\n };\n }\n\n /**\n * Create a mark\n */\n mark(type: string, attrs?: Record<string, unknown>): Mark {\n const spec = this.schema.mark(type);\n if (!spec) {\n throw new Error(`Unknown mark type: ${type}`);\n }\n\n return {\n type,\n attrs,\n };\n }\n\n /**\n * Clone a node with new children\n */\n cloneNode(node: BlockNode, children?: (TextNode | BlockNode)[]): BlockNode {\n return {\n ...node,\n id: generateBlockId(), // Generate new ID for cloned node\n children: children !== undefined ? children : node.children,\n };\n }\n}\n\n/**\n * Create a node factory with the given schema\n */\nexport function createNodeFactory(schema: Schema): NodeFactory {\n return new NodeFactory(schema);\n}\n","/**\n * Editor state management\n * Maintains the document state and provides methods for querying and updating\n */\n\nimport type { Document, Selection, BlockNode, BlockId, Node } from '../types/index.js';\nimport { Schema, createDefaultSchema } from '../schema/Schema.js';\nimport { NodeFactory, createNodeFactory } from '../schema/NodeFactory.js';\nimport type { Delta } from '../delta/Delta.js';\nimport type { Operation } from '../delta/Operations.js';\n\n/**\n * History entry for undo/redo\n */\ninterface HistoryEntry {\n delta: Delta;\n inverseOps: Operation[];\n timestamp: number;\n}\n\n/**\n * Editor state class\n */\nexport class EditorState {\n private document: Document;\n private selection: Selection | null = null;\n private history: HistoryEntry[] = [];\n private historyIndex: number = -1;\n private maxHistoryDepth: number;\n \n readonly schema: Schema;\n readonly nodeFactory: NodeFactory;\n\n constructor(\n initialDoc?: Document,\n schema?: Schema,\n options?: { maxHistoryDepth?: number }\n ) {\n this.schema = schema || createDefaultSchema();\n this.nodeFactory = createNodeFactory(this.schema);\n this.maxHistoryDepth = options?.maxHistoryDepth || 100;\n\n this.document = initialDoc || {\n version: 0,\n schemaVersion: '1.0.0',\n children: [this.nodeFactory.paragraph()],\n };\n }\n\n /**\n * Get current document\n */\n getDocument(): Document {\n return this.document;\n }\n\n /**\n * Get document version\n */\n getVersion(): number {\n return this.document.version;\n }\n\n /**\n * Get current selection\n */\n getSelection(): Selection | null {\n return this.selection;\n }\n\n /**\n * Set selection\n */\n setSelection(selection: Selection | null): void {\n this.selection = selection;\n }\n\n /**\n * Apply a delta to the state\n */\n applyDelta(delta: Delta): void {\n // Validate delta version\n if (delta.baseVersion !== this.document.version) {\n throw new Error(\n `Delta version mismatch: expected ${this.document.version}, got ${delta.baseVersion}`\n );\n }\n\n // Store in history (only if not a selection update)\n const hasContentOps = delta.ops.some((op) => op.op !== 'update_selection');\n if (hasContentOps) {\n this.addToHistory(delta);\n }\n\n // Apply each operation\n for (const op of delta.ops) {\n this.applyOperation(op);\n }\n\n // Increment version\n this.document.version++;\n }\n\n /**\n * Apply a single operation\n */\n private applyOperation(op: Operation): void {\n switch (op.op) {\n case 'insert_text':\n this.applyInsertText(op);\n break;\n case 'delete_range':\n this.applyDeleteRange(op);\n break;\n case 'apply_mark':\n this.applyMark(op);\n break;\n case 'insert_block_after':\n this.applyInsertBlockAfter(op);\n break;\n case 'insert_block_before':\n this.applyInsertBlockBefore(op);\n break;\n case 'delete_block':\n this.applyDeleteBlock(op);\n break;\n case 'set_attrs':\n this.applySetAttrs(op);\n break;\n case 'update_selection':\n this.selection = {\n anchor: op.selection.anchor,\n head: op.selection.head,\n };\n break;\n // Table operations would be implemented here\n default:\n console.warn('Unhandled operation type:', (op as Operation).op);\n }\n }\n\n /**\n * Apply insert text operation\n */\n private applyInsertText(op: Extract<Operation, { op: 'insert_text' }>): void {\n const block = this.findBlock(op.target.blockId);\n if (!block || !block.children) return;\n\n // Find text node at offset and insert text\n // Simplified implementation - would need proper offset handling\n const textNode = block.children.find((n): n is Extract<Node, { type: 'text' }> => 'text' in n);\n if (textNode) {\n const before = textNode.text.slice(0, op.target.offset);\n const after = textNode.text.slice(op.target.offset);\n textNode.text = before + op.text + after;\n if (op.marks && op.marks.length > 0) {\n textNode.marks = op.marks;\n }\n }\n }\n\n /**\n * Apply delete range operation\n */\n private applyDeleteRange(op: Extract<Operation, { op: 'delete_range' }>): void {\n const block = this.findBlock(op.range.start.blockId);\n if (!block || !block.children) return;\n\n const textNode = block.children.find((n): n is Extract<Node, { type: 'text' }> => 'text' in n);\n if (textNode) {\n const before = textNode.text.slice(0, op.range.start.offset);\n const after = textNode.text.slice(op.range.end.offset);\n textNode.text = before + after;\n }\n }\n\n /**\n * Apply mark operation\n */\n private applyMark(op: Extract<Operation, { op: 'apply_mark' }>): void {\n const block = this.findBlock(op.range.start.blockId);\n if (!block || !block.children) return;\n\n const textNode = block.children.find((n): n is Extract<Node, { type: 'text' }> => 'text' in n);\n if (textNode) {\n if (op.add) {\n textNode.marks = textNode.marks || [];\n if (!textNode.marks.some((m) => m.type === op.mark.type)) {\n textNode.marks.push(op.mark);\n }\n } else {\n textNode.marks = textNode.marks?.filter((m) => m.type !== op.mark.type);\n }\n }\n }\n\n /**\n * Apply insert block after operation\n */\n private applyInsertBlockAfter(op: Extract<Operation, { op: 'insert_block_after' }>): void {\n const index = this.document.children.findIndex((b) => b.id === op.after);\n if (index !== -1) {\n this.document.children.splice(index + 1, 0, op.block);\n }\n }\n\n /**\n * Apply insert block before operation\n */\n private applyInsertBlockBefore(op: Extract<Operation, { op: 'insert_block_before' }>): void {\n const index = this.document.children.findIndex((b) => b.id === op.before);\n if (index !== -1) {\n this.document.children.splice(index, 0, op.block);\n }\n }\n\n /**\n * Apply delete block operation\n */\n private applyDeleteBlock(op: Extract<Operation, { op: 'delete_block' }>): void {\n const index = this.document.children.findIndex((b) => b.id === op.target.blockId);\n if (index !== -1) {\n this.document.children.splice(index, 1);\n }\n }\n\n /**\n * Apply set attributes operation\n */\n private applySetAttrs(op: Extract<Operation, { op: 'set_attrs' }>): void {\n const block = this.findBlock(op.target.blockId);\n if (block) {\n block.attrs = { ...block.attrs, ...op.attrs };\n }\n }\n\n /**\n * Find a block by ID\n */\n findBlock(blockId: BlockId): BlockNode | undefined {\n const search = (nodes: BlockNode[]): BlockNode | undefined => {\n for (const node of nodes) {\n if (node.id === blockId) {\n return node;\n }\n if (node.children) {\n const blockChildren = node.children.filter((n): n is BlockNode => 'id' in n);\n const found = search(blockChildren);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n return search(this.document.children);\n }\n\n /**\n * Add delta to history\n */\n private addToHistory(delta: Delta): void {\n // Remove any redo entries\n if (this.historyIndex < this.history.length - 1) {\n this.history = this.history.slice(0, this.historyIndex + 1);\n }\n\n // Add to history\n this.history.push({\n delta,\n inverseOps: delta.inverseOps || [],\n timestamp: Date.now(),\n });\n\n // Maintain max depth\n if (this.history.length > this.maxHistoryDepth) {\n this.history.shift();\n } else {\n this.historyIndex++;\n }\n }\n\n /**\n * Undo last change\n */\n canUndo(): boolean {\n return this.historyIndex >= 0;\n }\n\n undo(): Delta | null {\n if (!this.canUndo()) return null;\n\n const entry = this.history[this.historyIndex];\n this.historyIndex--;\n\n // Create undo delta with inverse operations\n return {\n txnId: `undo-${entry.delta.txnId}`,\n clientId: entry.delta.clientId,\n timestamp: new Date().toISOString(),\n baseVersion: this.document.version,\n ltime: Date.now(),\n intent: 'edit',\n ops: entry.inverseOps,\n };\n }\n\n /**\n * Redo last undone change\n */\n canRedo(): boolean {\n return this.historyIndex < this.history.length - 1;\n }\n\n redo(): Delta | null {\n if (!this.canRedo()) return null;\n\n this.historyIndex++;\n const entry = this.history[this.historyIndex];\n\n return entry.delta;\n }\n\n /**\n * Export state as JSON\n */\n toJSON(): Document {\n return this.document;\n }\n\n /**\n * Create state from JSON\n */\n static fromJSON(json: Document, schema?: Schema): EditorState {\n return new EditorState(json, schema);\n }\n}\n","/**\n * Constants for Notectl Editor\n * Exported to avoid magic numbers and improve maintainability\n */\n\n/**\n * Timeout in milliseconds to wait for editor's connectedCallback to complete\n * and render the DOM structure including plugin containers.\n *\n * This is needed when registering plugins immediately after appending the editor\n * to the DOM, as the connectedCallback runs asynchronously.\n *\n * @example\n * ```typescript\n * const editor = document.createElement('notectl-editor');\n * container.appendChild(editor);\n * await new Promise(resolve => setTimeout(resolve, EDITOR_READY_TIMEOUT));\n * await editor.registerPlugin(new ToolbarPlugin());\n * ```\n */\nexport const EDITOR_READY_TIMEOUT = 100; // ms\n\n/**\n * Default timeout for screen reader announcements\n * Used to clear and reset the aria-live region\n */\nexport const ARIA_ANNOUNCEMENT_DELAY = 100; // ms\n\n/**\n * Default maximum number of history entries to keep\n */\nexport const DEFAULT_MAX_HISTORY_DEPTH = 100;\n\n/**\n * Default minimum height for the editor content area\n */\nexport const DEFAULT_MIN_HEIGHT = 200; // px\n\n/**\n * Error codes for structured error handling\n */\nexport const ErrorCodes = {\n // Plugin-related errors\n PLUGIN_ALREADY_REGISTERED: 'PLUGIN_ALREADY_REGISTERED',\n PLUGIN_NOT_FOUND: 'PLUGIN_NOT_FOUND',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n PLUGIN_INVALID_CONFIG: 'PLUGIN_INVALID_CONFIG',\n PLUGIN_INIT_FAILED: 'PLUGIN_INIT_FAILED',\n PLUGIN_DESTROY_FAILED: 'PLUGIN_DESTROY_FAILED',\n PLUGIN_DEPENDENCY_CONFLICT: 'PLUGIN_DEPENDENCY_CONFLICT',\n\n // Editor state errors\n EDITOR_NOT_MOUNTED: 'EDITOR_NOT_MOUNTED',\n EDITOR_NOT_INITIALIZED: 'EDITOR_NOT_INITIALIZED',\n EDITOR_DESTROYED: 'EDITOR_DESTROYED',\n\n // Command errors\n COMMAND_NOT_FOUND: 'COMMAND_NOT_FOUND',\n COMMAND_ALREADY_REGISTERED: 'COMMAND_ALREADY_REGISTERED',\n COMMAND_EXECUTION_FAILED: 'COMMAND_EXECUTION_FAILED',\n COMMAND_INVALID_ARGS: 'COMMAND_INVALID_ARGS',\n\n // Content errors\n INVALID_CONTENT: 'INVALID_CONTENT',\n INVALID_DELTA: 'INVALID_DELTA',\n INVALID_DOCUMENT: 'INVALID_DOCUMENT',\n SANITIZATION_FAILED: 'SANITIZATION_FAILED',\n\n // Security errors\n XSS_DETECTED: 'XSS_DETECTED',\n UNSAFE_OPERATION: 'UNSAFE_OPERATION',\n\n // General errors\n INVALID_OPERATION: 'INVALID_OPERATION',\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n} as const;\n\n/**\n * Type for error codes\n */\nexport type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];\n\n/**\n * Structured error class for Notectl\n */\nexport class NotectlError extends Error {\n constructor(\n public code: ErrorCode,\n message: string,\n public details?: unknown\n ) {\n super(message);\n this.name = 'NotectlError';\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, NotectlError);\n }\n }\n\n /**\n * Convert to JSON-serializable format\n */\n toJSON() {\n return {\n error: {\n code: this.code,\n message: this.message,\n details: this.details,\n }\n };\n }\n}\n\n/**\n * Validation constraints for document structure\n */\nexport const ValidationConstraints = {\n NO_DANGLING_REFS: 'noDanglingRefs',\n TABLE_GRID_CONSISTENT: 'tableGridConsistent',\n ALT_OR_DECORATIVE: 'altOrDecorative',\n RTL_INTEGRITY: 'rtlIntegrity',\n} as const;\n","/**\n * Plugin manager for registering and managing plugins\n */\n\nimport type { Plugin, PluginContext } from './Plugin.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Delta } from '../delta/Delta.js';\nimport { ErrorCodes, NotectlError } from '../constants.js';\n\n/**\n * Plugin manager class\n */\nexport class PluginManager {\n private plugins: Map<string, Plugin> = new Map();\n private initializationOrder: string[] = [];\n\n constructor() {}\n\n /**\n * Register a plugin\n *\n * @param plugin - The plugin to register\n * @param context - Plugin context with editor APIs\n * @throws {NotectlError} If plugin validation fails or initialization errors occur\n *\n * @example\n * ```typescript\n * const toolbarPlugin = new ToolbarPlugin();\n * await pluginManager.register(toolbarPlugin, context);\n * ```\n */\n async register(plugin: Plugin, context: PluginContext): Promise<void> {\n // Validate plugin object\n if (!plugin) {\n throw new NotectlError(\n ErrorCodes.PLUGIN_INVALID_CONFIG,\n 'Cannot register null or undefined plugin'\n );\n }\n\n if (!plugin.id || typeof plugin.id !== 'string') {\n throw new NotectlError(\n ErrorCodes.PLUGIN_INVALID_CONFIG,\n 'Plugin must have a valid string \"id\" property',\n { plugin }\n );\n }\n\n if (!plugin.name || typeof plugin.name !== 'string') {\n throw new NotectlError(\n ErrorCodes.PLUGIN_INVALID_CONFIG,\n `Plugin \"${plugin.id}\" must have a valid string \"name\" property`,\n { pluginId: plugin.id }\n );\n }\n\n if (!plugin.version || typeof plugin.version !== 'string') {\n throw new NotectlError(\n ErrorCodes.PLUGIN_INVALID_CONFIG,\n `Plugin \"${plugin.id}\" must have a valid string \"version\" property`,\n { pluginId: plugin.id, pluginName: plugin.name }\n );\n }\n\n if (typeof plugin.init !== 'function') {\n throw new NotectlError(\n ErrorCodes.PLUGIN_INVALID_CONFIG,\n `Plugin \"${plugin.id}\" must have an \"init\" method`,\n { pluginId: plugin.id, pluginName: plugin.name }\n );\n }\n\n // Check if already registered\n if (this.plugins.has(plugin.id)) {\n const existing = this.plugins.get(plugin.id)!;\n throw new NotectlError(\n ErrorCodes.PLUGIN_ALREADY_REGISTERED,\n `Plugin \"${plugin.id}\" is already registered (version: ${existing.version})`,\n { pluginId: plugin.id, existingVersion: existing.version, newVersion: plugin.version }\n );\n }\n\n // Check dependencies\n if (plugin.dependencies && plugin.dependencies.length > 0) {\n const missingDeps: string[] = [];\n\n for (const depId of plugin.dependencies) {\n if (!this.plugins.has(depId)) {\n missingDeps.push(depId);\n }\n }\n\n if (missingDeps.length > 0) {\n throw new NotectlError(\n ErrorCodes.PLUGIN_MISSING_DEPENDENCY,\n `Plugin \"${plugin.id}\" (${plugin.name}) cannot be registered because the following dependencies are missing: ${missingDeps.join(', ')}. Please register these plugins first.`,\n {\n pluginId: plugin.id,\n pluginName: plugin.name,\n missingDependencies: missingDeps,\n registeredPlugins: Array.from(this.plugins.keys())\n }\n );\n }\n }\n\n // Initialize plugin\n try {\n await plugin.init(context);\n } catch (error) {\n throw new NotectlError(\n ErrorCodes.PLUGIN_INIT_FAILED,\n `Failed to initialize plugin \"${plugin.id}\" (${plugin.name}): ${error instanceof Error ? error.message : String(error)}`,\n {\n pluginId: plugin.id,\n pluginName: plugin.name,\n originalError: error\n }\n );\n }\n\n // Store plugin\n this.plugins.set(plugin.id, plugin);\n this.initializationOrder.push(plugin.id);\n\n // Emit event\n context.emit('plugin-registered', { pluginId: plugin.id, plugin });\n }\n\n /**\n * Unregister a plugin\n *\n * @param pluginId - ID of the plugin to unregister\n * @param context - Plugin context for event emission\n * @throws {NotectlError} If plugin is not found or has dependents\n *\n * @example\n * ```typescript\n * await pluginManager.unregister('toolbar-plugin', context);\n * ```\n */\n async unregister(pluginId: string, context: PluginContext): Promise<void> {\n // Validate plugin ID\n if (!pluginId || typeof pluginId !== 'string') {\n throw new NotectlError(\n ErrorCodes.PLUGIN_NOT_FOUND,\n 'Plugin ID must be a non-empty string',\n { pluginId }\n );\n }\n\n // Check if plugin exists\n const plugin = this.plugins.get(pluginId);\n if (!plugin) {\n throw new NotectlError(\n ErrorCodes.PLUGIN_NOT_FOUND,\n `Plugin \"${pluginId}\" is not registered and cannot be unregistered`,\n {\n pluginId,\n registeredPlugins: Array.from(this.plugins.keys())\n }\n );\n }\n\n // Check if other plugins depend on this one\n const dependentPlugins: string[] = [];\n for (const [id, p] of this.plugins.entries()) {\n if (p.dependencies?.includes(pluginId)) {\n dependentPlugins.push(`${id} (${p.name})`);\n }\n }\n\n if (dependentPlugins.length > 0) {\n throw new NotectlError(\n ErrorCodes.PLUGIN_DEPENDENCY_CONFLICT,\n `Cannot unregister plugin \"${pluginId}\" (${plugin.name}) because the following plugins depend on it: ${dependentPlugins.join(', ')}. Please unregister dependent plugins first.`,\n {\n pluginId,\n pluginName: plugin.name,\n dependentPlugins: dependentPlugins\n }\n );\n }\n\n // Destroy plugin\n if (plugin.destroy) {\n try {\n await plugin.destroy();\n } catch (error) {\n throw new NotectlError(\n ErrorCodes.PLUGIN_DESTROY_FAILED,\n `Failed to destroy plugin \"${pluginId}\" (${plugin.name}): ${error instanceof Error ? error.message : String(error)}`,\n {\n pluginId,\n pluginName: plugin.name,\n originalError: error\n }\n );\n }\n }\n\n // Remove plugin\n this.plugins.delete(pluginId);\n this.initializationOrder = this.initializationOrder.filter((id) => id !== pluginId);\n\n // Emit event\n context.emit('plugin-unregistered', { pluginId });\n }\n\n /**\n * Get a plugin by ID\n */\n get(pluginId: string): Plugin | undefined {\n return this.plugins.get(pluginId);\n }\n\n /**\n * Check if a plugin is registered\n */\n has(pluginId: string): boolean {\n return this.plugins.has(pluginId);\n }\n\n /**\n * Get all registered plugins\n */\n getAll(): Plugin[] {\n return this.initializationOrder.map((id) => this.plugins.get(id)!);\n }\n\n /**\n * Notify plugins of state update\n */\n notifyStateUpdate(oldState: EditorState, newState: EditorState): void {\n for (const pluginId of this.initializationOrder) {\n const plugin = this.plugins.get(pluginId);\n if (plugin?.onStateUpdate) {\n try {\n plugin.onStateUpdate(oldState, newState);\n } catch (error) {\n console.error(`Error in plugin ${pluginId} onStateUpdate:`, error);\n }\n }\n }\n }\n\n /**\n * Notify plugins of delta application\n */\n notifyDeltaApplied(delta: Delta): void {\n for (const pluginId of this.initializationOrder) {\n const plugin = this.plugins.get(pluginId);\n if (plugin?.onDeltaApplied) {\n try {\n plugin.onDeltaApplied(delta);\n } catch (error) {\n console.error(`Error in plugin ${pluginId} onDeltaApplied:`, error);\n }\n }\n }\n }\n\n /**\n * Destroy all plugins\n */\n async destroyAll(): Promise<void> {\n // Destroy in reverse order\n const pluginIds = [...this.initializationOrder].reverse();\n \n for (const pluginId of pluginIds) {\n const plugin = this.plugins.get(pluginId);\n if (plugin?.destroy) {\n try {\n await plugin.destroy();\n } catch (error) {\n console.error(`Error destroying plugin ${pluginId}:`, error);\n }\n }\n }\n\n this.plugins.clear();\n this.initializationOrder = [];\n }\n}\n","/*! @license DOMPurify 3.2.7 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.7/LICENSE */\n\nconst {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor\n} = Object;\nlet {\n freeze,\n seal,\n create\n} = Object; // eslint-disable-line import/no-mutable-exports\nlet {\n apply,\n construct\n} = typeof Reflect !== 'undefined' && Reflect;\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\nif (!apply) {\n apply = function apply(func, thisArg) {\n for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n args[_key - 2] = arguments[_key];\n }\n return func.apply(thisArg, args);\n };\n}\nif (!construct) {\n construct = function construct(Func) {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n return new Func(...args);\n };\n}\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySplice = unapply(Array.prototype.splice);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param func - The function to be wrapped and called.\n * @returns A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return function (thisArg) {\n if (thisArg instanceof RegExp) {\n thisArg.lastIndex = 0;\n }\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n return apply(func, thisArg, args);\n };\n}\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param func - The constructor function to be wrapped and called.\n * @returns A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(Func) {\n return function () {\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n return construct(Func, args);\n };\n}\n/**\n * Add properties to a lookup table\n *\n * @param set - The set to which elements will be added.\n * @param array - The array containing elements to be added to the set.\n * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns The modified set with added elements.\n */\nfunction addToSet(set, array) {\n let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n element = lcElement;\n }\n }\n set[element] = true;\n }\n return set;\n}\n/**\n * Clean up an array to harden against CSPP\n *\n * @param array - The array to be cleaned.\n * @returns The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n return array;\n}\n/**\n * Shallow clone an object\n *\n * @param object - The object to be cloned.\n * @returns A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (value && typeof value === 'object' && value.constructor === Object) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n return newObject;\n}\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param object - The object to look up the getter function in its prototype chain.\n * @param prop - The property name for which to find the getter function.\n * @returns The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n object = getPrototypeOf(object);\n }\n function fallbackValue() {\n return null;\n }\n return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'slot', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\n// eslint-disable-next-line unicorn/better-regex\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\$\\{[\\w\\W]*/gm); // eslint-disable-line unicorn/better-regex\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]+$/); // eslint-disable-line no-useless-escape\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\nconst CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n __proto__: null,\n ARIA_ATTR: ARIA_ATTR,\n ATTR_WHITESPACE: ATTR_WHITESPACE,\n CUSTOM_ELEMENT: CUSTOM_ELEMENT,\n DATA_ATTR: DATA_ATTR,\n DOCTYPE_NAME: DOCTYPE_NAME,\n ERB_EXPR: ERB_EXPR,\n IS_ALLOWED_URI: IS_ALLOWED_URI,\n IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n MUSTACHE_EXPR: MUSTACHE_EXPR,\n TMPLIT_EXPR: TMPLIT_EXPR\n});\n\n/* eslint-disable @typescript-eslint/indent */\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5,\n // Deprecated\n entityNode: 6,\n // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12 // Deprecated\n};\nconst getGlobal = function getGlobal() {\n return typeof window === 'undefined' ? null : window;\n};\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param trustedTypes The policy factory.\n * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n }\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n }\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\nconst _createHooksMap = function _createHooksMap() {\n return {\n afterSanitizeAttributes: [],\n afterSanitizeElements: [],\n afterSanitizeShadowDOM: [],\n beforeSanitizeAttributes: [],\n beforeSanitizeElements: [],\n beforeSanitizeShadowDOM: [],\n uponSanitizeAttribute: [],\n uponSanitizeElement: [],\n uponSanitizeShadowNode: []\n };\n};\nfunction createDOMPurify() {\n let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n const DOMPurify = root => createDOMPurify(root);\n DOMPurify.version = '3.2.7';\n DOMPurify.removed = [];\n if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n return DOMPurify;\n }\n let {\n document\n } = window;\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes\n } = window;\n const ElementPrototype = Element.prototype;\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n let trustedTypesPolicy;\n let emptyHTML = '';\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName\n } = document;\n const {\n importNode\n } = originalDocument;\n let hooks = _createHooksMap();\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT\n } = EXPRESSIONS;\n let {\n IS_ALLOWED_URI: IS_ALLOWED_URI$1\n } = EXPRESSIONS;\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n /*\n * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false\n }\n }));\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']);\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n const formElement = document.createElement('form');\n const isRegexOrFunction = function isRegexOrFunction(testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n /**\n * _parseConfig\n *\n * @param cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function _parseConfig() {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS;\n HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html$1);\n addToSet(ALLOWED_ATTR, html);\n }\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg$1);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl$1);\n addToSet(ALLOWED_ATTR, mathMl);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n }\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n }\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n }\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n CONFIG = cfg;\n };\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);\n const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);\n /**\n * @param element a DOM element whose namespace is being checked\n * @returns Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function _checkValidNamespace(element) {\n let parent = getParentNode(element);\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template'\n };\n }\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either <annotation-xml> or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n }\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n }\n // For XHTML and XML documents that support custom namespaces\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n return true;\n }\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n /**\n * _forceRemove\n *\n * @param node a DOM node\n */\n const _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, {\n element: node\n });\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n /**\n * _removeAttribute\n *\n * @param name an Attribute name\n * @param element a DOM node\n */\n const _removeAttribute = function _removeAttribute(name, element) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: element.getAttributeNode(name),\n from: element\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: element\n });\n }\n element.removeAttribute(name);\n // We void attribute values for unremovable \"is\" attributes\n if (name === 'is') {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(element);\n } catch (_) {}\n } else {\n try {\n element.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n /**\n * _initDocument\n *\n * @param dirty - a string of dirty markup\n * @return a DOM, filled with the dirty markup\n */\n const _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty = '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' + dirty + '</body></html>';\n }\n const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n const body = doc.body || doc.documentElement;\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param root The root element or node to start traversing on.\n * @return The created NodeIterator\n */\n const _createNodeIterator = function _createNodeIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);\n };\n /**\n * _isClobbered\n *\n * @param element element to check for clobbering attacks\n * @return true if clobbered, false if safe\n */\n const _isClobbered = function _isClobbered(element) {\n return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function');\n };\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param value object to check whether it's a DOM node\n * @return true is object is a DOM node\n */\n const _isNode = function _isNode(value) {\n return typeof Node === 'function' && value instanceof Node;\n };\n function _executeHooks(hooks, currentNode, data) {\n arrayForEach(hooks, hook => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n }\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n * @param currentNode to check for permission to exist\n * @return true if node was killed, false if left alive\n */\n const _sanitizeElements = function _sanitizeElements(currentNode) {\n let content = null;\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeElements, currentNode, null);\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeElement, currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS\n });\n /* Detect mXSS attempts abusing namespace confusion */\n if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\\w!]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove any kind of possibly harmful comments */\n if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\\w]/g, currentNode.data)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {\n return false;\n }\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {\n return false;\n }\n }\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n _forceRemove(currentNode);\n return true;\n }\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n return true;\n }\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n content = stringReplace(content, expr, ' ');\n });\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, {\n element: currentNode.cloneNode()\n });\n currentNode.textContent = content;\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeElements, currentNode, null);\n return false;\n };\n /**\n * _isValidAttribute\n *\n * @param lcTag Lowercase tag name of containing element.\n * @param lcName Lowercase attribute name.\n * @param value Attribute value.\n * @return Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n return false;\n } else ;\n return true;\n };\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param tagName name of the tag of the node to sanitize\n * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function _isBasicCustomElement(tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param currentNode to sanitize\n */\n const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);\n const {\n attributes\n } = currentNode;\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes || _isClobbered(currentNode)) {\n return;\n }\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n forceKeepAttr: undefined\n };\n let l = attributes.length;\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const {\n name,\n namespaceURI,\n value: attrValue\n } = attr;\n const lcName = transformCaseFunc(name);\n const initValue = attrValue;\n let value = name === 'value' ? initValue : stringTrim(initValue);\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);\n value = hookEvent.attrValue;\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title|textarea)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Make sure we cannot easily use animated hrefs, even if animations are allowed */\n if (lcName === 'attributename' && stringMatch(value, 'href')) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n value = stringReplace(value, expr, ' ');\n });\n }\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n /* Handle attributes that require Trusted Types */\n if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n if (namespaceURI) ; else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML':\n {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n case 'TrustedScriptURL':\n {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n }\n }\n }\n /* Handle invalid data-* attribute set by try-catching it */\n if (value !== initValue) {\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {\n _removeAttribute(name, currentNode);\n }\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);\n };\n /**\n * _sanitizeShadowDOM\n *\n * @param fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n /* Execute a hook if present */\n _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);\n /* Sanitize tags and elements */\n _sanitizeElements(shadowNode);\n /* Check attributes next */\n _sanitizeAttributes(shadowNode);\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n }\n /* Execute a hook if present */\n _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);\n };\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty) {\n let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n /* Clean up removed elements */\n DOMPurify.removed = [];\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n /* Now start iterating over the created document */\n while (currentNode = nodeIterator.nextNode()) {\n /* Sanitize tags and elements */\n _sanitizeElements(currentNode);\n /* Check attributes next */\n _sanitizeAttributes(currentNode);\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n }\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n return returnNode;\n }\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n /* Serialize doctype if allowed */\n if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n DOMPurify.setConfig = function () {\n let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n arrayPush(hooks[entryPoint], hookFunction);\n };\n DOMPurify.removeHook = function (entryPoint, hookFunction) {\n if (hookFunction !== undefined) {\n const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);\n return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];\n }\n return arrayPop(hooks[entryPoint]);\n };\n DOMPurify.removeHooks = function (entryPoint) {\n hooks[entryPoint] = [];\n };\n DOMPurify.removeAllHooks = function () {\n hooks = _createHooksMap();\n };\n return DOMPurify;\n}\nvar purify = createDOMPurify();\n\nexport { purify as default };\n//# sourceMappingURL=purify.es.mjs.map\n","/**\n * Security utilities for XSS prevention and content sanitization\n */\n\nimport DOMPurify from 'dompurify';\nimport type { Delta } from '../delta/Delta.js';\nimport type { Config } from 'dompurify';\n\n/**\n * DOMPurify configuration for editor content\n */\nconst EDITOR_SANITIZE_CONFIG: Config = {\n ALLOWED_TAGS: [\n 'p', 'br', 'strong', 'em', 'u', 's', 'code', 'pre',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'ul', 'ol', 'li',\n 'blockquote',\n 'a', 'img',\n 'table', 'thead', 'tbody', 'tr', 'th', 'td',\n 'div', 'span'\n ],\n ALLOWED_ATTR: [\n 'href', 'src', 'alt', 'title', 'class', 'id',\n 'style', 'data-*',\n 'role', 'aria-*'\n ],\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\n KEEP_CONTENT: true,\n SANITIZE_DOM: true,\n SAFE_FOR_TEMPLATES: true,\n};\n\n/**\n * Strict DOMPurify configuration for untrusted content\n */\nconst STRICT_SANITIZE_CONFIG: Config = {\n ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'u', 'code'],\n ALLOWED_ATTR: [],\n KEEP_CONTENT: true,\n SANITIZE_DOM: true,\n SAFE_FOR_TEMPLATES: true,\n};\n\n/**\n * Sanitize HTML content using DOMPurify\n * @param html - HTML content to sanitize\n * @param strict - Use strict configuration (default: false)\n * @returns Sanitized HTML\n */\nexport function sanitizeHTML(html: string, strict: boolean = false): string {\n const config = strict ? STRICT_SANITIZE_CONFIG : EDITOR_SANITIZE_CONFIG;\n return DOMPurify.sanitize(html, config) as string;\n}\n\n/**\n * Sanitize user content (text and HTML)\n * @param content - Content to sanitize\n * @param allowHTML - Allow HTML tags (default: true)\n * @returns Sanitized content\n */\nexport function sanitizeContent(content: string, allowHTML: boolean = true): string {\n if (!allowHTML) {\n // Escape all HTML\n return escapeHTML(content);\n }\n\n // Sanitize HTML while preserving allowed tags\n return sanitizeHTML(content);\n}\n\n/**\n * Escape HTML entities\n * @param text - Text to escape\n * @returns Escaped text\n */\nexport function escapeHTML(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n}\n\n/**\n * Unescape HTML entities\n * @param html - HTML to unescape\n * @returns Unescaped text\n */\nexport function unescapeHTML(html: string): string {\n const div = document.createElement('div');\n div.innerHTML = html;\n return div.textContent || '';\n}\n\n/**\n * Validate delta operations for potential XSS\n * @param delta - Delta to validate\n * @returns True if delta is safe\n */\nexport function validateDelta(delta: Delta): boolean {\n try {\n // Check if delta has required structure\n if (!delta || typeof delta !== 'object') {\n return false;\n }\n\n // Validate operations array\n if (!Array.isArray(delta.ops)) {\n return false;\n }\n\n // Check each operation\n for (const op of delta.ops) {\n // Validate insert operations\n if ('insert' in op) {\n const insert = op.insert;\n\n // Check for script injection in strings\n if (typeof insert === 'string') {\n const sanitized = sanitizeHTML(insert);\n if (sanitized !== insert && insert.includes('<script')) {\n return false;\n }\n }\n\n // Check for dangerous attributes\n if (typeof insert === 'object' && insert !== null) {\n const insertObj = insert as Record<string, unknown>;\n if ('script' in insertObj || 'onerror' in insertObj || 'onclick' in insertObj) {\n return false;\n }\n }\n }\n\n // Validate attributes\n if ('attributes' in op && op.attributes) {\n const attrs = op.attributes as Record<string, unknown>;\n\n // Check for event handlers\n for (const key in attrs) {\n if (key.startsWith('on') || key.toLowerCase().includes('script')) {\n return false;\n }\n }\n }\n }\n\n return true;\n } catch (error) {\n console.error('Error validating delta:', error);\n return false;\n }\n}\n\n/**\n * Prevent XSS in URLs\n * @param url - URL to validate\n * @returns Sanitized URL or empty string if invalid\n */\nexport function sanitizeURL(url: string): string {\n try {\n const trimmed = url.trim();\n\n // Block javascript: and data: URLs\n if (\n trimmed.toLowerCase().startsWith('javascript:') ||\n trimmed.toLowerCase().startsWith('data:') ||\n trimmed.toLowerCase().startsWith('vbscript:')\n ) {\n return '';\n }\n\n // Validate URL format\n const urlObj = new URL(trimmed, window.location.origin);\n\n // Only allow http, https, mailto, tel protocols\n const allowedProtocols = ['http:', 'https:', 'mailto:', 'tel:'];\n if (!allowedProtocols.includes(urlObj.protocol)) {\n return '';\n }\n\n return urlObj.href;\n } catch {\n // Invalid URL\n return '';\n }\n}\n\n/**\n * Create a safe HTML string with sanitization\n * @param strings - Template strings\n * @param values - Template values\n * @returns Sanitized HTML\n */\nexport function safeHTML(strings: TemplateStringsArray, ...values: unknown[]): string {\n let html = strings[0];\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n const escaped = typeof value === 'string' ? escapeHTML(value) : String(value);\n html += escaped + strings[i + 1];\n }\n\n return sanitizeHTML(html);\n}\n\n/**\n * Remove dangerous attributes from an element\n * @param element - Element to clean\n */\nexport function removeDangerousAttributes(element: Element): void {\n const dangerousAttrs = [\n 'onerror', 'onload', 'onclick', 'onmouseover', 'onfocus', 'onblur',\n 'onchange', 'onsubmit', 'onkeydown', 'onkeyup', 'onkeypress'\n ];\n\n dangerousAttrs.forEach(attr => {\n if (element.hasAttribute(attr)) {\n element.removeAttribute(attr);\n }\n });\n\n // Check all attributes for javascript:\n Array.from(element.attributes).forEach(attr => {\n if (attr.value.toLowerCase().includes('javascript:')) {\n element.removeAttribute(attr.name);\n }\n });\n}\n\n/**\n * Sanitize DOM element and its children\n * @param element - Element to sanitize\n */\nexport function sanitizeElement(element: Element): void {\n // Remove dangerous attributes from current element\n removeDangerousAttributes(element);\n\n // Recursively sanitize children\n Array.from(element.children).forEach(child => {\n sanitizeElement(child);\n });\n}\n\n/**\n * Check if content contains potential XSS\n * @param content - Content to check\n * @returns True if potentially dangerous\n */\nexport function containsXSS(content: string): boolean {\n const dangerous = [\n '<script',\n 'javascript:',\n 'onerror=',\n 'onclick=',\n 'onload=',\n '<iframe',\n '<object',\n '<embed',\n 'data:text/html'\n ];\n\n const lower = content.toLowerCase();\n return dangerous.some(pattern => lower.includes(pattern));\n}\n","/**\n * Accessibility utilities for ARIA attributes and screen reader support\n */\n\n/**\n * ARIA live region politeness levels\n */\nexport type AriaLive = 'off' | 'polite' | 'assertive';\n\n/**\n * Keyboard shortcut configuration\n */\nexport interface KeyboardShortcut {\n key: string;\n ctrlKey?: boolean;\n metaKey?: boolean;\n shiftKey?: boolean;\n altKey?: boolean;\n description: string;\n action: () => void;\n}\n\n/**\n * Focus trap configuration\n */\nexport interface FocusTrapConfig {\n container: HTMLElement;\n initialFocus?: HTMLElement;\n returnFocus?: HTMLElement;\n escapeDeactivates?: boolean;\n}\n\n/**\n * Announce message to screen readers\n * @param message - Message to announce\n * @param politeness - ARIA live politeness level\n */\nexport function announceToScreenReader(\n message: string,\n politeness: AriaLive = 'polite'\n): void {\n // Create or get existing live region\n let liveRegion = document.getElementById('notectl-sr-live');\n\n if (!liveRegion) {\n liveRegion = document.createElement('div');\n liveRegion.id = 'notectl-sr-live';\n liveRegion.setAttribute('role', 'status');\n liveRegion.setAttribute('aria-live', politeness);\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.style.position = 'absolute';\n liveRegion.style.left = '-10000px';\n liveRegion.style.width = '1px';\n liveRegion.style.height = '1px';\n liveRegion.style.overflow = 'hidden';\n document.body.appendChild(liveRegion);\n } else {\n liveRegion.setAttribute('aria-live', politeness);\n }\n\n // Clear and set message (ensures announcement)\n liveRegion.textContent = '';\n setTimeout(() => {\n liveRegion!.textContent = message;\n }, 100);\n}\n\n/**\n * Get all focusable elements within a container\n * @param container - Container element\n * @returns Array of focusable elements\n */\nexport function getFocusableElements(container: HTMLElement): HTMLElement[] {\n const selector = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]'\n ].join(',');\n\n return Array.from(container.querySelectorAll<HTMLElement>(selector)).filter(\n el => {\n // Check if element is visible\n return el.offsetParent !== null &&\n getComputedStyle(el).visibility !== 'hidden' &&\n !el.hasAttribute('hidden');\n }\n );\n}\n\n/**\n * Trap focus within a container\n * @param config - Focus trap configuration\n * @returns Cleanup function\n */\nexport function trapFocus(config: FocusTrapConfig): () => void {\n const { container, initialFocus, returnFocus, escapeDeactivates = true } = config;\n\n const focusableElements = getFocusableElements(container);\n if (focusableElements.length === 0) {\n console.warn('No focusable elements found in container');\n return () => {};\n }\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n // Focus initial element\n if (initialFocus && focusableElements.includes(initialFocus)) {\n initialFocus.focus();\n } else {\n firstElement.focus();\n }\n\n // Handle keyboard events\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n // Shift+Tab\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n } else if (escapeDeactivates && event.key === 'Escape') {\n event.preventDefault();\n deactivate();\n }\n };\n\n // Deactivate focus trap\n const deactivate = (): void => {\n document.removeEventListener('keydown', handleKeyDown);\n if (returnFocus) {\n returnFocus.focus();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return deactivate;\n}\n\n/**\n * Generate ARIA label for editor actions\n * @param action - Action name\n * @param state - Current state description\n * @returns ARIA label\n */\nexport function getAriaLabel(action: string, state?: string): string {\n const labels: Record<string, string> = {\n bold: 'Toggle bold formatting',\n italic: 'Toggle italic formatting',\n underline: 'Toggle underline formatting',\n strikethrough: 'Toggle strikethrough formatting',\n code: 'Toggle code formatting',\n heading1: 'Format as heading level 1',\n heading2: 'Format as heading level 2',\n heading3: 'Format as heading level 3',\n bulletList: 'Create bullet list',\n orderedList: 'Create numbered list',\n blockquote: 'Create blockquote',\n codeBlock: 'Create code block',\n link: 'Insert link',\n image: 'Insert image',\n undo: 'Undo last action',\n redo: 'Redo last action',\n clear: 'Clear formatting'\n };\n\n const baseLabel = labels[action] || action;\n return state ? `${baseLabel} (${state})` : baseLabel;\n}\n\n/**\n * Get keyboard shortcut description\n * @param shortcut - Keyboard shortcut\n * @returns Human-readable description\n */\nexport function getShortcutDescription(shortcut: KeyboardShortcut): string {\n const parts: string[] = [];\n\n const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n\n if (shortcut.ctrlKey || shortcut.metaKey) {\n parts.push(isMac ? 'Cmd' : 'Ctrl');\n }\n if (shortcut.shiftKey) {\n parts.push('Shift');\n }\n if (shortcut.altKey) {\n parts.push(isMac ? 'Option' : 'Alt');\n }\n\n parts.push(shortcut.key.toUpperCase());\n\n return `${parts.join('+')} - ${shortcut.description}`;\n}\n\n/**\n * Register keyboard shortcuts with announcements\n * @param shortcuts - Array of keyboard shortcuts\n * @param container - Container element to attach listeners\n * @returns Cleanup function\n */\nexport function registerKeyboardShortcuts(\n shortcuts: KeyboardShortcut[],\n container: HTMLElement\n): () => void {\n const handleKeyDown = (event: KeyboardEvent): void => {\n for (const shortcut of shortcuts) {\n const ctrlMatch = shortcut.ctrlKey ? event.ctrlKey : true;\n const metaMatch = shortcut.metaKey ? event.metaKey : true;\n const shiftMatch = shortcut.shiftKey ? event.shiftKey : !event.shiftKey;\n const altMatch = shortcut.altKey ? event.altKey : !event.altKey;\n\n if (\n event.key.toLowerCase() === shortcut.key.toLowerCase() &&\n ctrlMatch &&\n metaMatch &&\n shiftMatch &&\n altMatch\n ) {\n event.preventDefault();\n shortcut.action();\n announceToScreenReader(shortcut.description);\n break;\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n };\n}\n\n/**\n * Set ARIA attributes for an element\n * @param element - Element to update\n * @param attributes - ARIA attributes\n */\nexport function setAriaAttributes(\n element: HTMLElement,\n attributes: Record<string, string | boolean | number>\n): void {\n for (const [key, value] of Object.entries(attributes)) {\n const attrName = key.startsWith('aria-') ? key : `aria-${key}`;\n element.setAttribute(attrName, String(value));\n }\n}\n\n/**\n * Create a visually hidden element (accessible to screen readers)\n * @param text - Text content\n * @returns Visually hidden element\n */\nexport function createVisuallyHidden(text: string): HTMLElement {\n const element = document.createElement('span');\n element.textContent = text;\n element.style.position = 'absolute';\n element.style.left = '-10000px';\n element.style.width = '1px';\n element.style.height = '1px';\n element.style.overflow = 'hidden';\n element.setAttribute('aria-hidden', 'false');\n return element;\n}\n\n/**\n * Update ARIA live region\n * @param id - Live region ID\n * @param message - Message to announce\n * @param politeness - Politeness level\n */\nexport function updateAriaLive(\n id: string,\n message: string,\n politeness: AriaLive = 'polite'\n): void {\n let liveRegion = document.getElementById(id);\n\n if (!liveRegion) {\n liveRegion = document.createElement('div');\n liveRegion.id = id;\n liveRegion.setAttribute('role', 'status');\n liveRegion.setAttribute('aria-live', politeness);\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.style.position = 'absolute';\n liveRegion.style.left = '-10000px';\n liveRegion.style.width = '1px';\n liveRegion.style.height = '1px';\n liveRegion.style.overflow = 'hidden';\n document.body.appendChild(liveRegion);\n }\n\n liveRegion.textContent = message;\n}\n\n/**\n * Check if reduced motion is preferred\n * @returns True if reduced motion is preferred\n */\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/**\n * Check if high contrast is enabled\n * @returns True if high contrast is enabled\n */\nexport function prefersHighContrast(): boolean {\n return window.matchMedia('(prefers-contrast: high)').matches;\n}\n\n/**\n * Get accessible color contrast ratio\n * @param foreground - Foreground color (hex)\n * @param background - Background color (hex)\n * @returns Contrast ratio\n */\nexport function getContrastRatio(foreground: string, background: string): number {\n const getLuminance = (color: string): number => {\n const rgb = parseInt(color.slice(1), 16);\n const r = ((rgb >> 16) & 0xff) / 255;\n const g = ((rgb >> 8) & 0xff) / 255;\n const b = (rgb & 0xff) / 255;\n\n const [rs, gs, bs] = [r, g, b].map(c => {\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n });\n\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n };\n\n const l1 = getLuminance(foreground);\n const l2 = getLuminance(background);\n\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n","/**\n * NotectlEditor Web Component\n * Framework-agnostic rich text editor\n */\n\nimport { EditorState } from '../state/EditorState.js';\nimport { PluginManager } from '../plugins/PluginManager.js';\nimport type { Plugin, PluginContext, CommandHandler } from '../plugins/Plugin.js';\nimport type { Delta } from '../delta/Delta.js';\nimport type { EditorConfig, EditorEvent, EditorEventCallback, Document } from '../types/index.js';\nimport { createDefaultSchema } from '../schema/Schema.js';\nimport { sanitizeHTML, sanitizeContent, validateDelta } from '../utils/security.js';\nimport {\n announceToScreenReader,\n registerKeyboardShortcuts,\n setAriaAttributes,\n type KeyboardShortcut\n} from '../utils/accessibility.js';\n\n/**\n * NotectlEditor custom element\n */\nexport class NotectlEditor extends HTMLElement {\n private state: EditorState;\n private pluginManager: PluginManager;\n private eventListeners: Map<string, Set<EditorEventCallback>> = new Map();\n private commands: Map<string, CommandHandler> = new Map();\n private contentElement: HTMLDivElement | null = null;\n private pluginContainerTop: HTMLDivElement | null = null;\n private pluginContainerBottom: HTMLDivElement | null = null;\n private config: EditorConfig;\n private keyboardShortcutCleanup?: () => void;\n private ariaLiveRegion: HTMLDivElement | null = null;\n\n // Plugin queue system for pre-mount registration\n private pendingPlugins: Plugin[] = [];\n private readyPromise: Promise<void>;\n private readyResolve?: () => void;\n private isReady: boolean = false;\n\n constructor() {\n super();\n\n // Default config\n this.config = {\n placeholder: 'Start typing...',\n readonly: false,\n autofocus: false,\n sanitizeHTML: true,\n maxHistoryDepth: 100,\n };\n\n // Initialize state\n const schema = createDefaultSchema();\n this.state = new EditorState(undefined, schema, {\n maxHistoryDepth: this.config.maxHistoryDepth,\n });\n\n // Initialize plugin manager\n this.pluginManager = new PluginManager();\n\n // Initialize ready promise\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n // Attach shadow DOM\n this.attachShadow({ mode: 'open' });\n }\n\n /**\n * Observed attributes for the web component\n */\n static get observedAttributes(): string[] {\n return ['placeholder', 'readonly', 'autofocus'];\n }\n\n /**\n * Called when element is connected to DOM\n */\n async connectedCallback(): Promise<void> {\n this.render();\n this.attachEventListeners();\n this.setupAccessibility();\n this.setupKeyboardShortcuts();\n\n // Mark editor as ready\n this.isReady = true;\n\n // Process pending plugins that were registered before mounting\n if (this.pendingPlugins.length > 0) {\n const plugins = [...this.pendingPlugins];\n this.pendingPlugins = [];\n\n for (const plugin of plugins) {\n try {\n await this.pluginManager.register(plugin, this.createPluginContext());\n } catch (error) {\n console.error(`Failed to register pending plugin ${plugin.id}:`, error);\n }\n }\n }\n\n // Resolve the ready promise\n if (this.readyResolve) {\n this.readyResolve();\n }\n\n // Emit ready event\n this.emit('ready', { editor: this });\n\n if (this.config.autofocus) {\n this.focus();\n }\n }\n\n /**\n * Called when element is disconnected from DOM\n */\n disconnectedCallback(): void {\n this.detachEventListeners();\n this.pluginManager.destroyAll();\n if (this.keyboardShortcutCleanup) {\n this.keyboardShortcutCleanup();\n }\n if (this.ariaLiveRegion && this.ariaLiveRegion.parentNode) {\n this.ariaLiveRegion.parentNode.removeChild(this.ariaLiveRegion);\n }\n\n // Reset ready state for potential re-mounting\n this.isReady = false;\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n }\n\n /**\n * Called when attributes change\n */\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n\n switch (name) {\n case 'placeholder':\n this.config.placeholder = newValue || '';\n this.updatePlaceholder();\n break;\n case 'readonly':\n this.config.readonly = newValue !== null;\n this.updateReadonly();\n break;\n case 'autofocus':\n this.config.autofocus = newValue !== null;\n break;\n }\n }\n\n /**\n * Render the editor UI\n */\n private render(): void {\n if (!this.shadowRoot) return;\n\n this.shadowRoot.innerHTML = `\n <style>\n :host {\n display: block;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 16px;\n line-height: 1.5;\n }\n\n .notectl-container {\n display: flex;\n flex-direction: column;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n background: white;\n }\n\n .notectl-plugin-container {\n display: block;\n background: transparent;\n }\n\n .notectl-plugin-container[data-position=\"top\"] {\n order: -1;\n }\n\n .notectl-plugin-container[data-position=\"bottom\"] {\n order: 1;\n }\n\n .notectl-editor-wrapper {\n position: relative;\n flex: 1;\n }\n\n .notectl-editor {\n min-height: 200px;\n padding: 1rem;\n outline: none;\n background: white;\n }\n\n .notectl-container:focus-within {\n border-color: #2196F3;\n box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.1);\n }\n\n .notectl-editor[data-readonly=\"true\"] {\n background: #f5f5f5;\n cursor: not-allowed;\n }\n\n .notectl-editor table {\n border-collapse: collapse;\n width: 100%;\n margin: 1em 0;\n }\n\n .notectl-editor table td,\n .notectl-editor table th {\n border: 1px solid #ddd;\n padding: 8px;\n min-width: 100px;\n }\n\n .notectl-placeholder {\n position: absolute;\n top: 1rem;\n left: 1rem;\n color: #9e9e9e;\n pointer-events: none;\n user-select: none;\n }\n\n .notectl-placeholder.hidden {\n display: none;\n }\n\n .visually-hidden {\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n }\n </style>\n\n <div class=\"notectl-container\">\n <div class=\"notectl-plugin-container\" data-position=\"top\"></div>\n <div class=\"notectl-editor-wrapper\">\n <div class=\"notectl-placeholder\" aria-hidden=\"true\">${this.config.placeholder}</div>\n <div\n class=\"notectl-editor\"\n contenteditable=\"${!this.config.readonly}\"\n data-readonly=\"${this.config.readonly}\"\n role=\"textbox\"\n aria-label=\"Rich text editor\"\n aria-multiline=\"true\"\n aria-describedby=\"notectl-help-text\"\n tabindex=\"0\"\n ></div>\n </div>\n <div class=\"notectl-plugin-container\" data-position=\"bottom\"></div>\n </div>\n <div id=\"notectl-help-text\" class=\"visually-hidden\">\n Use arrow keys to navigate. Press Ctrl+B for bold, Ctrl+I for italic, Ctrl+U for underline.\n Press Ctrl+Z to undo, Ctrl+Shift+Z to redo.\n </div>\n <div id=\"notectl-aria-live\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"visually-hidden\"></div>\n `;\n\n this.contentElement = this.shadowRoot.querySelector('.notectl-editor');\n this.pluginContainerTop = this.shadowRoot.querySelector('.notectl-plugin-container[data-position=\"top\"]');\n this.pluginContainerBottom = this.shadowRoot.querySelector('.notectl-plugin-container[data-position=\"bottom\"]');\n this.ariaLiveRegion = this.shadowRoot.querySelector('#notectl-aria-live');\n this.renderContent();\n }\n\n /**\n * Render document content\n */\n private renderContent(): void {\n if (!this.contentElement) return;\n\n const doc = this.state.getDocument();\n const html = this.documentToHTML(doc);\n\n // Sanitize HTML before rendering\n this.contentElement.innerHTML = this.config.sanitizeHTML\n ? sanitizeHTML(html)\n : html;\n }\n\n /**\n * Convert document to HTML\n */\n private documentToHTML(doc: Document): string {\n return doc.children.map((block) => this.blockToHTML(block)).join('');\n }\n\n /**\n * Convert block to HTML (simplified)\n */\n private blockToHTML(block: any): string {\n switch (block.type) {\n case 'paragraph':\n return `<p>${this.childrenToHTML(block.children || [])}</p>`;\n case 'heading':\n const level = block.attrs?.level || 1;\n return `<h${level}>${this.childrenToHTML(block.children || [])}</h${level}>`;\n case 'table':\n return this.tableToHTML(block);\n default:\n return `<div>${this.childrenToHTML(block.children || [])}</div>`;\n }\n }\n\n /**\n * Convert children to HTML\n */\n private childrenToHTML(children: any[]): string {\n return children\n .map((child) => {\n if (child.type === 'text') {\n let html = this.escapeHTML(child.text);\n if (child.marks) {\n for (const mark of child.marks) {\n html = this.applyMarkHTML(html, mark);\n }\n }\n return html;\n }\n return this.blockToHTML(child);\n })\n .join('');\n }\n\n /**\n * Apply mark as HTML\n */\n private applyMarkHTML(text: string, mark: any): string {\n switch (mark.type) {\n case 'bold':\n return `<strong>${text}</strong>`;\n case 'italic':\n return `<em>${text}</em>`;\n case 'underline':\n return `<u>${text}</u>`;\n case 'strikethrough':\n return `<s>${text}</s>`;\n case 'code':\n return `<code>${text}</code>`;\n default:\n return text;\n }\n }\n\n /**\n * Escape HTML\n */\n private escapeHTML(text: string): string {\n if (!this.config.sanitizeHTML) return text;\n\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n private tableToHTML(block: any): string {\n const tableData = block.attrs?.table;\n const tableId = block.id || crypto.randomUUID();\n const attrParts: string[] = [\n 'data-node-type=\"table\"',\n `data-block-id=\"${tableId}\"`,\n ];\n\n if (block.attrs?.style) {\n const styleString = this.styleObjectToString(block.attrs.style);\n if (styleString) {\n attrParts.push(`style=\"${styleString}\"`);\n }\n }\n\n let bodyHTML = '';\n const rows = Array.isArray(tableData?.rows) ? tableData.rows : [];\n\n if (rows.length === 0) {\n const fallbackCellId = crypto.randomUUID();\n const fallbackRowId = crypto.randomUUID();\n bodyHTML = `\n <tr data-node-type=\"table_row\" data-row=\"0\" data-block-id=\"${fallbackRowId}\">\n <td data-node-type=\"table_cell\" data-row=\"0\" data-col=\"0\" data-block-id=\"${fallbackCellId}\"><br></td>\n </tr>\n `;\n } else {\n bodyHTML = rows\n .map((row: any, rowIndex: number) => this.tableRowToHTML(row, rowIndex))\n .join('');\n }\n\n return `<table ${attrParts.join(' ')}><tbody>${bodyHTML}</tbody></table>`;\n }\n\n private tableRowToHTML(row: any, rowIndex: number): string {\n const rowId = row.id || crypto.randomUUID();\n const attrs: string[] = [\n 'data-node-type=\"table_row\"',\n `data-row=\"${rowIndex}\"`,\n `data-block-id=\"${rowId}\"`,\n ];\n\n if (row.attrs?.style) {\n const style = this.styleObjectToString(row.attrs.style);\n if (style) {\n attrs.push(`style=\"${style}\"`);\n }\n }\n\n const cells = Array.isArray(row.cells) ? row.cells : [];\n\n const cellsHTML = cells\n .map((cell: any, colIndex: number) => this.tableCellToHTML(cell, rowIndex, colIndex))\n .join('');\n\n return `<tr ${attrs.join(' ')}>${cellsHTML}</tr>`;\n }\n\n private tableCellToHTML(cell: any, rowIndex: number, colIndex: number): string {\n const cellId = cell.id || crypto.randomUUID();\n const attrs: string[] = [\n 'data-node-type=\"table_cell\"',\n `data-row=\"${rowIndex}\"`,\n `data-col=\"${colIndex}\"`,\n `data-block-id=\"${cellId}\"`,\n ];\n\n const rowSpan = Number(cell.rowSpan) || 1;\n const colSpan = Number(cell.colSpan) || 1;\n if (rowSpan > 1) {\n attrs.push(`rowspan=\"${rowSpan}\"`);\n }\n if (colSpan > 1) {\n attrs.push(`colspan=\"${colSpan}\"`);\n }\n\n if (cell.attrs?.style) {\n const style = this.styleObjectToString(cell.attrs.style);\n if (style) {\n attrs.push(`style=\"${style}\"`);\n }\n }\n\n const content = typeof cell.content === 'string' ? this.escapeHTML(cell.content) : '';\n const inner = content || '<br>';\n\n return `<td ${attrs.join(' ')}>${inner}</td>`;\n }\n\n private styleObjectToString(style: Record<string, unknown>): string {\n return Object.entries(style)\n .map(([key, value]) => {\n if (value === undefined || value === null || value === '') {\n return null;\n }\n const cssKey = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n return `${cssKey}: ${String(value)}`;\n })\n .filter(Boolean)\n .join('; ');\n }\n\n /**\n * Setup accessibility features\n */\n private setupAccessibility(): void {\n if (!this.contentElement) return;\n\n // Set comprehensive ARIA attributes\n setAriaAttributes(this.contentElement, {\n 'role': 'textbox',\n 'aria-multiline': true,\n 'aria-label': 'Rich text editor',\n 'aria-describedby': 'notectl-help-text',\n 'aria-autocomplete': 'none'\n });\n\n // Update ARIA attributes based on readonly state\n if (this.config.readonly) {\n this.contentElement.setAttribute('aria-readonly', 'true');\n }\n }\n\n /**\n * Setup keyboard shortcuts with screen reader announcements\n */\n private setupKeyboardShortcuts(): void {\n if (!this.contentElement) return;\n\n const shortcuts: KeyboardShortcut[] = [\n {\n key: 'b',\n ctrlKey: true,\n description: 'Bold formatting applied',\n action: () => this.toggleFormat('bold')\n },\n {\n key: 'i',\n ctrlKey: true,\n description: 'Italic formatting applied',\n action: () => this.toggleFormat('italic')\n },\n {\n key: 'u',\n ctrlKey: true,\n description: 'Underline formatting applied',\n action: () => this.toggleFormat('underline')\n },\n {\n key: 'z',\n ctrlKey: true,\n description: 'Action undone',\n action: () => this.undo()\n },\n {\n key: 'z',\n ctrlKey: true,\n shiftKey: true,\n description: 'Action redone',\n action: () => this.redo()\n }\n ];\n\n this.keyboardShortcutCleanup = registerKeyboardShortcuts(shortcuts, this.contentElement);\n }\n\n /**\n * Toggle formatting\n */\n private toggleFormat(format: string): void {\n // Get current selection\n const selection = window.getSelection();\n if (!selection || !this.contentElement) return;\n\n // Apply formatting via execCommand (will be replaced with Delta operations)\n try {\n switch (format) {\n case 'bold':\n document.execCommand('bold', false);\n break;\n case 'italic':\n document.execCommand('italic', false);\n break;\n case 'underline':\n document.execCommand('underline', false);\n break;\n case 'strikethrough':\n document.execCommand('strikeThrough', false);\n break;\n case 'code':\n // Wrap selection in <code> tag\n const code = document.createElement('code');\n if (selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n code.appendChild(range.extractContents());\n range.insertNode(code);\n }\n break;\n }\n\n this.announceToScreenReader(`${format} formatting applied`);\n this.emit('change', { state: this.state });\n } catch (error) {\n console.error(`Failed to apply ${format} formatting:`, error);\n this.announceToScreenReader(`Failed to apply ${format} formatting`);\n }\n }\n\n /**\n * Insert table at current selection\n */\n insertTable(rows: number = 3, cols: number = 3): void {\n if (!this.contentElement) return;\n\n try {\n // Focus the editor if not already focused\n this.contentElement.focus();\n\n // Create table element\n const table = document.createElement('table');\n table.setAttribute('data-notectl-table', 'true');\n\n // Create tbody\n const tbody = document.createElement('tbody');\n\n // Generate rows - all cells are equal, user can style as needed\n for (let i = 0; i < rows; i++) {\n const tr = document.createElement('tr');\n\n for (let j = 0; j < cols; j++) {\n const cell = document.createElement('td');\n cell.textContent = ''; // Empty cells - user fills them\n tr.appendChild(cell);\n }\n\n tbody.appendChild(tr);\n }\n\n table.appendChild(tbody);\n\n // Get the current selection\n const selection = window.getSelection();\n let insertPosition = this.contentElement.childNodes.length;\n\n // Try to find the cursor position\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n\n // Check if the range is inside contentElement\n if (this.contentElement.contains(range.commonAncestorContainer)) {\n // Find the position in childNodes\n let node = range.startContainer;\n\n // If it's a text node, get its parent\n if (node.nodeType === Node.TEXT_NODE) {\n node = node.parentNode as Node;\n }\n\n // Find position among contentElement's children\n if (node === this.contentElement) {\n insertPosition = range.startOffset;\n } else {\n // Find the index of the node or its ancestor\n let child = node;\n while (child.parentNode && child.parentNode !== this.contentElement) {\n child = child.parentNode;\n }\n if (child.parentNode === this.contentElement) {\n insertPosition = Array.from(this.contentElement.childNodes).indexOf(child as ChildNode) + 1;\n }\n }\n }\n }\n\n // Add a paragraph after the table\n const p = document.createElement('p');\n p.innerHTML = '<br>';\n\n // Insert at the correct position\n if (insertPosition >= this.contentElement.childNodes.length) {\n this.contentElement.appendChild(table);\n this.contentElement.appendChild(p);\n } else {\n const refNode = this.contentElement.childNodes[insertPosition];\n this.contentElement.insertBefore(table, refNode);\n this.contentElement.insertBefore(p, refNode);\n }\n\n // Set cursor in the new paragraph\n if (selection) {\n const range = document.createRange();\n range.setStart(p, 0);\n range.setEnd(p, 0);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n\n // Update placeholder visibility (content is no longer empty)\n this.updatePlaceholder();\n\n // Force sync to state\n this.syncContentToState();\n\n this.announceToScreenReader(`Table with ${rows} rows and ${cols} columns inserted`);\n this.emit('change', { state: this.state });\n } catch (error) {\n console.error('Failed to insert table:', error);\n this.announceToScreenReader('Failed to insert table');\n }\n }\n\n /**\n * Announce message to screen readers\n */\n private announceToScreenReader(message: string): void {\n if (this.ariaLiveRegion) {\n this.ariaLiveRegion.textContent = '';\n setTimeout(() => {\n if (this.ariaLiveRegion) {\n this.ariaLiveRegion.textContent = message;\n }\n }, 100);\n } else {\n announceToScreenReader(message);\n }\n }\n\n /**\n * Attach event listeners\n */\n private attachEventListeners(): void {\n if (!this.contentElement) return;\n\n this.contentElement.addEventListener('input', this.handleInput);\n this.contentElement.addEventListener('keydown', this.handleKeydown);\n this.contentElement.addEventListener('focus', this.handleFocus);\n this.contentElement.addEventListener('blur', this.handleBlur);\n this.contentElement.addEventListener('contextmenu', this.handleContextMenu);\n }\n\n /**\n * Detach event listeners\n */\n private detachEventListeners(): void {\n if (!this.contentElement) return;\n\n this.contentElement.removeEventListener('input', this.handleInput);\n this.contentElement.removeEventListener('keydown', this.handleKeydown);\n this.contentElement.removeEventListener('focus', this.handleFocus);\n this.contentElement.removeEventListener('blur', this.handleBlur);\n this.contentElement.removeEventListener('contextmenu', this.handleContextMenu);\n }\n\n /**\n * Handle input event\n */\n private handleInput = (event: Event): void => {\n this.updatePlaceholder();\n\n // Skip syncing if input originates inside a managed table to avoid\n // clobbering the plugin-driven document state until table syncing is\n // fully implemented.\n const target = event.target as HTMLElement | null;\n if (!target?.closest('[data-node-type=\"table\"]')) {\n this.syncContentToState();\n }\n\n this.emit('change', { state: this.state });\n };\n\n /**\n * Handle keydown event\n */\n private handleKeydown = (event: KeyboardEvent): void => {\n this.emit('keydown', event);\n if (event.defaultPrevented) {\n return;\n }\n\n // Handle undo/redo\n if ((event.ctrlKey || event.metaKey) && event.key === 'z') {\n event.preventDefault();\n if (event.shiftKey) {\n this.redo();\n this.announceToScreenReader('Action redone');\n } else {\n this.undo();\n this.announceToScreenReader('Action undone');\n }\n }\n\n // Announce navigation\n if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {\n if (event.ctrlKey || event.metaKey) {\n this.announceToScreenReader(`Navigating ${event.key.replace('Arrow', '').toLowerCase()}`);\n }\n }\n };\n\n /**\n * Handle focus event\n */\n private handleFocus = (): void => {\n this.emit('focus', { state: this.state });\n };\n\n /**\n * Handle blur event\n */\n private handleBlur = (): void => {\n this.emit('blur', { state: this.state });\n };\n\n private handleContextMenu = (event: MouseEvent): void => {\n this.emit('contextmenu', event);\n };\n\n /**\n * Update placeholder visibility\n */\n private updatePlaceholder(): void {\n if (!this.shadowRoot) return;\n\n const placeholder = this.shadowRoot.querySelector('.notectl-placeholder');\n const isEmpty = !this.contentElement?.textContent?.trim();\n\n if (placeholder) {\n placeholder.classList.toggle('hidden', !isEmpty);\n }\n }\n\n /**\n * Sync content from DOM to state\n */\n private syncContentToState(): void {\n if (!this.contentElement) return;\n\n try {\n const doc = this.htmlToDocument(this.contentElement.innerHTML);\n this.state = EditorState.fromJSON(doc, this.state.schema);\n } catch (error) {\n console.error('Failed to sync content to state:', error);\n }\n }\n\n /**\n * Convert HTML to document structure\n */\n private htmlToDocument(html: string): Document {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n const body = doc.body;\n\n const children: any[] = [];\n\n // Parse child nodes\n Array.from(body.childNodes).forEach((node) => {\n const block = this.nodeToBlock(node);\n if (block) {\n children.push(block);\n }\n });\n\n // If no children, create empty paragraph\n if (children.length === 0) {\n children.push({\n id: crypto.randomUUID(),\n type: 'paragraph',\n children: [],\n });\n }\n\n return {\n version: this.state.getDocument().version + 1,\n schemaVersion: '1.0.0',\n children,\n };\n }\n\n /**\n * Convert DOM node to block\n */\n private nodeToBlock(node: Node): any {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || '';\n if (!text.trim()) return null;\n return {\n type: 'text',\n text,\n marks: [],\n };\n }\n\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n\n // Block elements\n if (tagName === 'p') {\n return {\n id: crypto.randomUUID(),\n type: 'paragraph',\n children: this.parseChildren(element),\n };\n }\n\n if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tagName)) {\n const level = parseInt(tagName.charAt(1), 10);\n return {\n id: crypto.randomUUID(),\n type: 'heading',\n attrs: { level },\n children: this.parseChildren(element),\n };\n }\n\n // Inline elements - extract text with marks\n return this.parseInlineElement(element);\n }\n\n return null;\n }\n\n /**\n * Parse children nodes\n */\n private parseChildren(element: Element): any[] {\n const children: any[] = [];\n\n Array.from(element.childNodes).forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || '';\n if (text) {\n children.push({\n type: 'text',\n text,\n marks: [],\n });\n }\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const childElement = node as Element;\n const result = this.parseInlineElement(childElement);\n if (result) {\n if (Array.isArray(result)) {\n children.push(...result);\n } else {\n children.push(result);\n }\n }\n }\n });\n\n return children;\n }\n\n /**\n * Parse inline element with marks\n */\n private parseInlineElement(element: Element): any {\n const tagName = element.tagName.toLowerCase();\n const marks: any[] = [];\n\n // Determine mark type\n if (tagName === 'strong' || tagName === 'b') {\n marks.push({ type: 'bold' });\n } else if (tagName === 'em' || tagName === 'i') {\n marks.push({ type: 'italic' });\n } else if (tagName === 'u') {\n marks.push({ type: 'underline' });\n } else if (tagName === 's' || tagName === 'strike') {\n marks.push({ type: 'strikethrough' });\n } else if (tagName === 'code') {\n marks.push({ type: 'code' });\n }\n\n // Get text content and nested marks\n const children: any[] = [];\n Array.from(element.childNodes).forEach((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent || '';\n if (text) {\n children.push({\n type: 'text',\n text,\n marks,\n });\n }\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const childElement = node as Element;\n const childResult = this.parseInlineElement(childElement);\n if (childResult) {\n // Merge marks\n if (childResult.type === 'text') {\n childResult.marks = [...marks, ...(childResult.marks || [])];\n children.push(childResult);\n } else if (Array.isArray(childResult)) {\n childResult.forEach((item: any) => {\n if (item.type === 'text') {\n item.marks = [...marks, ...(item.marks || [])];\n }\n children.push(item);\n });\n }\n }\n }\n });\n\n return children.length === 1 ? children[0] : children;\n }\n\n /**\n * Update readonly state\n */\n private updateReadonly(): void {\n if (this.contentElement) {\n this.contentElement.contentEditable = String(!this.config.readonly);\n this.contentElement.setAttribute('data-readonly', String(this.config.readonly));\n }\n }\n\n /**\n * Register a plugin\n *\n * Plugins can be registered before or after the editor is mounted.\n * If registered before mounting, they will be queued and initialized\n * automatically when the editor connects to the DOM.\n *\n * @param plugin - The plugin to register\n * @returns Promise that resolves when the plugin is registered\n */\n async registerPlugin(plugin: Plugin): Promise<void> {\n // If editor is not yet connected to DOM, queue the plugin\n if (!this.isReady) {\n this.pendingPlugins.push(plugin);\n return;\n }\n\n // Editor is ready, register immediately\n const context = this.createPluginContext();\n await this.pluginManager.register(plugin, context);\n }\n\n /**\n * Unregister a plugin\n */\n async unregisterPlugin(pluginId: string): Promise<void> {\n const context = this.createPluginContext();\n await this.pluginManager.unregister(pluginId, context);\n }\n\n /**\n * Wait for the editor to be ready\n *\n * Returns a Promise that resolves when the editor has been mounted\n * and all pending plugins have been initialized. This is useful when\n * you need to ensure the editor is fully initialized before performing\n * operations that depend on the editor being mounted.\n *\n * @returns Promise that resolves when the editor is ready\n * @example\n * ```typescript\n * const editor = document.createElement('notectl-editor');\n * container.appendChild(editor);\n * await editor.whenReady();\n * // Editor is now fully initialized\n * ```\n */\n async whenReady(): Promise<void> {\n return this.readyPromise;\n }\n\n // ===== Plugin Context Helper Methods =====\n\n /**\n * Get the block containing the current selection\n */\n private getSelectedBlock(): import('../types/index.js').BlockNode | null {\n const selection = this.state.getSelection();\n if (!selection) return null;\n\n return this.state.findBlock(selection.anchor.blockId) || null;\n }\n\n /**\n * Find all blocks of a specific type\n */\n private findBlocksByType(type: string): import('../types/index.js').BlockNode[] {\n const results: import('../types/index.js').BlockNode[] = [];\n const doc = this.state.getDocument();\n\n const search = (nodes: import('../types/index.js').BlockNode[]): void => {\n for (const node of nodes) {\n if (node.type === type) {\n results.push(node);\n }\n if (node.children) {\n const blockChildren = node.children.filter(\n (n): n is import('../types/index.js').BlockNode => 'id' in n\n );\n search(blockChildren);\n }\n }\n };\n\n search(doc.children);\n return results;\n }\n\n /**\n * Find parent block of a given block\n */\n private findParentBlock(block: import('../types/index.js').BlockNode): import('../types/index.js').BlockNode | null {\n const doc = this.state.getDocument();\n\n const search = (\n nodes: import('../types/index.js').BlockNode[],\n parent: import('../types/index.js').BlockNode | null = null\n ): import('../types/index.js').BlockNode | null => {\n for (const node of nodes) {\n if (node.id === block.id) {\n return parent;\n }\n if (node.children) {\n const blockChildren = node.children.filter(\n (n): n is import('../types/index.js').BlockNode => 'id' in n\n );\n const found = search(blockChildren, node);\n if (found) return found;\n }\n }\n return null;\n };\n\n return search(doc.children);\n }\n\n /**\n * Get block at current cursor position\n */\n private getBlockAtCursor(): import('../types/index.js').BlockNode | null {\n return this.getSelectedBlock();\n }\n\n /**\n * Insert a block after another block (Delta-based)\n */\n private insertBlockAfter(block: import('../types/index.js').BlockNode, afterId?: import('../types/index.js').BlockId): void {\n const doc = this.state.getDocument();\n const targetId = afterId || (doc.children[doc.children.length - 1]?.id);\n\n if (!targetId) {\n // Document is empty, just add the block\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'edit',\n ops: [\n {\n op: 'insert_block_after',\n after: '',\n block,\n },\n ],\n };\n this.applyDelta(delta);\n return;\n }\n\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'edit',\n ops: [\n {\n op: 'insert_block_after',\n after: targetId,\n block,\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Insert a block before another block (Delta-based)\n */\n private insertBlockBefore(block: import('../types/index.js').BlockNode, beforeId?: import('../types/index.js').BlockId): void {\n const doc = this.state.getDocument();\n const targetId = beforeId || doc.children[0]?.id;\n\n if (!targetId) {\n // Document is empty, just add the block\n this.insertBlockAfter(block);\n return;\n }\n\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'edit',\n ops: [\n {\n op: 'insert_block_before',\n before: targetId,\n block,\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Update block attributes (Delta-based)\n */\n private updateBlockAttrs(blockId: import('../types/index.js').BlockId, attrs: Record<string, unknown>): void {\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'edit',\n ops: [\n {\n op: 'set_attrs',\n target: { blockId },\n attrs,\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Delete a block (Delta-based)\n */\n private deleteBlockById(blockId: import('../types/index.js').BlockId): void {\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'edit',\n ops: [\n {\n op: 'delete_block',\n target: { blockId },\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Add mark to current selection (Delta-based)\n */\n private addMarkToSelection(mark: import('../types/index.js').Mark): void {\n const selection = this.state.getSelection();\n if (!selection) return;\n\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'format',\n ops: [\n {\n op: 'apply_mark',\n range: {\n start: selection.anchor,\n end: selection.head,\n },\n mark,\n add: true,\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Remove mark from current selection (Delta-based)\n */\n private removeMarkFromSelection(markType: string): void {\n const selection = this.state.getSelection();\n if (!selection) return;\n\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'format',\n ops: [\n {\n op: 'apply_mark',\n range: {\n start: selection.anchor,\n end: selection.head,\n },\n mark: { type: markType },\n add: false,\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Toggle mark on current selection (Delta-based)\n */\n private toggleMarkOnSelection(markType: string): void {\n const selection = this.state.getSelection();\n if (!selection) return;\n\n const block = this.state.findBlock(selection.anchor.blockId);\n if (!block || !block.children) return;\n\n // Check if mark already exists in selection\n const textNode = block.children.find((n): n is import('../types/index.js').TextNode => 'text' in n);\n const hasMark = textNode?.marks?.some((m) => m.type === markType) || false;\n\n const delta: Delta = {\n txnId: crypto.randomUUID(),\n clientId: 'editor',\n timestamp: new Date().toISOString(),\n baseVersion: this.state.getVersion(),\n ltime: Date.now(),\n intent: 'format',\n ops: [\n {\n op: 'apply_mark',\n range: {\n start: selection.anchor,\n end: selection.head,\n },\n mark: { type: markType },\n add: !hasMark,\n },\n ],\n };\n\n this.applyDelta(delta);\n }\n\n /**\n * Create plugin context\n */\n private createPluginContext(): PluginContext {\n return {\n // Core state and delta operations\n getState: () => this.state,\n applyDelta: (delta: Delta) => this.applyDelta(delta),\n\n // Selection helpers\n getSelection: () => this.state.getSelection(),\n setSelection: (selection) => {\n this.state.setSelection(selection);\n this.emit('selection-change', { selection });\n },\n getSelectedBlock: () => this.getSelectedBlock(),\n\n // Node queries\n findBlocksByType: (type: string) => this.findBlocksByType(type),\n findBlockById: (blockId) => this.state.findBlock(blockId),\n findParentBlock: (block) => this.findParentBlock(block),\n getBlockAtCursor: () => this.getBlockAtCursor(),\n\n // Block mutations\n insertBlockAfter: (block, afterId) => this.insertBlockAfter(block, afterId),\n insertBlockBefore: (block, beforeId) => this.insertBlockBefore(block, beforeId),\n updateBlockAttrs: (blockId, attrs) => this.updateBlockAttrs(blockId, attrs),\n deleteBlock: (blockId) => this.deleteBlockById(blockId),\n\n // Mark utilities\n addMark: (mark) => this.addMarkToSelection(mark),\n removeMark: (markType) => this.removeMarkFromSelection(markType),\n toggleMark: (markType) => this.toggleMarkOnSelection(markType),\n\n // Events\n on: (event: string, callback: (data: unknown) => void) => this.on(event as EditorEvent, callback),\n off: (event: string, callback: (data: unknown) => void) => this.off(event as EditorEvent, callback),\n emit: (event: string, data?: unknown) => this.emit(event, data),\n\n // Commands\n registerCommand: (name: string, handler: CommandHandler) => this.registerCommand(name, handler),\n executeCommand: (name: string, ...args: unknown[]) => this.executeCommand(name, ...args),\n\n // DOM access (deprecated)\n getContainer: () => this.contentElement!,\n getPluginContainer: (position: 'top' | 'bottom') => {\n if (position === 'top') {\n return this.pluginContainerTop!;\n }\n return this.pluginContainerBottom!;\n },\n };\n }\n\n /**\n * Apply a delta\n */\n applyDelta(delta: Delta): void {\n // Validate delta for security\n if (!validateDelta(delta)) {\n console.error('Invalid or unsafe delta rejected');\n this.announceToScreenReader('Action blocked due to security validation');\n return;\n }\n\n this.state.applyDelta(delta);\n this.renderContent();\n this.pluginManager.notifyDeltaApplied(delta);\n this.emit('change', { delta, state: this.state });\n }\n\n /**\n * Register event listener\n */\n on(event: EditorEvent, callback: EditorEventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Unregister event listener\n */\n off(event: EditorEvent, callback: EditorEventCallback): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Emit event\n */\n private emit(event: string, data?: unknown): void {\n this.eventListeners.get(event)?.forEach((callback) => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event listener for ${event}:`, error);\n }\n });\n }\n\n /**\n * Register command\n */\n registerCommand(name: string, handler: CommandHandler): void {\n this.commands.set(name, handler);\n }\n\n /**\n * Execute command\n */\n executeCommand(name: string, ...args: unknown[]): unknown {\n const handler = this.commands.get(name);\n if (!handler) {\n throw new Error(`Command not found: ${name}`);\n }\n return handler(...args);\n }\n\n /**\n * Undo last change\n */\n undo(): void {\n const undoDelta = this.state.undo();\n if (undoDelta) {\n this.renderContent();\n this.announceToScreenReader('Undo performed');\n this.emit('change', { delta: undoDelta, state: this.state });\n } else {\n this.announceToScreenReader('Nothing to undo');\n }\n }\n\n /**\n * Redo last undone change\n */\n redo(): void {\n const redoDelta = this.state.redo();\n if (redoDelta) {\n this.renderContent();\n this.announceToScreenReader('Redo performed');\n this.emit('change', { delta: redoDelta, state: this.state });\n } else {\n this.announceToScreenReader('Nothing to redo');\n }\n }\n\n /**\n * Configure editor options\n * @param config - Configuration options to apply\n */\n configure(config: EditorConfig): void {\n this.config = { ...this.config, ...config };\n\n // Apply configuration changes\n if (config.readonly !== undefined) {\n this.updateReadonly();\n }\n\n if (config.placeholder !== undefined && this.shadowRoot) {\n const placeholder = this.shadowRoot.querySelector('.notectl-placeholder');\n if (placeholder) {\n placeholder.textContent = config.placeholder;\n }\n }\n\n if (config.initialContent) {\n if (typeof config.initialContent === 'object') {\n this.setJSON(config.initialContent);\n }\n }\n\n if (config.content) {\n if (typeof config.content === 'string') {\n this.setContent(config.content);\n } else {\n this.setJSON(config.content as Document);\n }\n }\n }\n\n /**\n * Destroy the editor and clean up resources\n */\n destroy(): void {\n this.detachEventListeners();\n this.pluginManager.destroyAll();\n\n if (this.keyboardShortcutCleanup) {\n this.keyboardShortcutCleanup();\n }\n\n if (this.ariaLiveRegion && this.ariaLiveRegion.parentNode) {\n this.ariaLiveRegion.parentNode.removeChild(this.ariaLiveRegion);\n }\n\n this.eventListeners.clear();\n this.commands.clear();\n }\n\n /**\n * Get current content as string or JSON\n * @returns Current document content\n */\n getContent(): Document | string {\n return this.getJSON();\n }\n\n /**\n * Get current state\n */\n getState(): EditorState {\n return this.state;\n }\n\n /**\n * Get document as JSON\n */\n getJSON(): Document {\n return this.state.toJSON();\n }\n\n /**\n * Set document from JSON\n */\n setJSON(doc: Document): void {\n this.state = EditorState.fromJSON(doc, this.state.schema);\n this.renderContent();\n }\n\n /**\n * Get HTML content (sanitized)\n */\n getHTML(): string {\n const html = this.documentToHTML(this.state.getDocument());\n return this.config.sanitizeHTML ? sanitizeHTML(html) : html;\n }\n\n /**\n * Set HTML content (with sanitization)\n * @param html - HTML content to set\n */\n setHTML(html: string): void {\n const sanitized = this.config.sanitizeHTML ? sanitizeHTML(html) : html;\n if (this.contentElement) {\n this.contentElement.innerHTML = sanitized;\n this.announceToScreenReader('Content updated');\n }\n }\n\n /**\n * Set content from string (with sanitization)\n * @param content - Content to set\n * @param allowHTML - Allow HTML tags\n */\n setContent(content: string, allowHTML: boolean = true): void {\n const sanitized = this.config.sanitizeHTML\n ? sanitizeContent(content, allowHTML)\n : content;\n\n if (this.contentElement) {\n this.contentElement.innerHTML = sanitized;\n this.announceToScreenReader('Content updated');\n }\n }\n\n /**\n * Export HTML content (sanitized)\n * @returns Sanitized HTML\n */\n exportHTML(): string {\n return this.getHTML();\n }\n\n /**\n * Focus the editor\n */\n focus(): void {\n this.contentElement?.focus();\n }\n\n /**\n * Blur the editor\n */\n blur(): void {\n this.contentElement?.blur();\n }\n}\n\n/**\n * Register custom element\n */\nif (!customElements.get('notectl-editor')) {\n customElements.define('notectl-editor', NotectlEditor);\n}\n","/**\n * Plugin interface and types for Notectl\n */\n\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Delta } from '../delta/Delta.js';\nimport type { Selection, BlockNode, Mark, BlockId } from '../types/index.js';\n\n/**\n * Plugin context provided to plugins\n */\nexport interface PluginContext {\n // === Core State & Delta Operations ===\n\n /**\n * Get current editor state\n */\n getState(): EditorState;\n\n /**\n * Apply a delta to the editor\n */\n applyDelta(delta: Delta): void;\n\n // === Selection Helpers ===\n\n /**\n * Get current selection\n */\n getSelection(): Selection | null;\n\n /**\n * Set selection\n */\n setSelection(selection: Selection): void;\n\n /**\n * Get the block containing the current cursor/selection\n */\n getSelectedBlock(): BlockNode | null;\n\n // === Node Queries ===\n\n /**\n * Find all blocks of a specific type\n * @param type - Block type to search for (e.g., 'table', 'heading', 'paragraph')\n * @returns Array of matching blocks\n */\n findBlocksByType(type: string): BlockNode[];\n\n /**\n * Find a block by its ID\n * @param blockId - Block identifier\n * @returns Block or undefined if not found\n */\n findBlockById(blockId: BlockId): BlockNode | undefined;\n\n /**\n * Find parent block of a given block\n * @param block - Child block\n * @returns Parent block or null if block is at root level\n */\n findParentBlock(block: BlockNode): BlockNode | null;\n\n /**\n * Get block at current cursor position\n */\n getBlockAtCursor(): BlockNode | null;\n\n // === Block Mutations (Delta-based) ===\n\n /**\n * Insert a block after another block\n * @param block - Block to insert\n * @param afterId - ID of block to insert after (if undefined, appends to end)\n */\n insertBlockAfter(block: BlockNode, afterId?: BlockId): void;\n\n /**\n * Insert a block before another block\n * @param block - Block to insert\n * @param beforeId - ID of block to insert before (if undefined, prepends to start)\n */\n insertBlockBefore(block: BlockNode, beforeId?: BlockId): void;\n\n /**\n * Update block attributes\n * @param blockId - Block to update\n * @param attrs - Attributes to merge\n */\n updateBlockAttrs(blockId: BlockId, attrs: Record<string, unknown>): void;\n\n /**\n * Delete a block\n * @param blockId - Block to delete\n */\n deleteBlock(blockId: BlockId): void;\n\n // === Mark Utilities ===\n\n /**\n * Add mark to current selection\n * @param mark - Mark to add\n */\n addMark(mark: Mark): void;\n\n /**\n * Remove mark from current selection\n * @param markType - Type of mark to remove\n */\n removeMark(markType: string): void;\n\n /**\n * Toggle mark on current selection\n * @param markType - Type of mark to toggle\n */\n toggleMark(markType: string): void;\n\n // === Events ===\n\n /**\n * Register event listener\n */\n on(event: string, callback: (data: unknown) => void): void;\n\n /**\n * Unregister event listener\n */\n off(event: string, callback: (data: unknown) => void): void;\n\n /**\n * Emit an event\n */\n emit(event: string, data?: unknown): void;\n\n // === Commands ===\n\n /**\n * Register a command\n */\n registerCommand(name: string, handler: CommandHandler): void;\n\n /**\n * Execute a command\n */\n executeCommand(name: string, ...args: unknown[]): unknown;\n\n // === DOM Access (discouraged, use Delta operations instead) ===\n\n /**\n * Access DOM container (editable area)\n * @deprecated Prefer using Delta operations instead of direct DOM manipulation\n */\n getContainer(): HTMLElement;\n\n /**\n * Access plugin container for UI elements (toolbar, etc.)\n * @param position - 'top' or 'bottom'\n */\n getPluginContainer(position: 'top' | 'bottom'): HTMLElement;\n}\n\n/**\n * Command handler function\n */\nexport type CommandHandler = (...args: unknown[]) => unknown;\n\n/**\n * Plugin interface\n */\nexport interface Plugin {\n /**\n * Unique plugin identifier\n */\n id: string;\n\n /**\n * Plugin name\n */\n name: string;\n\n /**\n * Plugin version\n */\n version: string;\n\n /**\n * Plugin dependencies (optional)\n */\n dependencies?: string[];\n\n /**\n * Initialize the plugin\n */\n init(context: PluginContext): Promise<void> | void;\n\n /**\n * Cleanup the plugin\n */\n destroy?(): Promise<void> | void;\n\n /**\n * Handle state updates (optional)\n */\n onStateUpdate?(oldState: EditorState, newState: EditorState): void;\n\n /**\n * Handle delta application (optional)\n */\n onDeltaApplied?(delta: Delta): void;\n}\n\n/**\n * Plugin factory function type\n */\nexport type PluginFactory<TConfig = unknown> = (config?: TConfig) => Plugin;\n\n/**\n * Base plugin class for convenience\n */\nexport abstract class BasePlugin implements Plugin {\n abstract id: string;\n abstract name: string;\n abstract version: string;\n dependencies?: string[];\n\n protected context?: PluginContext;\n\n async init(context: PluginContext): Promise<void> {\n this.context = context;\n }\n\n async destroy(): Promise<void> {\n this.context = undefined;\n }\n\n protected getContext(): PluginContext {\n if (!this.context) {\n throw new Error('Plugin not initialized');\n }\n return this.context;\n }\n}\n","/**\n * Delta envelope - transactional container for operations\n */\n\nimport type { Operation } from './Operations.js';\nimport type { ValidationConstraint } from '../types/index.js';\n\n/**\n * Validation metadata for delta\n */\nexport interface DeltaValidation {\n requiresSchemaVersion: string;\n constraints: ValidationConstraint[];\n}\n\n/**\n * Delta envelope containing operations and metadata\n */\nexport interface Delta {\n txnId: string;\n clientId: string;\n timestamp: string;\n baseVersion: number;\n ltime: number;\n intent: 'edit' | 'comment' | 'format' | 'import' | string;\n undoGroup?: string;\n ops: Operation[];\n inverseOps?: Operation[];\n validation?: DeltaValidation;\n}\n\n/**\n * Delta class for creating and managing deltas\n */\nexport class DeltaBuilder {\n private delta: Partial<Delta>;\n private operations: Operation[] = [];\n\n constructor(clientId: string, baseVersion: number) {\n this.delta = {\n txnId: this.generateTxnId(),\n clientId,\n timestamp: new Date().toISOString(),\n baseVersion,\n ltime: Date.now(),\n ops: [],\n };\n }\n\n /**\n * Set the intent of this delta\n */\n setIntent(intent: Delta['intent']): this {\n this.delta.intent = intent;\n return this;\n }\n\n /**\n * Set the undo group for batch operations\n */\n setUndoGroup(group: string): this {\n this.delta.undoGroup = group;\n return this;\n }\n\n /**\n * Add an operation to this delta\n */\n addOperation(op: Operation): this {\n this.operations.push(op);\n return this;\n }\n\n /**\n * Add multiple operations\n */\n addOperations(ops: Operation[]): this {\n this.operations.push(...ops);\n return this;\n }\n\n /**\n * Set inverse operations for fast undo\n */\n setInverseOps(inverseOps: Operation[]): this {\n this.delta.inverseOps = inverseOps;\n return this;\n }\n\n /**\n * Set validation constraints\n */\n setValidation(validation: DeltaValidation): this {\n this.delta.validation = validation;\n return this;\n }\n\n /**\n * Build the final delta\n */\n build(): Delta {\n if (this.operations.length === 0) {\n throw new Error('Delta must contain at least one operation');\n }\n\n return {\n ...this.delta,\n ops: this.operations,\n } as Delta;\n }\n\n /**\n * Generate a unique transaction ID\n */\n private generateTxnId(): string {\n // Simple UUID v4 implementation\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n\n/**\n * Utility function to create a delta builder\n */\nexport function createDelta(clientId: string, baseVersion: number): DeltaBuilder {\n return new DeltaBuilder(clientId, baseVersion);\n}\n\n/**\n * Compute inverse operations for undo\n * This is a simplified implementation - full implementation would inspect document state\n */\nexport function computeInverse(delta: Delta): Operation[] {\n // In a real implementation, this would:\n // 1. Examine each operation\n // 2. Query the document state to determine the inverse\n // 3. Return the inverse operations in reverse order\n \n // For now, return empty array (inverse ops should be provided explicitly)\n return delta.inverseOps || [];\n}\n\n/**\n * Validate a delta against constraints\n */\nexport function validateDelta(delta: Delta): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if (!delta.txnId) {\n errors.push('Delta must have a transaction ID');\n }\n\n if (!delta.clientId) {\n errors.push('Delta must have a client ID');\n }\n\n if (delta.ops.length === 0) {\n errors.push('Delta must contain at least one operation');\n }\n\n if (delta.baseVersion < 0) {\n errors.push('Base version must be non-negative');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * Delta operation definitions for Notectl\n * Implements the operations specified in the Delta Design document\n */\n\nimport type { BlockId, Position, Range, Mark, BlockNode, BlockAttrs } from '../types/index.js';\n\n/**\n * Base operation interface\n */\nexport interface BaseOperation {\n op: string;\n}\n\n/**\n * Insert text at a position\n */\nexport interface InsertTextOp extends BaseOperation {\n op: 'insert_text';\n target: Position;\n text: string;\n marks?: Mark[];\n}\n\n/**\n * Delete text across a range\n */\nexport interface DeleteRangeOp extends BaseOperation {\n op: 'delete_range';\n range: Range;\n}\n\n/**\n * Apply or remove a mark across a range\n */\nexport interface ApplyMarkOp extends BaseOperation {\n op: 'apply_mark';\n range: Range;\n mark: Mark;\n add: boolean;\n}\n\n/**\n * Insert a block before another block\n */\nexport interface InsertBlockBeforeOp extends BaseOperation {\n op: 'insert_block_before';\n before: BlockId;\n block: BlockNode;\n}\n\n/**\n * Insert a block after another block\n */\nexport interface InsertBlockAfterOp extends BaseOperation {\n op: 'insert_block_after';\n after: BlockId;\n block: BlockNode;\n}\n\n/**\n * Delete a block\n */\nexport interface DeleteBlockOp extends BaseOperation {\n op: 'delete_block';\n target: { blockId: BlockId };\n}\n\n/**\n * Set attributes on a block\n */\nexport interface SetAttrsOp extends BaseOperation {\n op: 'set_attrs';\n target: { blockId: BlockId };\n attrs: BlockAttrs;\n}\n\n/**\n * Wrap blocks in a container\n */\nexport interface WrapInOp extends BaseOperation {\n op: 'wrap_in';\n blockIds: BlockId[];\n wrapperType: string;\n wrapperAttrs?: BlockAttrs;\n}\n\n/**\n * Lift blocks out of their container\n */\nexport interface LiftOutOp extends BaseOperation {\n op: 'lift_out';\n blockIds: BlockId[];\n}\n\n/**\n * Table operation: insert row\n */\nexport interface TableInsertRowOp extends BaseOperation {\n op: 'table_insert_row';\n target: { tableId: BlockId; rowIndex: number };\n row: BlockNode;\n}\n\n/**\n * Table operation: delete row\n */\nexport interface TableDeleteRowOp extends BaseOperation {\n op: 'table_delete_row';\n target: { tableId: BlockId; rowIndex: number };\n}\n\n/**\n * Table operation: insert column\n */\nexport interface TableInsertColOp extends BaseOperation {\n op: 'table_insert_col';\n target: { tableId: BlockId; colIndex: number };\n}\n\n/**\n * Table operation: delete column\n */\nexport interface TableDeleteColOp extends BaseOperation {\n op: 'table_delete_col';\n target: { tableId: BlockId; colIndex: number };\n}\n\n/**\n * Table operation: merge cells\n */\nexport interface TableMergeCellsOp extends BaseOperation {\n op: 'table_merge_cells';\n target: { tableId: BlockId; cells: BlockId[] };\n}\n\n/**\n * Table operation: split cell\n */\nexport interface TableSplitCellOp extends BaseOperation {\n op: 'table_split_cell';\n target: { tableId: BlockId; cellId: BlockId };\n}\n\n/**\n * Update selection/cursor\n */\nexport interface UpdateSelectionOp extends BaseOperation {\n op: 'update_selection';\n actorId: string;\n selection: {\n anchor: Position;\n head: Position;\n };\n}\n\n/**\n * Union of all operation types\n */\nexport type Operation =\n | InsertTextOp\n | DeleteRangeOp\n | ApplyMarkOp\n | InsertBlockBeforeOp\n | InsertBlockAfterOp\n | DeleteBlockOp\n | SetAttrsOp\n | WrapInOp\n | LiftOutOp\n | TableInsertRowOp\n | TableDeleteRowOp\n | TableInsertColOp\n | TableDeleteColOp\n | TableMergeCellsOp\n | TableSplitCellOp\n | UpdateSelectionOp;\n\n/**\n * Type guard for operation types\n */\nexport function isTextOperation(op: Operation): op is InsertTextOp | DeleteRangeOp | ApplyMarkOp {\n return op.op === 'insert_text' || op.op === 'delete_range' || op.op === 'apply_mark';\n}\n\nexport function isBlockOperation(\n op: Operation\n): op is InsertBlockBeforeOp | InsertBlockAfterOp | DeleteBlockOp | SetAttrsOp {\n return (\n op.op === 'insert_block_before' ||\n op.op === 'insert_block_after' ||\n op.op === 'delete_block' ||\n op.op === 'set_attrs'\n );\n}\n\nexport function isTableOperation(op: Operation): boolean {\n return op.op.startsWith('table_');\n}\n\nexport function isSelectionOperation(op: Operation): op is UpdateSelectionOp {\n return op.op === 'update_selection';\n}\n","/**\n * Operational Transformation (OT) logic for concurrent editing\n */\n\nimport type { Operation } from './Operations.js';\nimport type { Delta } from './Delta.js';\n\n/**\n * Transform operation A against operation B\n * Returns transformed version of A that can be applied after B\n */\nexport function transformOperation(opA: Operation, opB: Operation, side: 'left' | 'right'): Operation {\n // This is a simplified OT implementation\n // Full OT would require detailed transformation rules for each operation pair\n \n // For text operations, we need to adjust positions\n if (opA.op === 'insert_text' && opB.op === 'insert_text') {\n return transformInsertInsert(opA, opB, side);\n }\n \n if (opA.op === 'insert_text' && opB.op === 'delete_range') {\n return transformInsertDelete(opA, opB);\n }\n \n if (opA.op === 'delete_range' && opB.op === 'insert_text') {\n return transformDeleteInsert(opA, opB);\n }\n \n if (opA.op === 'delete_range' && opB.op === 'delete_range') {\n return transformDeleteDelete(opA, opB, side);\n }\n \n // For other operations, return as-is (naive approach)\n // A full implementation would handle all operation pairs\n return opA;\n}\n\n/**\n * Transform two concurrent insert operations\n */\nfunction transformInsertInsert(\n opA: Extract<Operation, { op: 'insert_text' }>,\n opB: Extract<Operation, { op: 'insert_text' }>,\n side: 'left' | 'right'\n): Operation {\n // If insertions are in the same block\n if (opA.target.blockId === opB.target.blockId) {\n // If B inserted before A's position, adjust A's offset\n if (opB.target.offset <= opA.target.offset) {\n return {\n ...opA,\n target: {\n ...opA.target,\n offset: opA.target.offset + opB.text.length,\n },\n };\n }\n // If B inserted at same position, use side to determine order\n if (opB.target.offset === opA.target.offset && side === 'right') {\n return {\n ...opA,\n target: {\n ...opA.target,\n offset: opA.target.offset + opB.text.length,\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform insert against delete\n */\nfunction transformInsertDelete(\n opA: Extract<Operation, { op: 'insert_text' }>,\n opB: Extract<Operation, { op: 'delete_range' }>\n): Operation {\n // If insertion is in the deleted range, move it to start of range\n if (opA.target.blockId === opB.range.start.blockId) {\n if (opA.target.offset >= opB.range.start.offset) {\n const deleteLength = opB.range.end.offset - opB.range.start.offset;\n return {\n ...opA,\n target: {\n ...opA.target,\n offset: Math.max(opB.range.start.offset, opA.target.offset - deleteLength),\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform delete against insert\n */\nfunction transformDeleteInsert(\n opA: Extract<Operation, { op: 'delete_range' }>,\n opB: Extract<Operation, { op: 'insert_text' }>\n): Operation {\n // If insert is before delete range, adjust delete positions\n if (opA.range.start.blockId === opB.target.blockId) {\n if (opB.target.offset <= opA.range.start.offset) {\n return {\n ...opA,\n range: {\n start: {\n ...opA.range.start,\n offset: opA.range.start.offset + opB.text.length,\n },\n end: {\n ...opA.range.end,\n offset: opA.range.end.offset + opB.text.length,\n },\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform two concurrent delete operations\n */\nfunction transformDeleteDelete(\n opA: Extract<Operation, { op: 'delete_range' }>,\n opB: Extract<Operation, { op: 'delete_range' }>,\n _side: 'left' | 'right'\n): Operation {\n // If ranges overlap, need to adjust A's range\n if (opA.range.start.blockId === opB.range.start.blockId) {\n const aStart = opA.range.start.offset;\n const aEnd = opA.range.end.offset;\n const bStart = opB.range.start.offset;\n const bEnd = opB.range.end.offset;\n \n // If B's delete is completely before A\n if (bEnd <= aStart) {\n const bLength = bEnd - bStart;\n return {\n ...opA,\n range: {\n start: { ...opA.range.start, offset: aStart - bLength },\n end: { ...opA.range.end, offset: aEnd - bLength },\n },\n };\n }\n \n // If B's delete overlaps with A, adjust accordingly\n // This is complex - simplified version here\n if (bStart <= aStart && bEnd >= aEnd) {\n // B deletes all of A's range - A becomes no-op (delete zero chars)\n return {\n ...opA,\n range: {\n start: { ...opA.range.start, offset: bStart },\n end: { ...opA.range.end, offset: bStart },\n },\n };\n }\n }\n return opA;\n}\n\n/**\n * Transform a delta against another delta\n * Returns transformed version of deltaA that can be applied after deltaB\n */\nexport function transformDelta(deltaA: Delta, deltaB: Delta, side: 'left' | 'right' = 'left'): Delta {\n const transformedOps = deltaA.ops.map((opA) => {\n let transformed = opA;\n for (const opB of deltaB.ops) {\n transformed = transformOperation(transformed, opB, side);\n }\n return transformed;\n });\n\n return {\n ...deltaA,\n ops: transformedOps,\n baseVersion: deltaB.baseVersion + 1, // Update to new base\n };\n}\n\n/**\n * Compose two deltas into a single delta\n * Applies deltaB after deltaA\n */\nexport function composeDelta(deltaA: Delta, deltaB: Delta): Delta {\n // Compose operations - this is simplified\n // Full implementation would optimize/merge operations\n return {\n ...deltaB,\n ops: [...deltaA.ops, ...deltaB.ops],\n baseVersion: deltaA.baseVersion,\n };\n}\n\n/**\n * Check if two deltas can be safely composed\n */\nexport function canCompose(deltaA: Delta, deltaB: Delta): boolean {\n // DeltaB should be based on the version after deltaA\n return deltaB.baseVersion === deltaA.baseVersion || deltaB.clientId === deltaA.clientId;\n}\n","/**\n * Helper utilities for selection, blocks, and node operations\n */\n\nimport type {\n Selection,\n Position,\n BlockNode,\n TextNode,\n Node as NotectlNode,\n SelectionHelpers,\n BlockHelpers,\n} from '../types/index.js';\n\n/**\n * Selection helper implementation\n */\nexport const selectionHelpers: SelectionHelpers = {\n /**\n * Check if selection is collapsed (cursor)\n */\n isCollapsed(selection: Selection): boolean {\n return (\n selection.anchor.blockId === selection.head.blockId &&\n selection.anchor.offset === selection.head.offset\n );\n },\n\n /**\n * Check if selection spans multiple blocks\n */\n isMultiBlock(selection: Selection): boolean {\n return selection.anchor.blockId !== selection.head.blockId;\n },\n\n /**\n * Get the direction of selection (forward/backward)\n */\n getDirection(selection: Selection): 'forward' | 'backward' | 'none' {\n if (this.isCollapsed(selection)) {\n return 'none';\n }\n\n if (selection.anchor.blockId === selection.head.blockId) {\n return selection.anchor.offset < selection.head.offset ? 'forward' : 'backward';\n }\n\n // For multi-block selections, would need document order comparison\n // Simplified: assume forward\n return 'forward';\n },\n\n /**\n * Create a collapsed selection at a position\n */\n createCollapsed(position: Position): Selection {\n return {\n anchor: position,\n head: position,\n };\n },\n\n /**\n * Create a selection range\n */\n createRange(start: Position, end: Position): Selection {\n return {\n anchor: start,\n head: end,\n };\n },\n};\n\n/**\n * Block helper implementation\n */\nexport const blockHelpers: BlockHelpers = {\n /**\n * Check if a node is a text node\n */\n isTextNode(node: NotectlNode): node is TextNode {\n return 'text' in node && node.type === 'text';\n },\n\n /**\n * Check if a node is a block node\n */\n isBlockNode(node: NotectlNode): node is BlockNode {\n return 'id' in node && 'type' in node;\n },\n\n /**\n * Get all text content from a block\n */\n getTextContent(block: BlockNode): string {\n if (!block.children) {\n return '';\n }\n\n return block.children\n .map((child) => {\n if (this.isTextNode(child)) {\n return child.text;\n } else if (this.isBlockNode(child)) {\n return this.getTextContent(child);\n }\n return '';\n })\n .join('');\n },\n\n /**\n * Check if block is empty\n */\n isEmpty(block: BlockNode): boolean {\n if (!block.children || block.children.length === 0) {\n return true;\n }\n\n return this.getTextContent(block).trim() === '';\n },\n};\n","/**\n * Notectl Core - Framework-agnostic rich text editor\n * @packageDocumentation\n */\n\n// Main editor\nexport { NotectlEditor } from './editor/NotectlEditor.js';\nimport { NotectlEditor } from './editor/NotectlEditor.js';\n\n// State management\nexport { EditorState } from './state/EditorState.js';\n\n// Schema\nexport { Schema, createDefaultSchema } from './schema/Schema.js';\nexport type { NodeSpec, MarkSpec, AttributeSpec } from './schema/Schema.js';\n\n// Node factory\nexport { NodeFactory, createNodeFactory, generateBlockId } from './schema/NodeFactory.js';\n\n// Plugin system\nexport { PluginManager } from './plugins/PluginManager.js';\nexport { BasePlugin } from './plugins/Plugin.js';\nexport type {\n Plugin,\n PluginContext,\n PluginFactory,\n CommandHandler,\n} from './plugins/Plugin.js';\n\n// Delta system\nexport { DeltaBuilder, createDelta, computeInverse, validateDelta } from './delta/Delta.js';\nexport type { Delta, DeltaValidation } from './delta/Delta.js';\n\n// Operations\nexport type {\n Operation,\n InsertTextOp,\n DeleteRangeOp,\n ApplyMarkOp,\n InsertBlockBeforeOp,\n InsertBlockAfterOp,\n DeleteBlockOp,\n SetAttrsOp,\n WrapInOp,\n LiftOutOp,\n TableInsertRowOp,\n TableDeleteRowOp,\n TableInsertColOp,\n TableDeleteColOp,\n TableMergeCellsOp,\n TableSplitCellOp,\n UpdateSelectionOp,\n} from './delta/Operations.js';\nexport {\n isTextOperation,\n isBlockOperation,\n isTableOperation,\n isSelectionOperation,\n} from './delta/Operations.js';\n\n// Transformation\nexport { transformOperation, transformDelta, composeDelta, canCompose } from './delta/Transform.js';\n\n// Core types\nexport type {\n BlockId,\n Position,\n Range,\n Mark,\n NodeType,\n TextNode,\n BlockNode,\n BlockAttrs,\n Node,\n Document,\n Selection,\n EditorEvent,\n EditorEventCallback,\n EditorConfig,\n EditorAPI,\n ValidationConstraint,\n ErrorEnvelope,\n CommandRegistry,\n CommandDefinition,\n SelectionHelpers,\n BlockHelpers,\n TableData,\n TableRow,\n TableCell,\n} from './types/index.js';\nimport type { EditorConfig } from './types/index.js';\n\n// Utility helpers\nexport { selectionHelpers, blockHelpers } from './utils/helpers.js';\n\n// Constants and error handling\nexport {\n EDITOR_READY_TIMEOUT,\n ARIA_ANNOUNCEMENT_DELAY,\n DEFAULT_MAX_HISTORY_DEPTH,\n DEFAULT_MIN_HEIGHT,\n ErrorCodes,\n ValidationConstraints,\n NotectlError,\n} from './constants.js';\nexport type { ErrorCode } from './constants.js';\n\n// Utility function to initialize editor\nexport function createEditor(container: HTMLElement, config?: EditorConfig) {\n const editor = new NotectlEditor();\n\n // Apply configuration if provided\n if (config) {\n // Config would be applied here\n }\n\n container.appendChild(editor);\n return editor;\n}\n\n// Version\nexport const VERSION = '0.0.1';\n"],"names":["Schema","config","spec","type","node","errors","textNode","mark","blockNode","attrName","attrSpec","child","childValidation","markType","nodeType","nodeSpec","markA","markB","specA","specB","createDefaultSchema","val","generateBlockId","c","r","NodeFactory","schema","text","marks","content","attrs","level","items","rows","cells","src","alt","children","createNodeFactory","EditorState","initialDoc","options","selection","delta","op","block","n","before","after","m","index","b","blockId","search","nodes","blockChildren","found","entry","json","EDITOR_READY_TIMEOUT","ARIA_ANNOUNCEMENT_DELAY","DEFAULT_MAX_HISTORY_DEPTH","DEFAULT_MIN_HEIGHT","ErrorCodes","NotectlError","code","message","details","ValidationConstraints","PluginManager","plugin","context","existing","missingDeps","depId","error","pluginId","dependentPlugins","id","p","oldState","newState","pluginIds","entries","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","freeze","seal","create","apply","construct","x","func","thisArg","_len","args","_key","Func","_len2","_key2","arrayForEach","unapply","arrayLastIndexOf","arrayPop","arrayPush","arraySplice","stringToLowerCase","stringToString","stringMatch","stringReplace","stringIndexOf","stringTrim","objectHasOwnProperty","regExpTest","typeErrorCreate","unconstruct","_len3","_key3","_len4","_key4","addToSet","set","array","transformCaseFunc","l","element","lcElement","cleanArray","clone","object","newObject","property","value","lookupGetter","prop","desc","fallbackValue","html$1","svg$1","svgFilters","svgDisallowed","mathMl$1","mathMlDisallowed","html","svg","mathMl","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","CUSTOM_ELEMENT","EXPRESSIONS","NODE_TYPE","getGlobal","_createTrustedTypesPolicy","trustedTypes","purifyHostElement","suffix","ATTR_NAME","policyName","scriptUrl","_createHooksMap","createDOMPurify","window","DOMPurify","root","document","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","HTMLFormElement","DOMParser","ElementPrototype","cloneNode","remove","getNextSibling","getChildNodes","getParentNode","template","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","IS_ALLOWED_URI$1","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","CUSTOM_ELEMENT_HANDLING","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","SAFE_FOR_XML","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","SANITIZE_NAMED_PROPS_PREFIX","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","DEFAULT_PARSER_MEDIA_TYPE","CONFIG","formElement","isRegexOrFunction","testValue","_parseConfig","cfg","ALL_SVG_TAGS","ALL_MATHML_TAGS","_checkValidNamespace","parent","tagName","parentTagName","_forceRemove","_removeAttribute","name","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","body","_createNodeIterator","_isClobbered","_isNode","_executeHooks","currentNode","data","hook","_sanitizeElements","_isBasicCustomElement","parentNode","childNodes","childCount","i","childClone","expr","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","attributes","hookEvent","attr","namespaceURI","attrValue","initValue","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","importedNode","returnNode","nodeIterator","serializedHTML","tag","entryPoint","hookFunction","purify","EDITOR_SANITIZE_CONFIG","STRICT_SANITIZE_CONFIG","sanitizeHTML","strict","sanitizeContent","allowHTML","escapeHTML","div","validateDelta","insert","insertObj","key","announceToScreenReader","politeness","liveRegion","registerKeyboardShortcuts","shortcuts","container","handleKeyDown","event","shortcut","ctrlMatch","metaMatch","shiftMatch","altMatch","setAriaAttributes","NotectlEditor","resolve","plugins","oldValue","newValue","tableData","attrParts","styleString","bodyHTML","fallbackCellId","row","rowIndex","rowId","style","cellsHTML","cell","colIndex","cellId","rowSpan","colSpan","inner","match","format","range","cols","table","tbody","tr","j","insertPosition","refNode","placeholder","isEmpty","childElement","result","childResult","item","results","afterId","targetId","beforeId","hasMark","callback","handler","position","undoDelta","redoDelta","sanitized","BasePlugin","DeltaBuilder","clientId","baseVersion","intent","group","ops","inverseOps","validation","createDelta","computeInverse","isTextOperation","isBlockOperation","isTableOperation","isSelectionOperation","transformOperation","opA","opB","side","transformInsertInsert","transformInsertDelete","transformDeleteInsert","transformDeleteDelete","deleteLength","_side","aStart","aEnd","bStart","bEnd","bLength","transformDelta","deltaA","deltaB","transformedOps","transformed","composeDelta","canCompose","selectionHelpers","start","end","blockHelpers","createEditor","editor","VERSION"],"mappings":"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","x_google_ignoreList":[5]}